From a17f09683bd651a72c265a9e219ae03af27bcb30 Mon Sep 17 00:00:00 2001 From: caojia <1301869380@qq.com> Date: Thu, 17 Sep 2026 11:00:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BA=94=E6=94=B6=E8=B4=A6=E5=8D=95=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=EF=BC=8C=E8=B0=83=E6=95=B4=E6=9E=9A=E4=B8=BE=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruoyi/ar/domain/ArBalanceWriteoff.java | 7 +- .../main/java/com/ruoyi/ar/domain/ArBill.java | 1 + .../com/ruoyi/ar/domain/ArBillExport.java | 1 + .../java/com/ruoyi/ar/domain/ArBillLog.java | 4 + .../ar/enums/ArBalanceWriteoffStatus.java | 50 +++++++++ .../com/ruoyi/ar/enums/ArExportStatus.java | 41 ++++++- .../com/ruoyi/ar/enums/ArLogObjectType.java | 31 ++++++ .../ruoyi/ar/enums/ArLogOperationSource.java | 33 ++++++ .../ruoyi/ar/enums/ArLogOperationType.java | 39 +++++++ .../java/com/ruoyi/ar/enums/ArLogResult.java | 27 ++++- .../ar/mapper/ArBalanceWriteoffMapper.java | 4 +- .../com/ruoyi/ar/mapper/ArBillLogMapper.java | 3 +- .../ruoyi/ar/service/IArBillLogService.java | 4 +- .../impl/ArBalanceWriteoffServiceImpl.java | 23 ++-- .../ar/service/impl/ArBillLogServiceImpl.java | 11 +- .../ar/service/impl/ArBillServiceImpl.java | 103 ++++++++++-------- .../mapper/ar/ArBalanceWriteoffMapper.xml | 4 +- .../resources/mapper/ar/ArBillLogMapper.xml | 3 +- bms-back/sql/ar/ar_balance_writeoff.sql | 2 +- bms-back/sql/ar/ar_bill.sql | 12 +- .../ar_bill_log_balance_writeoff_comment.sql | 10 +- .../ar/ar_status_enum_comment_migration.sql | 30 +++++ bms-front/src/constants/ar/bill.js | 29 +---- .../views/ar/bill/components/BillDetail.vue | 13 ++- bms-front/src/views/ar/bill/log.vue | 31 ++++-- .../customerinfo/customermoney/index.vue | 21 ++-- 26 files changed, 397 insertions(+), 140 deletions(-) create mode 100644 bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArBalanceWriteoffStatus.java create mode 100644 bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArLogObjectType.java create mode 100644 bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArLogOperationSource.java create mode 100644 bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArLogOperationType.java create mode 100644 bms-back/sql/ar/ar_status_enum_comment_migration.sql diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/ArBalanceWriteoff.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/ArBalanceWriteoff.java index 79a34831..34aa9954 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/ArBalanceWriteoff.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/ArBalanceWriteoff.java @@ -22,11 +22,6 @@ public class ArBalanceWriteoff extends BaseEntity { private static final long serialVersionUID = 1L; - /** 有效 */ - public static final String STATUS_EFFECTIVE = "EFFECTIVE"; - /** 已取消(反核销) */ - public static final String STATUS_CANCELLED = "CANCELLED"; - /** 余额核销ID */ private Long writeoffId; @@ -61,7 +56,7 @@ public class ArBalanceWriteoff extends BaseEntity @JsonFormat(pattern = "yyyy-MM-dd") private Date writeoffDate; - /** 状态:EFFECTIVE/CANCELLED */ + /** 状态:EFFECTIVE(有效)/CANCELLED(已反核销),取值由 ArBalanceWriteoffStatus 维护。 */ private String status; /** 核销备注 */ diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/ArBill.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/ArBill.java index 94708716..c13dd750 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/ArBill.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/ArBill.java @@ -36,6 +36,7 @@ public class ArBill extends BaseEntity private BigDecimal totalAmount; private BigDecimal writtenOffAmount; private BigDecimal unwrittenAmount; + /** 状态:DRAFT草稿、CONFIRMED已确认、PARTIAL_WRITTEN_OFF部分核销、WRITTEN_OFF已核销、VOID已作废。 */ private String status; private Integer billVersion; private String bankAccountName; diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/ArBillExport.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/ArBillExport.java index fd09b927..964d44b5 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/ArBillExport.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/ArBillExport.java @@ -21,6 +21,7 @@ public class ArBillExport implements Serializable private Long fileSize; private String fileHash; private Integer rowCount; + /** 导出状态:PROCESSING生成中、SUCCESS成功可下载、FAILED失败。 */ private String exportStatus; private String exportBy; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/ArBillLog.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/ArBillLog.java index caca2a32..a22c351c 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/ArBillLog.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/ArBillLog.java @@ -13,10 +13,12 @@ public class ArBillLog implements Serializable private Long logId; private Long arBillId; + /** 对象类型:BILL应收账单、EXPORT账单导出、BALANCE_WRITEOFF余额核销。 */ private String objectType; private String objectId; /** 对象业务标识,例如账单号、收款单号或核销单号。 */ private String objectDisplay; + /** 操作类型,取值由 ArLogOperationType 维护。 */ private String operationType; private String operationDesc; private String fromStatus; @@ -25,9 +27,11 @@ public class ArBillLog implements Serializable private String afterData; private String operatorId; private String operatorName; + /** 操作来源:WEB网页端、API接口、JOB定时任务、IMPORT数据导入。 */ private String operationSource; private String requestId; private String traceId; + /** 操作结果:SUCCESS成功、FAILED失败。 */ private String result; private String errorMessage; private String clientIp; diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArBalanceWriteoffStatus.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArBalanceWriteoffStatus.java new file mode 100644 index 00000000..1f1c696e --- /dev/null +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArBalanceWriteoffStatus.java @@ -0,0 +1,50 @@ +package com.ruoyi.ar.enums; + +/** + * 应收账单余额核销单状态。 + * + *

数据库保存英文编码,页面通过前端枚举展示中文名称。

+ */ +public enum ArBalanceWriteoffStatus +{ + /** 核销已生效,余额已扣减。 */ + EFFECTIVE("EFFECTIVE", "有效"), + /** 核销已取消,余额已回补。 */ + CANCELLED("CANCELLED", "已反核销"); + + private final String code; + private final String label; + + ArBalanceWriteoffStatus(String code, String label) + { + this.code = code; + this.label = label; + } + + public String getCode() + { + return code; + } + + public String getLabel() + { + return label; + } + + public boolean isEffective() + { + return this == EFFECTIVE; + } + + public static ArBalanceWriteoffStatus of(String code) + { + for (ArBalanceWriteoffStatus status : values()) + { + if (status.code.equalsIgnoreCase(code)) + { + return status; + } + } + return null; + } +} diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArExportStatus.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArExportStatus.java index 86ee5267..c0643ec6 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArExportStatus.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArExportStatus.java @@ -1,21 +1,52 @@ package com.ruoyi.ar.enums; -/** 应收账单导出任务状态。 */ +/** + * 应收账单导出任务状态。 + * + *

PROCESSING 表示处理中,SUCCESS 表示生成成功,FAILED 表示生成失败。

+ */ public enum ArExportStatus { - PROCESSING("PROCESSING"), - SUCCESS("SUCCESS"), - FAILED("FAILED"); + /** 文件正在生成。 */ + PROCESSING("PROCESSING", "生成中"), + /** 文件已生成,可以下载。 */ + SUCCESS("SUCCESS", "成功"), + /** 文件生成失败。 */ + FAILED("FAILED", "失败"); private final String code; + private final String label; - ArExportStatus(String code) + ArExportStatus(String code, String label) { this.code = code; + this.label = label; } public String getCode() { return code; } + + public String getLabel() + { + return label; + } + + public boolean isSuccess() + { + return this == SUCCESS; + } + + public static ArExportStatus of(String code) + { + for (ArExportStatus status : values()) + { + if (status.code.equalsIgnoreCase(code)) + { + return status; + } + } + return null; + } } diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArLogObjectType.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArLogObjectType.java new file mode 100644 index 00000000..5ab98272 --- /dev/null +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArLogObjectType.java @@ -0,0 +1,31 @@ +package com.ruoyi.ar.enums; + +/** 应收日志关联对象类型。 */ +public enum ArLogObjectType +{ + /** 应收账单主对象。 */ + BILL("BILL", "应收账单"), + /** 账单导出文件对象。 */ + EXPORT("EXPORT", "账单导出"), + /** 客户余额核销单对象。 */ + BALANCE_WRITEOFF("BALANCE_WRITEOFF", "余额核销"); + + private final String code; + private final String label; + + ArLogObjectType(String code, String label) + { + this.code = code; + this.label = label; + } + + public String getCode() + { + return code; + } + + public String getLabel() + { + return label; + } +} diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArLogOperationSource.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArLogOperationSource.java new file mode 100644 index 00000000..e2359fd4 --- /dev/null +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArLogOperationSource.java @@ -0,0 +1,33 @@ +package com.ruoyi.ar.enums; + +/** 应收日志操作来源。 */ +public enum ArLogOperationSource +{ + /** 浏览器页面操作。 */ + WEB("WEB", "网页端"), + /** 开放接口或系统间接口调用。 */ + API("API", "接口"), + /** 定时任务或后台作业。 */ + JOB("JOB", "定时任务"), + /** 数据导入操作。 */ + IMPORT("IMPORT", "数据导入"); + + private final String code; + private final String label; + + ArLogOperationSource(String code, String label) + { + this.code = code; + this.label = label; + } + + public String getCode() + { + return code; + } + + public String getLabel() + { + return label; + } +} diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArLogOperationType.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArLogOperationType.java new file mode 100644 index 00000000..ceeff672 --- /dev/null +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArLogOperationType.java @@ -0,0 +1,39 @@ +package com.ruoyi.ar.enums; + +/** 应收日志操作类型。 */ +public enum ArLogOperationType +{ + /** 生成应收账单成功。 */ + CREATE("CREATE", "生成账单"), + /** 生成账单前的校验或生成失败记录。 */ + GENERATE("GENERATE", "生成账单校验"), + /** 确认草稿账单。 */ + CONFIRM("CONFIRM", "确认账单"), + /** 作废账单并释放来源订单。 */ + VOID("VOID", "作废账单"), + /** 生成账单导出文件。 */ + EXPORT("EXPORT", "导出账单"), + /** 使用客户余额核销账单。 */ + BALANCE_WRITEOFF("BALANCE_WRITEOFF", "余额核销"), + /** 取消余额核销并回补客户余额。 */ + CANCEL_BALANCE_WRITEOFF("CANCEL_BALANCE_WRITEOFF", "取消余额核销"); + + private final String code; + private final String label; + + ArLogOperationType(String code, String label) + { + this.code = code; + this.label = label; + } + + public String getCode() + { + return code; + } + + public String getLabel() + { + return label; + } +} diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArLogResult.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArLogResult.java index f65c9d8d..22031a84 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArLogResult.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/enums/ArLogResult.java @@ -3,18 +3,39 @@ package com.ruoyi.ar.enums; /** 应收操作日志结果。 */ public enum ArLogResult { - SUCCESS("SUCCESS"), - FAILED("FAILED"); + /** 操作执行成功。 */ + SUCCESS("SUCCESS", "成功"), + /** 操作执行失败。 */ + FAILED("FAILED", "失败"); private final String code; + private final String label; - ArLogResult(String code) + ArLogResult(String code, String label) { this.code = code; + this.label = label; } public String getCode() { return code; } + + public String getLabel() + { + return label; + } + + public static ArLogResult of(String code) + { + for (ArLogResult result : values()) + { + if (result.code.equalsIgnoreCase(code)) + { + return result; + } + } + return null; + } } diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/mapper/ArBalanceWriteoffMapper.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/mapper/ArBalanceWriteoffMapper.java index cb4f0df2..d8707003 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/mapper/ArBalanceWriteoffMapper.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/mapper/ArBalanceWriteoffMapper.java @@ -27,7 +27,9 @@ public interface ArBalanceWriteoffMapper int updateCancelled(@Param("writeoffId") Long writeoffId, @Param("reverseFlowId") Long reverseFlowId, @Param("cancelBy") String cancelBy, - @Param("cancelRemark") String cancelRemark); + @Param("cancelRemark") String cancelRemark, + @Param("status") String status, + @Param("effectiveStatus") String effectiveStatus); /** 查询核销记录列表(关联账单名称/客户名称) */ List selectWriteoffList(ArBalanceWriteoff query); diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/mapper/ArBillLogMapper.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/mapper/ArBillLogMapper.java index 280257b8..6f6279de 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/mapper/ArBillLogMapper.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/mapper/ArBillLogMapper.java @@ -9,7 +9,8 @@ public interface ArBillLogMapper List selectList(ArBillLog query); ArBillLog selectSuccessByRequestId(@Param("requestId") String requestId, - @Param("objectType") String objectType); + @Param("objectType") String objectType, + @Param("result") String result); int insert(ArBillLog log); } diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/IArBillLogService.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/IArBillLogService.java index 94e9ecbc..f3b8f453 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/IArBillLogService.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/IArBillLogService.java @@ -2,6 +2,8 @@ package com.ruoyi.ar.service; import java.util.List; import com.ruoyi.ar.domain.ArBillLog; +import com.ruoyi.ar.enums.ArLogObjectType; +import com.ruoyi.ar.enums.ArLogOperationType; public interface IArBillLogService { @@ -9,6 +11,6 @@ public interface IArBillLogService void record(ArBillLog log); - void recordFailure(Long arBillId, String objectType, String objectId, String operationType, + void recordFailure(Long arBillId, ArLogObjectType objectType, String objectId, ArLogOperationType operationType, String fromStatus, String message, String operator, String requestId); } diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/impl/ArBalanceWriteoffServiceImpl.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/impl/ArBalanceWriteoffServiceImpl.java index e70965bd..582a4cda 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/impl/ArBalanceWriteoffServiceImpl.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/impl/ArBalanceWriteoffServiceImpl.java @@ -14,7 +14,11 @@ import org.springframework.util.StringUtils; import com.ruoyi.ar.domain.ArBalanceWriteoff; import com.ruoyi.ar.domain.ArBill; import com.ruoyi.ar.domain.ArBillLog; +import com.ruoyi.ar.enums.ArBalanceWriteoffStatus; import com.ruoyi.ar.enums.ArBillStatus; +import com.ruoyi.ar.enums.ArLogObjectType; +import com.ruoyi.ar.enums.ArLogOperationSource; +import com.ruoyi.ar.enums.ArLogOperationType; import com.ruoyi.ar.enums.ArLogResult; import com.ruoyi.ar.mapper.ArBalanceWriteoffMapper; import com.ruoyi.ar.mapper.ArBillMapper; @@ -119,7 +123,7 @@ public class ArBalanceWriteoffServiceImpl implements IArBalanceWriteoffService writeoff.setCurrency(currency); writeoff.setWriteoffAmount(amount); writeoff.setWriteoffDate(writeoffDate); - writeoff.setStatus(ArBalanceWriteoff.STATUS_EFFECTIVE); + writeoff.setStatus(ArBalanceWriteoffStatus.EFFECTIVE.getCode()); writeoff.setRemark(StringUtils.hasText(cmd.getRemark()) ? cmd.getRemark().trim() : null); writeoff.setCreateBy(operator); writeoffMapper.insertArBalanceWriteoff(writeoff); @@ -148,7 +152,7 @@ public class ArBalanceWriteoffServiceImpl implements IArBalanceWriteoffService throw new ServiceException("账单状态已发生变化,请刷新后重试"); } - recordLog(bill.getArBillId(), writeoff.getWriteoffId(), "BALANCE_WRITEOFF", + recordLog(bill.getArBillId(), writeoff.getWriteoffId(), ArLogOperationType.BALANCE_WRITEOFF, "账户余额核销账单 " + amount.toPlainString() + " " + currency, fromStatus, nextStatus, operator, requestId); writeoff.setAccountId(flow.getAccountId()); @@ -170,7 +174,7 @@ public class ArBalanceWriteoffServiceImpl implements IArBalanceWriteoffService { throw new ServiceException("核销记录不存在"); } - if (!ArBalanceWriteoff.STATUS_EFFECTIVE.equals(writeoff.getStatus())) + if (!ArBalanceWriteoffStatus.EFFECTIVE.getCode().equals(writeoff.getStatus())) { throw new ServiceException("只有有效状态的核销记录可以反核销"); } @@ -213,11 +217,12 @@ public class ArBalanceWriteoffServiceImpl implements IArBalanceWriteoffService } // 4. 核销单置为CANCELLED并登记回补流水 - if (writeoffMapper.updateCancelled(writeoffId, reverseFlow.getId(), operator, cancelRemark) != 1) + if (writeoffMapper.updateCancelled(writeoffId, reverseFlow.getId(), operator, cancelRemark, + ArBalanceWriteoffStatus.CANCELLED.getCode(), ArBalanceWriteoffStatus.EFFECTIVE.getCode()) != 1) { throw new ServiceException("核销记录状态已变化,请刷新后重试"); } - recordLog(bill.getArBillId(), writeoffId, "CANCEL_BALANCE_WRITEOFF", + recordLog(bill.getArBillId(), writeoffId, ArLogOperationType.CANCEL_BALANCE_WRITEOFF, "反核销回补账单:" + cancelRemark, fromStatus, nextStatus, operator, requestId); } @@ -234,20 +239,20 @@ public class ArBalanceWriteoffServiceImpl implements IArBalanceWriteoffService ? ArBillStatus.WRITTEN_OFF.getCode() : ArBillStatus.PARTIAL_WRITTEN_OFF.getCode(); } - private void recordLog(Long billId, Long writeoffId, String operationType, String desc, + private void recordLog(Long billId, Long writeoffId, ArLogOperationType operationType, String desc, String fromStatus, String toStatus, String operator, String requestId) { ArBillLog log = new ArBillLog(); log.setArBillId(billId); - log.setObjectType("BALANCE_WRITEOFF"); + log.setObjectType(ArLogObjectType.BALANCE_WRITEOFF.getCode()); log.setObjectId(String.valueOf(writeoffId)); - log.setOperationType(operationType); + log.setOperationType(operationType.getCode()); log.setOperationDesc(desc); log.setFromStatus(fromStatus); log.setToStatus(toStatus); log.setOperatorId(operator); log.setOperatorName(operator); - log.setOperationSource("WEB"); + log.setOperationSource(ArLogOperationSource.WEB.getCode()); log.setRequestId(requestId); log.setResult(ArLogResult.SUCCESS.getCode()); logService.record(log); diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/impl/ArBillLogServiceImpl.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/impl/ArBillLogServiceImpl.java index 99386065..55740d69 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/impl/ArBillLogServiceImpl.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/impl/ArBillLogServiceImpl.java @@ -6,6 +6,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.ruoyi.ar.domain.ArBillLog; +import com.ruoyi.ar.enums.ArLogObjectType; +import com.ruoyi.ar.enums.ArLogOperationSource; +import com.ruoyi.ar.enums.ArLogOperationType; import com.ruoyi.ar.enums.ArLogResult; import com.ruoyi.ar.mapper.ArBillLogMapper; import com.ruoyi.ar.service.IArBillLogService; @@ -32,19 +35,19 @@ public class ArBillLogServiceImpl implements IArBillLogService /** 失败日志必须独立提交,不能随业务异常一起回滚。 */ @Override @Transactional(propagation = Propagation.REQUIRES_NEW) - public void recordFailure(Long arBillId, String objectType, String objectId, String operationType, + public void recordFailure(Long arBillId, ArLogObjectType objectType, String objectId, ArLogOperationType operationType, String fromStatus, String message, String operator, String requestId) { ArBillLog log = new ArBillLog(); log.setArBillId(arBillId); - log.setObjectType(objectType); + log.setObjectType(objectType.getCode()); log.setObjectId(objectId); - log.setOperationType(operationType); + log.setOperationType(operationType.getCode()); log.setOperationDesc(message); log.setFromStatus(fromStatus); log.setOperatorId(operator); log.setOperatorName(operator); - log.setOperationSource("WEB"); + log.setOperationSource(ArLogOperationSource.WEB.getCode()); log.setRequestId(requestId == null ? IdUtils.fastSimpleUUID() : requestId); log.setResult(ArLogResult.FAILED.getCode()); log.setErrorMessage(message); diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/impl/ArBillServiceImpl.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/impl/ArBillServiceImpl.java index 90a8b7da..d2d32457 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/impl/ArBillServiceImpl.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/impl/ArBillServiceImpl.java @@ -37,6 +37,9 @@ import com.ruoyi.ar.domain.ArBillExport; import com.ruoyi.ar.domain.ArBillLog; import com.ruoyi.ar.enums.ArBillStatus; import com.ruoyi.ar.enums.ArExportStatus; +import com.ruoyi.ar.enums.ArLogObjectType; +import com.ruoyi.ar.enums.ArLogOperationSource; +import com.ruoyi.ar.enums.ArLogOperationType; import com.ruoyi.ar.enums.ArLogResult; import com.ruoyi.ar.enums.ArOrderBillStatus; import com.ruoyi.ar.mapper.ArBillDetailFeeMapper; @@ -135,7 +138,8 @@ public class ArBillServiceImpl implements IArBillService public ArBill generateBill(ArBillGenerateRequest request, String operator, String requestId) { validatePeriod(request); - ArBillLog previous = logMapper.selectSuccessByRequestId(requestId, "BILL"); + ArBillLog previous = logMapper.selectSuccessByRequestId(requestId, ArLogObjectType.BILL.getCode(), + ArLogResult.SUCCESS.getCode()); if (previous != null && isNumber(previous.getObjectId())) { return selectArBillById(Long.valueOf(previous.getObjectId())); @@ -144,7 +148,8 @@ public class ArBillServiceImpl implements IArBillService List requestedSourceBillIds = normalizeSourceBillIds(request.getSourceBillIds()); if (requestedSourceBillIds.isEmpty()) { - throw failure(null, "BILL", "", "GENERATE", null, "请至少选择一条有效订单", operator, requestId); + throw failure(null, ArLogObjectType.BILL, "", ArLogOperationType.GENERATE, + null, "请至少选择一条有效订单", operator, requestId); } String requestedCurrency = StringUtils.isEmpty(request.getCurrency()) ? "CNY" : request.getCurrency(); List sources = sourceBillMapper.selectPrcOrderBillByCustomerCutoffAndIds( @@ -152,7 +157,7 @@ public class ArBillServiceImpl implements IArBillService requestedSourceBillIds, ArOrderBillStatus.UNBILLED.getCode()); if (sources == null || sources.isEmpty() || sources.size() != requestedSourceBillIds.size()) { - throw failure(null, "BILL", "", "GENERATE", null, + throw failure(null, ArLogObjectType.BILL, "", ArLogOperationType.GENERATE, null, "部分所选订单已出账、已变更或不符合当前筛选条件,请重新查询后生成", operator, requestId); } @@ -162,7 +167,8 @@ public class ArBillServiceImpl implements IArBillService { if (source.getCurrency() != null && !currency.equalsIgnoreCase(source.getCurrency())) { - throw failure(null, "BILL", "", "GENERATE", null, "截止日期内存在多个币种,不能合并为一张账单", operator, requestId); + throw failure(null, ArLogObjectType.BILL, "", ArLogOperationType.GENERATE, + null, "截止日期内存在多个币种,不能合并为一张账单", operator, requestId); } total = total.add(nvl(source.getIncomeTotal())); } @@ -170,7 +176,7 @@ public class ArBillServiceImpl implements IArBillService ArBankAccount bankAccount = bankAccountMapper.selectDefaultByCurrency(currency); if (bankAccount == null) { - throw failure(null, "BILL", "", "GENERATE", null, + throw failure(null, ArLogObjectType.BILL, "", ArLogOperationType.GENERATE, null, "未配置 " + currency + " 币种的公司默认收款账户,请先完成收款账户配置", operator, requestId); } @@ -206,7 +212,7 @@ public class ArBillServiceImpl implements IArBillService ArOrderBillStatus.UNBILLED.getCode(), ArOrderBillStatus.BILLED.getCode()); if (claimedCount != sourceBillIds.size()) { - throw failure(null, "BILL", "", "GENERATE", null, + throw failure(null, ArLogObjectType.BILL, "", ArLogOperationType.GENERATE, null, "部分计费订单已被其他账单占用,请重新查询后生成", operator, requestId); } @@ -249,7 +255,8 @@ public class ArBillServiceImpl implements IArBillService { detailFeeMapper.insertBatch(detailFees); } - recordSuccess(bill, "CREATE", "生成正式账单", null, ArBillStatus.DRAFT.getCode(), requestId, operator); + recordSuccess(bill, ArLogObjectType.BILL, ArLogOperationType.CREATE, + "生成正式账单", null, ArBillStatus.DRAFT.getCode(), requestId, operator); bill.setBankAccountNo(maskAccount(bill.getBankAccountNo())); return bill; } @@ -261,26 +268,35 @@ public class ArBillServiceImpl implements IArBillService ArBill bill = billMapper.selectArBillByIdForUpdate(arBillId); if (bill == null) { - throw failure(arBillId, "BILL", String.valueOf(arBillId), "CONFIRM", null, "应收账单不存在", operator, requestId); + throw failure(arBillId, ArLogObjectType.BILL, String.valueOf(arBillId), ArLogOperationType.CONFIRM, + null, "应收账单不存在", operator, requestId); } ArBillStatus currentStatus = ArBillStatus.of(bill.getStatus()); if (currentStatus == null || !currentStatus.canConfirm()) { - throw failure(arBillId, "BILL", String.valueOf(arBillId), "CONFIRM", bill.getStatus(), + throw failure(arBillId, ArLogObjectType.BILL, String.valueOf(arBillId), ArLogOperationType.CONFIRM, + bill.getStatus(), "只有草稿账单可以确认,当前状态为 " + bill.getStatus(), operator, requestId); } if (!validateDetails(arBillId, bill.getTotalAmount())) { - throw failure(arBillId, "BILL", String.valueOf(arBillId), "CONFIRM", bill.getStatus(), + throw failure(arBillId, ArLogObjectType.BILL, String.valueOf(arBillId), ArLogOperationType.CONFIRM, + bill.getStatus(), "账单费用明细汇总与订单或账单总额不一致", operator, requestId); } if (billMapper.updateArBillStatus(arBillId, ArBillStatus.CONFIRMED.getCode(), StringUtils.isEmpty(request == null ? null : request.getRemark()) ? bill.getRemark() : request.getRemark(), operator, ArBillStatus.DRAFT.getCode()) != 1) { - throw failure(arBillId, "BILL", String.valueOf(arBillId), "CONFIRM", bill.getStatus(), + throw failure(arBillId, ArLogObjectType.BILL, String.valueOf(arBillId), ArLogOperationType.CONFIRM, + bill.getStatus(), "账单状态已发生变化,请刷新后重试", operator, requestId); } + // 账单确认:应收形成,按账单金额占用客户授信额度(账户不存在时仅CNY会自动初始化) + customerMoneyService.occupyCredit(bill.getCustomerId(), bill.getCurrency(), + nvl(bill.getTotalAmount())); + recordSuccess(bill, ArLogObjectType.BILL, ArLogOperationType.CONFIRM, + "确认应收账单", ArBillStatus.DRAFT.getCode(), ArBillStatus.CONFIRMED.getCode(), requestId, operator); // 账单确认:应收形成,按账单金额占用客户授信额度(账户不存在时仅CNY会自动初始化)。 // 不校验可用额度,兼容历史 used_credit 可高于总额度、外币账户静默跳过的口径 customerAccountApi.occupyCredit(buildCreditCommand(bill)); @@ -295,17 +311,20 @@ public class ArBillServiceImpl implements IArBillService String remark = request == null ? null : request.getRemark(); if (StringUtils.isEmpty(remark)) { - throw failure(arBillId, "BILL", String.valueOf(arBillId), "VOID", null, "作废必须填写原因", operator, requestId); + throw failure(arBillId, ArLogObjectType.BILL, String.valueOf(arBillId), ArLogOperationType.VOID, + null, "作废必须填写原因", operator, requestId); } ArBill bill = billMapper.selectArBillByIdForUpdate(arBillId); if (bill == null) { - throw failure(arBillId, "BILL", String.valueOf(arBillId), "VOID", null, "应收账单不存在", operator, requestId); + throw failure(arBillId, ArLogObjectType.BILL, String.valueOf(arBillId), ArLogOperationType.VOID, + null, "应收账单不存在", operator, requestId); } ArBillStatus currentStatus = ArBillStatus.of(bill.getStatus()); if (currentStatus == null || !currentStatus.canVoid()) { - throw failure(arBillId, "BILL", String.valueOf(arBillId), "VOID", bill.getStatus(), + throw failure(arBillId, ArLogObjectType.BILL, String.valueOf(arBillId), ArLogOperationType.VOID, + bill.getStatus(), "当前状态不允许作废", operator, requestId); } List sourceBillIds = new ArrayList<>(); @@ -318,13 +337,15 @@ public class ArBillServiceImpl implements IArBillService } if (billMapper.updateArBillStatus(arBillId, ArBillStatus.VOID.getCode(), remark, operator, currentStatus.getCode()) != 1) { - throw failure(arBillId, "BILL", String.valueOf(arBillId), "VOID", bill.getStatus(), + throw failure(arBillId, ArLogObjectType.BILL, String.valueOf(arBillId), ArLogOperationType.VOID, + bill.getStatus(), "账单状态已发生变化,请刷新后重试", operator, requestId); } // 账单作废:已确认账单占用的授信额度全额释放(可作废的CONFIRMED账单必然零核销) if (currentStatus == ArBillStatus.CONFIRMED) { - customerAccountApi.releaseCredit(buildCreditCommand(bill)); + customerMoneyService.releaseCredit(bill.getCustomerId(), bill.getCurrency(), + nvl(bill.getTotalAmount())); } if (!sourceBillIds.isEmpty()) { @@ -332,18 +353,21 @@ public class ArBillServiceImpl implements IArBillService ArOrderBillStatus.BILLED.getCode(), ArOrderBillStatus.UNBILLED.getCode()); if (releasedCount != sourceBillIds.size()) { - throw failure(arBillId, "BILL", String.valueOf(arBillId), "VOID", bill.getStatus(), + throw failure(arBillId, ArLogObjectType.BILL, String.valueOf(arBillId), ArLogOperationType.VOID, + bill.getStatus(), "部分来源订单状态异常,账单未作废,请刷新后重试", operator, requestId); } } - recordSuccess(bill, "VOID", "作废应收账单:" + remark, bill.getStatus(), ArBillStatus.VOID.getCode(), requestId, operator); + recordSuccess(bill, ArLogObjectType.BILL, ArLogOperationType.VOID, + "作废应收账单:" + remark, bill.getStatus(), ArBillStatus.VOID.getCode(), requestId, operator); return selectArBillById(arBillId); } @Override public ArBillExport exportBill(Long arBillId, String operator, String requestId) { - ArBillLog previous = logMapper.selectSuccessByRequestId(requestId, "EXPORT"); + 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())); @@ -355,11 +379,13 @@ public class ArBillServiceImpl implements IArBillService ArBill bill = billMapper.selectArBillById(arBillId); if (bill == null) { - throw failure(arBillId, "EXPORT", String.valueOf(arBillId), "EXPORT", null, "应收账单不存在", operator, requestId); + throw failure(arBillId, ArLogObjectType.EXPORT, String.valueOf(arBillId), ArLogOperationType.EXPORT, + null, "应收账单不存在", operator, requestId); } if (ArBillStatus.is(bill.getStatus(), ArBillStatus.DRAFT) || ArBillStatus.is(bill.getStatus(), ArBillStatus.VOID)) { - throw failure(arBillId, "EXPORT", String.valueOf(arBillId), "EXPORT", bill.getStatus(), + throw failure(arBillId, ArLogObjectType.EXPORT, String.valueOf(arBillId), ArLogOperationType.EXPORT, + bill.getStatus(), "草稿或作废账单不可导出", operator, requestId); } fillDetails(bill); @@ -385,7 +411,8 @@ public class ArBillServiceImpl implements IArBillService export.setFileHash(sha256(data)); export.setExportStatus(ArExportStatus.SUCCESS.getCode()); exportMapper.insert(export); - recordSuccess(bill, "EXPORT", "导出账单 XLSX", bill.getStatus(), bill.getStatus(), requestId, operator, export.getExportId()); + recordSuccess(bill, ArLogObjectType.EXPORT, ArLogOperationType.EXPORT, + "导出账单 XLSX", bill.getStatus(), bill.getStatus(), requestId, operator, export.getExportId()); return export; } catch (Exception e) @@ -394,7 +421,8 @@ public class ArBillServiceImpl implements IArBillService export.setExportStatus(ArExportStatus.FAILED.getCode()); export.setRemark(e.getMessage()); exportMapper.insert(export); - logService.recordFailure(arBillId, "EXPORT", String.valueOf(arBillId), "EXPORT", bill.getStatus(), + logService.recordFailure(arBillId, ArLogObjectType.EXPORT, String.valueOf(arBillId), ArLogOperationType.EXPORT, + bill.getStatus(), e.getMessage(), operator, requestId); throw new ServiceException("账单导出失败:" + e.getMessage()); } @@ -513,20 +541,20 @@ public class ArBillServiceImpl implements IArBillService return fee; } - private void recordSuccess(ArBill bill, String operationType, String desc, String fromStatus, + private void recordSuccess(ArBill bill, ArLogObjectType objectType, ArLogOperationType operationType, String desc, String fromStatus, String toStatus, String requestId, String operator) { - recordSuccess(bill, operationType, desc, fromStatus, toStatus, requestId, operator, null); + recordSuccess(bill, objectType, operationType, desc, fromStatus, toStatus, requestId, operator, null); } - private void recordSuccess(ArBill bill, String operationType, String desc, String fromStatus, + private void recordSuccess(ArBill bill, ArLogObjectType objectType, ArLogOperationType operationType, String desc, String fromStatus, String toStatus, String requestId, String operator, Long objectId) { ArBillLog log = new ArBillLog(); log.setArBillId(bill.getArBillId()); - log.setObjectType("BILL".equals(operationType) ? "BILL" : operationType.equals("EXPORT") ? "EXPORT" : "BILL"); + log.setObjectType(objectType.getCode()); log.setObjectId(objectId == null ? String.valueOf(bill.getArBillId()) : String.valueOf(objectId)); - log.setOperationType(operationType); + log.setOperationType(operationType.getCode()); log.setOperationDesc(desc); log.setFromStatus(fromStatus); log.setToStatus(toStatus); @@ -534,13 +562,13 @@ public class ArBillServiceImpl implements IArBillService log.setAfterData(safeStatusJson(toStatus)); log.setOperatorId(operator); log.setOperatorName(operator); - log.setOperationSource("WEB"); + log.setOperationSource(ArLogOperationSource.WEB.getCode()); log.setRequestId(requestId); log.setResult(ArLogResult.SUCCESS.getCode()); logService.record(log); } - private ServiceException failure(Long arBillId, String objectType, String objectId, String operationType, + private ServiceException failure(Long arBillId, ArLogObjectType objectType, String objectId, ArLogOperationType operationType, String fromStatus, String message, String operator, String requestId) { logService.recordFailure(arBillId, objectType, objectId, operationType, fromStatus, message, operator, requestId); @@ -861,21 +889,6 @@ public class ArBillServiceImpl implements IArBillService private BigDecimal decimal(BigDecimal value, int scale) { return value == null ? null : value.setScale(scale, java.math.RoundingMode.HALF_UP); } private BigDecimal nvl(BigDecimal value) { return value == null ? BigDecimal.ZERO : value; } - - /** 构造账单授信占用/释放命令(确认占用、作废释放共用,关联账单单据便于流水追溯) */ - private CreditUsageCommand buildCreditCommand(ArBill bill) - { - CreditUsageCommand command = new CreditUsageCommand(); - command.setCustomerId(bill.getCustomerId()); - command.setCurrency(bill.getCurrency()); - command.setAmount(nvl(bill.getTotalAmount())); - command.setBizType(CustomerFundBizType.AR_BILL); - command.setBizId(bill.getArBillId()); - command.setBizNo(bill.getBillNo()); - // 兼容历史口径:不校验可用额度(允许 used_credit 高于总额度、外币账户静默跳过) - command.setCheckAvailable(Boolean.FALSE); - return command; - } private String safeFilePart(String value) { return StringUtils.isEmpty(value) ? "客户" : value.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5_-]", "_"); } private String maskAccount(String value) { if (StringUtils.isEmpty(value)) return ""; return value.length() <= 4 ? "****" : "****" + value.substring(value.length() - 4); } private String sha256(byte[] data) throws NoSuchAlgorithmException { byte[] digest = MessageDigest.getInstance("SHA-256").digest(data); StringBuilder sb = new StringBuilder(); for (byte b : digest) sb.append(String.format("%02x", b)); return sb.toString(); } diff --git a/bms-back/ruoyi-system/src/main/resources/mapper/ar/ArBalanceWriteoffMapper.xml b/bms-back/ruoyi-system/src/main/resources/mapper/ar/ArBalanceWriteoffMapper.xml index 012299b3..c84ad7aa 100644 --- a/bms-back/ruoyi-system/src/main/resources/mapper/ar/ArBalanceWriteoffMapper.xml +++ b/bms-back/ruoyi-system/src/main/resources/mapper/ar/ArBalanceWriteoffMapper.xml @@ -65,12 +65,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update ar_balance_writeoff - set status = 'CANCELLED', + set status = #{status}, reverse_flow_id = #{reverseFlowId}, cancel_by = #{cancelBy}, cancel_time = sysdate(), cancel_remark = #{cancelRemark} - where writeoff_id = #{writeoffId} and status = 'EFFECTIVE' + where writeoff_id = #{writeoffId} and status = #{effectiveStatus} diff --git a/bms-back/sql/ar/ar_balance_writeoff.sql b/bms-back/sql/ar/ar_balance_writeoff.sql index d66d7378..765618bc 100644 --- a/bms-back/sql/ar/ar_balance_writeoff.sql +++ b/bms-back/sql/ar/ar_balance_writeoff.sql @@ -19,7 +19,7 @@ CREATE TABLE IF NOT EXISTS ar_balance_writeoff ( balance_flow_id BIGINT(20) DEFAULT NULL COMMENT '核销扣余额流水ID', reverse_flow_id BIGINT(20) DEFAULT NULL COMMENT '反核销回补余额流水ID', writeoff_date DATE NOT NULL COMMENT '核销日期', - status VARCHAR(30) NOT NULL COMMENT 'EFFECTIVE/CANCELLED', + status VARCHAR(30) NOT NULL COMMENT '状态:EFFECTIVE=有效(已扣减客户余额),CANCELLED=已反核销(已回补客户余额)', remark VARCHAR(500) DEFAULT NULL COMMENT '核销备注', create_by VARCHAR(64) NOT NULL COMMENT '创建人', create_time DATETIME NOT NULL COMMENT '创建时间', diff --git a/bms-back/sql/ar/ar_bill.sql b/bms-back/sql/ar/ar_bill.sql index a79dd7ad..850b7806 100644 --- a/bms-back/sql/ar/ar_bill.sql +++ b/bms-back/sql/ar/ar_bill.sql @@ -21,7 +21,7 @@ CREATE TABLE IF NOT EXISTS ar_bill ( total_amount DECIMAL(18,2) NOT NULL DEFAULT 0.00 COMMENT '账单应收总额', written_off_amount DECIMAL(18,2) NOT NULL DEFAULT 0.00 COMMENT '已核销金额缓存', unwritten_amount DECIMAL(18,2) NOT NULL DEFAULT 0.00 COMMENT '未核销金额缓存', - status VARCHAR(30) NOT NULL COMMENT 'DRAFT/CONFIRMED/PARTIAL_WRITTEN_OFF/WRITTEN_OFF/VOID', + status VARCHAR(30) NOT NULL COMMENT '状态:DRAFT=草稿,CONFIRMED=已确认,PARTIAL_WRITTEN_OFF=部分核销,WRITTEN_OFF=已核销,VOID=已作废', bill_version INT(11) NOT NULL DEFAULT 1 COMMENT '账单版本', bank_account_name VARCHAR(100) DEFAULT NULL COMMENT '收款账户名称快照', bank_account_no VARCHAR(128) DEFAULT NULL COMMENT '收款账号快照,应用层脱敏展示', @@ -109,7 +109,7 @@ CREATE TABLE IF NOT EXISTS ar_bill_export ( file_size BIGINT(20) DEFAULT NULL COMMENT '文件字节数', file_hash VARCHAR(128) DEFAULT NULL COMMENT 'SHA-256校验值', row_count INT(11) DEFAULT NULL COMMENT '导出订单行数', - export_status VARCHAR(30) NOT NULL COMMENT 'PROCESSING/SUCCESS/FAILED', + export_status VARCHAR(30) NOT NULL COMMENT '导出状态:PROCESSING=生成中,SUCCESS=成功(可下载),FAILED=失败', export_by VARCHAR(64) NOT NULL COMMENT '导出人', export_time DATETIME NOT NULL COMMENT '导出时间', remark VARCHAR(500) DEFAULT NULL COMMENT '失败原因或备注', @@ -122,9 +122,9 @@ CREATE TABLE IF NOT EXISTS ar_bill_export ( CREATE TABLE IF NOT EXISTS ar_bill_log ( log_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '日志ID', ar_bill_id BIGINT(20) DEFAULT NULL COMMENT '账单ID', - object_type VARCHAR(40) NOT NULL COMMENT 'BILL/EXPORT/BALANCE_WRITEOFF', + object_type VARCHAR(40) NOT NULL COMMENT '对象类型:BILL=应收账单,EXPORT=账单导出,BALANCE_WRITEOFF=余额核销;历史值可能包含已下线模块类型', object_id VARCHAR(64) NOT NULL COMMENT '通用对象ID', - operation_type VARCHAR(40) NOT NULL COMMENT '操作类型:CONFIRM/VOID/EXPORT/BALANCE_WRITEOFF/CANCEL_BALANCE_WRITEOFF', + operation_type VARCHAR(40) NOT NULL COMMENT '操作类型:CREATE=生成账单,GENERATE=生成校验,CONFIRM=确认账单,VOID=作废账单,EXPORT=导出账单,BALANCE_WRITEOFF=余额核销,CANCEL_BALANCE_WRITEOFF=取消余额核销', operation_desc VARCHAR(500) DEFAULT NULL COMMENT '操作说明', from_status VARCHAR(30) DEFAULT NULL COMMENT '变更前状态', to_status VARCHAR(30) DEFAULT NULL COMMENT '变更后状态', @@ -132,10 +132,10 @@ CREATE TABLE IF NOT EXISTS ar_bill_log ( after_data TEXT COMMENT '变更后安全快照', operator_id VARCHAR(64) NOT NULL COMMENT '操作人ID', operator_name VARCHAR(100) DEFAULT NULL COMMENT '操作人名称', - operation_source VARCHAR(30) NOT NULL COMMENT 'WEB/API/JOB/IMPORT', + operation_source VARCHAR(30) NOT NULL COMMENT '操作来源:WEB=网页端,API=接口,JOB=定时任务,IMPORT=数据导入', request_id VARCHAR(64) DEFAULT NULL COMMENT '请求幂等标识', trace_id VARCHAR(64) DEFAULT NULL COMMENT '链路标识', - result VARCHAR(20) NOT NULL COMMENT 'SUCCESS/FAILED', + result VARCHAR(20) NOT NULL COMMENT '执行结果:SUCCESS=成功,FAILED=失败', error_message VARCHAR(1000) DEFAULT NULL COMMENT '失败原因', client_ip VARCHAR(64) DEFAULT NULL COMMENT '来源IP', create_time DATETIME NOT NULL COMMENT '日志时间', diff --git a/bms-back/sql/ar/ar_bill_log_balance_writeoff_comment.sql b/bms-back/sql/ar/ar_bill_log_balance_writeoff_comment.sql index 1461df30..e8e57ea0 100644 --- a/bms-back/sql/ar/ar_bill_log_balance_writeoff_comment.sql +++ b/bms-back/sql/ar/ar_bill_log_balance_writeoff_comment.sql @@ -1,6 +1,10 @@ --- 应收日志兼容余额核销:仅更新字段注释,不改变字段类型和历史数据 +-- 应收日志枚举中文说明:仅更新字段注释,不改变字段类型、历史数据和业务逻辑 ALTER TABLE ar_bill_log MODIFY COLUMN object_type VARCHAR(40) NOT NULL - COMMENT 'BILL/EXPORT/BALANCE_WRITEOFF', + COMMENT '对象类型:BILL=应收账单,EXPORT=账单导出,BALANCE_WRITEOFF=余额核销;历史值可能包含已下线模块类型', MODIFY COLUMN operation_type VARCHAR(40) NOT NULL - COMMENT '操作类型:CONFIRM/VOID/EXPORT/BALANCE_WRITEOFF/CANCEL_BALANCE_WRITEOFF'; + COMMENT '操作类型:CREATE=生成账单,GENERATE=生成校验,CONFIRM=确认账单,VOID=作废账单,EXPORT=导出账单,BALANCE_WRITEOFF=余额核销,CANCEL_BALANCE_WRITEOFF=取消余额核销', + MODIFY COLUMN operation_source VARCHAR(30) NOT NULL + COMMENT '操作来源:WEB=网页端,API=接口,JOB=定时任务,IMPORT=数据导入', + MODIFY COLUMN result VARCHAR(20) NOT NULL + COMMENT '执行结果:SUCCESS=成功,FAILED=失败'; diff --git a/bms-back/sql/ar/ar_status_enum_comment_migration.sql b/bms-back/sql/ar/ar_status_enum_comment_migration.sql new file mode 100644 index 00000000..fff85ef1 --- /dev/null +++ b/bms-back/sql/ar/ar_status_enum_comment_migration.sql @@ -0,0 +1,30 @@ +-- ===================================================================== +-- 应收模块枚举中文说明迁移 +-- +-- 目的:为数据库中的状态/日志枚举补充中文业务含义,方便运维和数据排查。 +-- 说明:本脚本只修改字段 COMMENT,不修改字段类型、历史数据、索引或业务状态值。 +-- ALTER TABLE ... MODIFY COLUMN 可重复执行;已执行过旧注释脚本的环境也可直接执行。 +-- ===================================================================== +SET NAMES utf8mb4; + +ALTER TABLE ar_balance_writeoff + MODIFY COLUMN status VARCHAR(30) NOT NULL + COMMENT '状态:EFFECTIVE=有效(已扣减客户余额),CANCELLED=已反核销(已回补客户余额)'; + +ALTER TABLE ar_bill + MODIFY COLUMN status VARCHAR(30) NOT NULL + COMMENT '状态:DRAFT=草稿,CONFIRMED=已确认,PARTIAL_WRITTEN_OFF=部分核销,WRITTEN_OFF=已核销,VOID=已作废'; + +ALTER TABLE ar_bill_export + MODIFY COLUMN export_status VARCHAR(30) NOT NULL + COMMENT '导出状态:PROCESSING=生成中,SUCCESS=成功(可下载),FAILED=失败'; + +ALTER TABLE ar_bill_log + MODIFY COLUMN object_type VARCHAR(40) NOT NULL + COMMENT '对象类型:BILL=应收账单,EXPORT=账单导出,BALANCE_WRITEOFF=余额核销;历史值可能包含已下线模块类型', + MODIFY COLUMN operation_type VARCHAR(40) NOT NULL + COMMENT '操作类型:CREATE=生成账单,GENERATE=生成校验,CONFIRM=确认账单,VOID=作废账单,EXPORT=导出账单,BALANCE_WRITEOFF=余额核销,CANCEL_BALANCE_WRITEOFF=取消余额核销', + MODIFY COLUMN operation_source VARCHAR(30) NOT NULL + COMMENT '操作来源:WEB=网页端,API=接口,JOB=定时任务,IMPORT=数据导入', + MODIFY COLUMN result VARCHAR(20) NOT NULL + COMMENT '执行结果:SUCCESS=成功,FAILED=失败'; diff --git a/bms-front/src/constants/ar/bill.js b/bms-front/src/constants/ar/bill.js index c3f2d0cb..1ee8516f 100644 --- a/bms-front/src/constants/ar/bill.js +++ b/bms-front/src/constants/ar/bill.js @@ -1,23 +1,6 @@ -export const AR_BILL_STATUS = Object.freeze({ - DRAFT: 'DRAFT', - CONFIRMED: 'CONFIRMED', - PARTIAL_WRITTEN_OFF: 'PARTIAL_WRITTEN_OFF', - WRITTEN_OFF: 'WRITTEN_OFF', - VOID: 'VOID' -}) - -export const AR_BILL_STATUS_OPTIONS = Object.freeze([ - { label: '草稿', value: AR_BILL_STATUS.DRAFT }, - { label: '已确认', value: AR_BILL_STATUS.CONFIRMED }, - { label: '部分核销', value: AR_BILL_STATUS.PARTIAL_WRITTEN_OFF }, - { label: '已核销', value: AR_BILL_STATUS.WRITTEN_OFF }, - { label: '已作废', value: AR_BILL_STATUS.VOID } -]) - -export const AR_BILL_STATUS_TYPES = Object.freeze({ - [AR_BILL_STATUS.DRAFT]: 'info', - [AR_BILL_STATUS.CONFIRMED]: 'primary', - [AR_BILL_STATUS.PARTIAL_WRITTEN_OFF]: 'warning', - [AR_BILL_STATUS.WRITTEN_OFF]: 'success', - [AR_BILL_STATUS.VOID]: 'danger' -}) +// 保留旧的导入路径,统一从应收枚举文件导出,避免页面各自维护状态编码。 +export { + AR_BILL_STATUS, + AR_BILL_STATUS_OPTIONS, + AR_BILL_STATUS_TYPES +} from './enums' diff --git a/bms-front/src/views/ar/bill/components/BillDetail.vue b/bms-front/src/views/ar/bill/components/BillDetail.vue index 2bb34d81..8da3f728 100644 --- a/bms-front/src/views/ar/bill/components/BillDetail.vue +++ b/bms-front/src/views/ar/bill/components/BillDetail.vue @@ -43,10 +43,10 @@ - + - + @@ -54,13 +54,16 @@ diff --git a/bms-front/src/views/ar/bill/log.vue b/bms-front/src/views/ar/bill/log.vue index bb77b4a8..552a3960 100644 --- a/bms-front/src/views/ar/bill/log.vue +++ b/bms-front/src/views/ar/bill/log.vue @@ -1,30 +1,41 @@ diff --git a/bms-front/src/views/customersuppliermanagement/customerinfo/customermoney/index.vue b/bms-front/src/views/customersuppliermanagement/customerinfo/customermoney/index.vue index d3f21a64..caeade6c 100644 --- a/bms-front/src/views/customersuppliermanagement/customerinfo/customermoney/index.vue +++ b/bms-front/src/views/customersuppliermanagement/customerinfo/customermoney/index.vue @@ -485,8 +485,7 @@ - - + @@ -506,8 +505,8 @@ @@ -519,7 +518,7 @@