日志输出补充

This commit is contained in:
caojia
2026-09-28 14:12:14 +08:00
parent cc802d1292
commit be95794a1c
3 changed files with 142 additions and 15 deletions
@@ -8,7 +8,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.bms.ar.domain.ArBankAccount;
import com.bms.ar.mapper.ArBankAccountMapper;
import com.bms.ar.service.IArBillService;
import com.bms.common.core.controller.BaseController;
import com.bms.common.core.domain.AjaxResult;
@@ -20,14 +20,14 @@ import com.bms.common.core.domain.AjaxResult;
public class ArBankAccountController extends BaseController {
@Autowired
private ArBankAccountMapper arBankAccountMapper;
private IArBillService billService;
/**
* 启用账户列表;可按币种过滤,默认账户优先。
*/
@GetMapping("/options")
public AjaxResult options(@RequestParam(value = "currency", required = false) String currency) {
List<ArBankAccount> list = arBankAccountMapper.selectEnabledList(currency);
List<ArBankAccount> list = billService.selectEnabledBankAccounts(currency);
return AjaxResult.success(list);
}
}
@@ -33,6 +33,8 @@ public interface IArBillService
ArBankAccount getDefaultBankAccount(String currency);
List<ArBankAccount> selectEnabledBankAccounts(String currency);
List<PrcOrderBill> previewBill(ArBillGenerateQuery query);
BigDecimal sumPreviewBill(ArBillGenerateQuery query);
@@ -168,10 +168,14 @@ public class ArBillServiceImpl implements IArBillService {
*/
@Override
public List<ArBill> selectArBillList(ArBillQuery query) {
long startedAt = System.nanoTime();
List<ArBill> bills = billMapper.selectArBillList(query);
for (ArBill bill : bills) {
bill.setBankAccountNo(maskAccount(bill.getBankAccountNo()));
}
log.debug("应收账单列表查询完成,billNo={}, customerId={}, status={}, resultCount={}, costMs={}",
safeLogValue(query.getBillNo()), query.getCustomerId(), safeLogValue(query.getStatus()),
bills.size(), elapsedMillis(startedAt));
return bills;
}
@@ -180,12 +184,16 @@ public class ArBillServiceImpl implements IArBillService {
*/
@Override
public ArBill selectArBillById(Long arBillId) {
long startedAt = System.nanoTime();
ArBill bill = billMapper.selectArBillById(arBillId);
if (bill == null) {
throw new ServiceException("应收账单不存在");
}
bill.setBankAccountNo(maskAccount(bill.getBankAccountNo()));
bill.setExports(exportMapper.selectByBillId(arBillId));
log.debug("应收账单详情查询完成,arBillId={}, status={}, exportCount={}, costMs={}",
arBillId, bill.getStatus(), bill.getExports() == null ? 0 : bill.getExports().size(),
elapsedMillis(startedAt));
return bill;
}
@@ -194,7 +202,11 @@ public class ArBillServiceImpl implements IArBillService {
*/
@Override
public List<ArBillDetail> selectArBillDetails(Long arBillId) {
return detailMapper.selectByBillId(arBillId);
long startedAt = System.nanoTime();
List<ArBillDetail> details = detailMapper.selectByBillId(arBillId);
log.debug("应收账单明细查询完成,arBillId={}, resultCount={}, costMs={}",
arBillId, details.size(), elapsedMillis(startedAt));
return details;
}
/**
@@ -202,7 +214,11 @@ public class ArBillServiceImpl implements IArBillService {
*/
@Override
public List<ArBillDetailFee> selectArBillDetailFees(Long arBillId, Long detailId) {
return detailFeeMapper.selectByBillIdAndDetailId(arBillId, detailId);
long startedAt = System.nanoTime();
List<ArBillDetailFee> fees = detailFeeMapper.selectByBillIdAndDetailId(arBillId, detailId);
log.debug("应收账单费用明细查询完成,arBillId={}, detailId={}, resultCount={}, costMs={}",
arBillId, detailId, fees.size(), elapsedMillis(startedAt));
return fees;
}
/**
@@ -210,26 +226,45 @@ public class ArBillServiceImpl implements IArBillService {
*/
@Override
public ArBankAccount getDefaultBankAccount(String currency) {
long startedAt = System.nanoTime();
ArBankAccount account = bankAccountMapper.selectDefaultByCurrency(
StringUtils.isEmpty(currency) ? "CNY" : currency);
if (account != null) {
account.setAccountNo(maskAccount(account.getAccountNo()));
}
log.debug("应收默认收款账户查询完成,currency={}, found={}, costMs={}",
safeLogValue(StringUtils.isEmpty(currency) ? "CNY" : currency), account != null,
elapsedMillis(startedAt));
return account;
}
/** 查询启用的收款账户选项,账户号和账户名称不写入日志。 */
@Override
public List<ArBankAccount> selectEnabledBankAccounts(String currency) {
long startedAt = System.nanoTime();
List<ArBankAccount> accounts = bankAccountMapper.selectEnabledList(currency);
log.debug("应收收款账户选项查询完成,currency={}, resultCount={}, costMs={}",
safeLogValue(currency), accounts.size(), elapsedMillis(startedAt));
return accounts;
}
/**
* 分页预览可生成订单;多个订单号、运单号或转单号按 OR 条件精确匹配。
*/
@Override
public List<PrcOrderBill> previewBill(ArBillGenerateQuery query) {
long startedAt = System.nanoTime();
validatePreviewQuery(query);
List<String> orderIdentifiers = normalizeOrderIdentifiers(query.getOrderOrTrackingNo());
List<String> excludeOrderIdentifiers = normalizeOrderIdentifiers(query.getExcludeOrderOrTrackingNo());
return sourceBillMapper.selectPrcOrderBillByCustomerPeriod(query.getCustomerId(),
List<PrcOrderBill> result = sourceBillMapper.selectPrcOrderBillByCustomerPeriod(query.getCustomerId(),
query.getCustomerCode(), orderIdentifiers,
excludeOrderIdentifiers, query.getBillPeriodEnd(), query.getCurrency(),
eligibleOrderBillStatuses(), ArIncomeBillFeeStatus.UNBILLED.getCode(), null);
log.debug("应收账单生成范围预览查询完成,customerId={}, billPeriodEnd={}, currency={}, resultCount={}, costMs={}",
query.getCustomerId(), query.getBillPeriodEnd(), safeLogValue(query.getCurrency()),
result.size(), elapsedMillis(startedAt));
return result;
}
/**
@@ -237,13 +272,18 @@ public class ArBillServiceImpl implements IArBillService {
*/
@Override
public BigDecimal sumPreviewBill(ArBillGenerateQuery query) {
long startedAt = System.nanoTime();
validatePreviewQuery(query);
List<String> orderIdentifiers = normalizeOrderIdentifiers(query.getOrderOrTrackingNo());
List<String> excludeOrderIdentifiers = normalizeOrderIdentifiers(query.getExcludeOrderOrTrackingNo());
return nvl(sourceBillMapper.sumPrcOrderBillIncomeByCustomerPeriod(query.getCustomerId(),
BigDecimal total = nvl(sourceBillMapper.sumPrcOrderBillIncomeByCustomerPeriod(query.getCustomerId(),
query.getCustomerCode(), orderIdentifiers,
excludeOrderIdentifiers, query.getBillPeriodEnd(), query.getCurrency(),
eligibleOrderBillStatuses(), ArIncomeBillFeeStatus.UNBILLED.getCode()));
log.debug("应收账单生成范围金额汇总完成,customerId={}, billPeriodEnd={}, currency={}, costMs={}",
query.getCustomerId(), query.getBillPeriodEnd(), safeLogValue(query.getCurrency()),
elapsedMillis(startedAt));
return total;
}
/**
@@ -254,9 +294,13 @@ public class ArBillServiceImpl implements IArBillService {
@Override
@Transactional(rollbackFor = Exception.class)
public ArBillGenerateTask generateBill(ArBillGenerateRequest request, String operator, String requestId) {
long startedAt = System.nanoTime();
validatePeriod(request);
ArBillGenerateTask existed = generateTaskMapper.selectByRequestToken(requestId);
if (existed != null) {
log.info("应收账单生成请求命中幂等记录,operator={}, requestId={}, taskId={}, status={}, costMs={}",
safeLogValue(operator), safeLogValue(requestId), existed.getTaskId(), existed.getStatus(),
elapsedMillis(startedAt));
return existed;
}
@@ -341,6 +385,10 @@ public class ArBillServiceImpl implements IArBillService {
task.setCreateBy(operator);
generateTaskMapper.insert(task);
eventPublisher.publishEvent(new ArBillGenerateTaskEvent(task.getTaskId()));
log.info("应收账单生成任务已创建,operator={}, requestId={}, customerId={}, billPeriodEnd={}, selectionMode={}, selectedCount={}, excludedCount={}, taskId={}, status={}, costMs={}",
safeLogValue(operator), safeLogValue(requestId), request.getCustomerId(), request.getBillPeriodEnd(),
safeLogValue(selectionMode), sourceBillIds.size(), excludedSourceBillIds.size(),
task.getTaskId(), task.getStatus(), elapsedMillis(startedAt));
return task;
}
@@ -349,10 +397,13 @@ public class ArBillServiceImpl implements IArBillService {
*/
@Override
public ArBillGenerateTask selectGenerateTask(Long taskId) {
long startedAt = System.nanoTime();
ArBillGenerateTask task = generateTaskMapper.selectById(taskId);
if (task == null) {
throw new ServiceException("账单生成任务不存在");
}
log.debug("应收账单生成任务状态查询,taskId={}, status={}, processedCount={}, totalCount={}, costMs={}",
taskId, task.getStatus(), task.getProcessedCount(), task.getTotalCount(), elapsedMillis(startedAt));
return task;
}
@@ -361,7 +412,11 @@ public class ArBillServiceImpl implements IArBillService {
*/
@Override
public List<ArBillGenerateTask> selectActiveGenerateTasks(String operator) {
return generateTaskMapper.selectActiveByCreateBy(operator);
long startedAt = System.nanoTime();
List<ArBillGenerateTask> tasks = generateTaskMapper.selectActiveByCreateBy(operator);
log.debug("当前用户应收账单生成任务查询,operator={}, taskCount={}, costMs={}",
safeLogValue(operator), tasks.size(), elapsedMillis(startedAt));
return tasks;
}
/**
@@ -370,6 +425,7 @@ public class ArBillServiceImpl implements IArBillService {
@Override
@Transactional(rollbackFor = Exception.class)
public ArBillGenerateTask cancelGenerateTask(Long taskId, String operator, String requestId) {
long startedAt = System.nanoTime();
ArBillGenerateTask task = selectGenerateTask(taskId);
if (!operator.equals(task.getCreateBy())) {
throw new ServiceException("只能取消自己创建的账单生成任务");
@@ -377,6 +433,8 @@ public class ArBillServiceImpl implements IArBillService {
if (ArBillGenerateTaskStatus.SUCCESS.equals(task.getStatus())
|| ArBillGenerateTaskStatus.FAILED.equals(task.getStatus())
|| ArBillGenerateTaskStatus.CANCELED.equals(task.getStatus())) {
log.info("应收账单生成任务取消请求已处理,operator={}, requestId={}, taskId={}, status={}, costMs={}",
safeLogValue(operator), safeLogValue(requestId), taskId, task.getStatus(), elapsedMillis(startedAt));
return task;
}
if (ArBillGenerateTaskStatus.WAITING.equals(task.getStatus())) {
@@ -384,7 +442,10 @@ public class ArBillServiceImpl implements IArBillService {
} else {
generateTaskMapper.markCancelRequested(taskId);
}
return selectGenerateTask(taskId);
ArBillGenerateTask result = selectGenerateTask(taskId);
log.info("应收账单生成任务取消请求已处理,operator={}, requestId={}, taskId={}, status={}, costMs={}",
safeLogValue(operator), safeLogValue(requestId), taskId, result.getStatus(), elapsedMillis(startedAt));
return result;
}
/**
@@ -393,6 +454,7 @@ public class ArBillServiceImpl implements IArBillService {
@Override
@Transactional(rollbackFor = Exception.class)
public ArBillGenerateTask retryGenerateTask(Long taskId, String operator, String requestId) {
long startedAt = System.nanoTime();
ArBillGenerateTask task = selectGenerateTask(taskId);
if (!operator.equals(task.getCreateBy())) {
throw new ServiceException("只能重新生成自己创建的账单任务");
@@ -402,7 +464,11 @@ public class ArBillServiceImpl implements IArBillService {
}
ArBillGenerateRequest request = JSON.parseObject(task.getRequestPayload(), ArBillGenerateRequest.class);
request.setRequestId(requestId);
return generateBill(request, operator, requestId);
ArBillGenerateTask retried = generateBill(request, operator, requestId);
log.info("应收账单生成任务重试请求已处理,operator={}, requestId={}, sourceTaskId={}, newTaskId={}, status={}, costMs={}",
safeLogValue(operator), safeLogValue(requestId), taskId, retried.getTaskId(), retried.getStatus(),
elapsedMillis(startedAt));
return retried;
}
/**
@@ -757,6 +823,7 @@ public class ArBillServiceImpl implements IArBillService {
@Override
@Transactional(rollbackFor = Exception.class)
public ArBill confirmBill(Long arBillId, ArBillActionRequest request, String operator, String requestId) {
long startedAt = System.nanoTime();
ArBill bill = billMapper.selectArBillByIdForUpdate(arBillId);
if (bill == null) {
throw failure(arBillId, ArLogObjectType.BILL, String.valueOf(arBillId), ArLogOperationType.CONFIRM,
@@ -787,7 +854,10 @@ public class ArBillServiceImpl implements IArBillService {
// 应收账单只负责形成应收,不参与客户余额或授信额度变更。
recordSuccess(bill, ArLogObjectType.BILL, ArLogOperationType.CONFIRM,
"确认应收账单", ArBillStatus.DRAFT.getCode(), ArBillStatus.CONFIRMED.getCode(), requestId, operator);
return selectArBillById(arBillId);
ArBill result = selectArBillById(arBillId);
log.info("应收账单确认处理完成,operator={}, requestId={}, arBillId={}, status={}, costMs={}",
safeLogValue(operator), safeLogValue(requestId), arBillId, result.getStatus(), elapsedMillis(startedAt));
return result;
}
/**
@@ -796,6 +866,7 @@ public class ArBillServiceImpl implements IArBillService {
@Override
@Transactional(rollbackFor = Exception.class)
public ArBill voidBill(Long arBillId, ArBillActionRequest request, String operator, String requestId) {
long startedAt = System.nanoTime();
String remark = request == null ? null : request.getRemark();
if (StringUtils.isEmpty(remark)) {
throw failure(arBillId, ArLogObjectType.BILL, String.valueOf(arBillId), ArLogOperationType.VOID,
@@ -826,7 +897,10 @@ public class ArBillServiceImpl implements IArBillService {
sourceBillMapper.refreshArBillStatusByArBillId(arBillId);
recordSuccess(bill, ArLogObjectType.BILL, ArLogOperationType.VOID,
"作废应收账单:" + remark, bill.getStatus(), ArBillStatus.VOID.getCode(), requestId, operator);
return selectArBillById(arBillId);
ArBill result = selectArBillById(arBillId);
log.info("应收账单作废处理完成,operator={}, requestId={}, arBillId={}, status={}, costMs={}",
safeLogValue(operator), safeLogValue(requestId), arBillId, result.getStatus(), elapsedMillis(startedAt));
return result;
}
/**
@@ -835,11 +909,15 @@ public class ArBillServiceImpl implements IArBillService {
@Override
@Transactional(rollbackFor = Exception.class)
public ArBillExport exportBill(Long arBillId, String operator, String requestId) {
long startedAt = System.nanoTime();
ArBillLog previous = logMapper.selectSuccessByRequestId(requestId, ArLogObjectType.EXPORT.getCode(),
ArLogResult.SUCCESS.getCode());
if (previous != null && isNumber(previous.getObjectId())) {
ArBillExport previousExport = exportMapper.selectById(Long.valueOf(previous.getObjectId()));
if (previousExport != null) {
log.info("应收账单导出请求命中幂等记录,operator={}, requestId={}, arBillId={}, exportId={}, status={}, costMs={}",
safeLogValue(operator), safeLogValue(requestId), arBillId, previousExport.getExportId(),
previousExport.getExportStatus(), elapsedMillis(startedAt));
return previousExport;
}
}
@@ -859,6 +937,9 @@ public class ArBillServiceImpl implements IArBillService {
}
ArBillExport processing = exportMapper.selectProcessingByBillId(arBillId);
if (processing != null) {
log.info("应收账单导出任务已存在,operator={}, requestId={}, arBillId={}, exportId={}, status={}, costMs={}",
safeLogValue(operator), safeLogValue(requestId), arBillId, processing.getExportId(),
processing.getExportStatus(), elapsedMillis(startedAt));
return processing;
}
ArExportTemplate template = exportTemplateMapper.selectDefaultEnabled(EXPORT_TEMPLATE_BUSINESS_TYPE,
@@ -887,6 +968,9 @@ public class ArBillServiceImpl implements IArBillService {
recordSuccess(bill, ArLogObjectType.EXPORT, ArLogOperationType.EXPORT,
"已提交账单导出任务", bill.getStatus(), bill.getStatus(), requestId, operator, export.getExportId());
eventPublisher.publishEvent(new ArBillExportTaskEvent(export.getExportId()));
log.info("应收账单导出任务已创建,operator={}, requestId={}, arBillId={}, exportId={}, status={}, costMs={}",
safeLogValue(operator), safeLogValue(requestId), arBillId, export.getExportId(),
export.getExportStatus(), elapsedMillis(startedAt));
return export;
}
@@ -895,10 +979,13 @@ public class ArBillServiceImpl implements IArBillService {
*/
@Override
public ArBillExport selectExport(Long exportId) {
long startedAt = System.nanoTime();
ArBillExport export = exportMapper.selectById(exportId);
if (export == null) {
throw new ServiceException("导出任务不存在");
}
log.debug("应收账单导出任务状态查询,exportId={}, status={}, costMs={}",
exportId, export.getExportStatus(), elapsedMillis(startedAt));
return export;
}
@@ -909,9 +996,13 @@ public class ArBillServiceImpl implements IArBillService {
public void processExportTask(Long exportId) {
ArBillExport export = exportMapper.selectById(exportId);
if (export == null || !ArExportStatus.PROCESSING.getCode().equals(export.getExportStatus())) {
log.debug("应收账单导出任务跳过,exportId={}, status={}",
exportId, export == null ? null : export.getExportStatus());
return;
}
long startedAt = System.nanoTime();
log.info("开始执行应收账单导出任务,exportId={}, arBillId={}", exportId, export.getArBillId());
ArBill bill = null;
try {
bill = billMapper.selectArBillById(export.getArBillId());
@@ -940,11 +1031,20 @@ public class ArBillServiceImpl implements IArBillService {
export.setStorageKey(FileUploadUtils.getPathFileName(downloadDir, relative));
export.setFileSize(Files.size(target));
export.setFileHash(sha256(target));
if (exportMapper.markSuccess(export) == 0) {
int updated = exportMapper.markSuccess(export);
if (updated == 0) {
Files.deleteIfExists(target);
log.warn("应收账单导出文件已生成但任务状态未更新,exportId={}, arBillId={}",
exportId, export.getArBillId());
} else {
log.info("应收账单导出任务执行完成,exportId={}, arBillId={}, rowCount={}, fileSize={}, costMs={}",
exportId, export.getArBillId(), export.getRowCount(), export.getFileSize(),
elapsedMillis(startedAt));
}
} catch (Exception e) {
String message = exportFailureMessage(e);
log.error("应收账单导出任务执行失败,exportId={}, arBillId={}, message={}, costMs={}",
exportId, export.getArBillId(), safeLogValue(message), elapsedMillis(startedAt), e);
if (exportMapper.markFailed(exportId, message) > 0) {
logService.recordFailure(export.getArBillId(), ArLogObjectType.EXPORT, String.valueOf(exportId),
ArLogOperationType.EXPORT, bill == null ? null : bill.getStatus(), message, export.getExportBy(), null);
@@ -964,11 +1064,16 @@ public class ArBillServiceImpl implements IArBillService {
@Override
public List<ArBillExport> selectExports(Long arBillId) {
return exportMapper.selectByBillId(arBillId);
long startedAt = System.nanoTime();
List<ArBillExport> exports = exportMapper.selectByBillId(arBillId);
log.debug("应收账单导出记录查询,arBillId={}, exportCount={}, costMs={}",
arBillId, exports.size(), elapsedMillis(startedAt));
return exports;
}
@Override
public void downloadExport(Long exportId, HttpServletResponse response) throws Exception {
long startedAt = System.nanoTime();
ArBillExport export = exportMapper.selectById(exportId);
if (export == null || !ArExportStatus.SUCCESS.getCode().equals(export.getExportStatus()) || StringUtils.isEmpty(export.getStorageKey())) {
throw new ServiceException("导出文件不存在或尚未生成成功");
@@ -980,11 +1085,18 @@ public class ArBillServiceImpl implements IArBillService {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
FileUtils.setAttachmentResponseHeader(response, export.getFileName());
FileUtils.writeBytes(BmsConfig.getProfile() + FileUtils.stripPrefix(resource), response.getOutputStream());
log.debug("应收账单导出文件下载完成,exportId={}, fileSize={}, costMs={}",
exportId, export.getFileSize(), elapsedMillis(startedAt));
}
@Override
public List<ArBillLog> selectLogList(ArBillLog query) {
return logService.selectLogList(query);
long startedAt = System.nanoTime();
List<ArBillLog> logs = logService.selectLogList(query);
log.debug("应收账单操作日志查询完成,arBillId={}, objectType={}, operationType={}, resultCount={}, costMs={}",
query.getArBillId(), safeLogValue(query.getObjectType()), safeLogValue(query.getOperationType()),
logs.size(), elapsedMillis(startedAt));
return logs;
}
private String exportFailureMessage(Exception e) {
@@ -1738,4 +1850,17 @@ public class ArBillServiceImpl implements IArBillService {
}
return new ArrayList<>(uniqueIdentifiers);
}
private long elapsedMillis(long startedAt) {
return (System.nanoTime() - startedAt) / 1_000_000L;
}
/** 防止请求参数中的换行控制字符伪造多行日志,并限制日志字段长度。 */
private String safeLogValue(String value) {
if (StringUtils.isEmpty(value)) {
return value;
}
String sanitized = value.replaceAll("[\\p{Cntrl}]", "_");
return sanitized.length() > 128 ? sanitized.substring(0, 128) : sanitized;
}
}