From df7220d333d529a0da9528555903083bb88354f9 Mon Sep 17 00:00:00 2001 From: caojia <1301869380@qq.com> Date: Wed, 28 Oct 2026 20:13:20 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E2=80=9C=E6=94=B6=E6=AC=BE=E5=85=A5?= =?UTF-8?q?=E8=B4=A6=E2=80=9D=E5=92=8C=E2=80=9C=E8=B4=A6=E5=8D=95=E6=A0=B8?= =?UTF-8?q?=E9=94=80=E2=80=9D=E5=88=86=E5=BC=80=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ar/ArReceiptController.java | 9 +- .../impl/ArBalanceWriteoffServiceImpl.java | 4 +- .../api/ICustomerAccountApi.java | 2 +- .../customermoney/domain/CustomerReceipt.java | 8 +- .../domain/ReceiptWriteoffPlan.java | 14 +- .../mapper/CustomerMoneyMapper.java | 2 +- .../mapper/ReceiptWriteoffPlanMapper.java | 12 +- .../impl/CustomerMoneyServiceImpl.java | 186 +------------- .../vo/CustomerReceiptExportVO.java | 4 +- .../mapper/customer/CustomerMoneyMapper.xml | 12 +- .../customer/ReceiptWriteoffPlanMapper.xml | 20 -- bms-back/sql/bms_init.sql | 2 +- bms-front/src/views/ar/receipt/index.vue | 223 +---------------- .../customerinfo/customermoney/index.vue | 235 +----------------- 14 files changed, 64 insertions(+), 669 deletions(-) diff --git a/bms-back/bms-admin/src/main/java/com/bms/web/controller/ar/ArReceiptController.java b/bms-back/bms-admin/src/main/java/com/bms/web/controller/ar/ArReceiptController.java index 59a66ffa..5e0cc246 100644 --- a/bms-back/bms-admin/src/main/java/com/bms/web/controller/ar/ArReceiptController.java +++ b/bms-back/bms-admin/src/main/java/com/bms/web/controller/ar/ArReceiptController.java @@ -27,8 +27,7 @@ import com.bms.customer.customermoney.service.ICustomerMoneyService; * 收款管理 Controller(账单管理-收款管理) *

* 收款登记/审核/取消与「客户余额-登记收款」复用同一套 Service 逻辑; - * 账单核销同样复用余额核销 Service:登记收款时可携带核销计划(审核通过后联动核销), - * 本页「账单核销」页签可直接对账单发起核销/反核销。 + * 收款审核只将款项计入客户余额;账单核销由本页「账单核销」页签单独执行。 * * @author bms * @date 2026-10-13 @@ -82,7 +81,7 @@ public class ArReceiptController extends BaseController } /** - * 登记收款(必须选择客户;默认待确认,审核通过后入账并执行登记时选择的核销计划) + * 登记收款(必须选择客户;默认待确认,审核通过后将款项计入客户余额) */ @PreAuthorize("@ss.hasPermi('ar:receipt:add')") @Log(title = "收款管理-登记收款", businessType = BusinessType.INSERT) @@ -94,7 +93,7 @@ public class ArReceiptController extends BaseController } /** - * 审核通过收款单:确认后金额计入客户余额,登记时选择的账单一并核销 + * 审核通过收款单:确认后仅将收款金额计入客户余额,账单核销由账单核销页单独执行 */ @PreAuthorize("@ss.hasPermi('ar:receipt:review')") @Log(title = "收款管理-收款审核", businessType = BusinessType.UPDATE) @@ -116,7 +115,7 @@ public class ArReceiptController extends BaseController } /** - * 查询客户可核销账单(已确认/部分核销,未核销额大于0),登记收款选账单与核销页签共用 + * 查询客户可核销账单(已确认/部分核销,未核销额大于0),供账单核销页使用 */ @PreAuthorize("@ss.hasPermi('ar:receipt:list')") @GetMapping("/bill/unsettled/{customerId}") diff --git a/bms-back/bms-system/src/main/java/com/bms/ar/service/impl/ArBalanceWriteoffServiceImpl.java b/bms-back/bms-system/src/main/java/com/bms/ar/service/impl/ArBalanceWriteoffServiceImpl.java index 3786331b..00e91757 100644 --- a/bms-back/bms-system/src/main/java/com/bms/ar/service/impl/ArBalanceWriteoffServiceImpl.java +++ b/bms-back/bms-system/src/main/java/com/bms/ar/service/impl/ArBalanceWriteoffServiceImpl.java @@ -246,10 +246,8 @@ public class ArBalanceWriteoffServiceImpl implements IArBalanceWriteoffService { String receiptType; if (newAllocated.compareTo(BigDecimal.ZERO) == 0) { receiptType = CustomerReceipt.TYPE_PREPAY; - } else if (newAllocated.compareTo(base) >= 0) { - receiptType = CustomerReceipt.TYPE_REPAY; } else { - receiptType = CustomerReceipt.TYPE_MIXED; + receiptType = CustomerReceipt.TYPE_REPAY; } CustomerReceipt update = new CustomerReceipt(); diff --git a/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/api/ICustomerAccountApi.java b/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/api/ICustomerAccountApi.java index f3b79bfd..47c04edc 100644 --- a/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/api/ICustomerAccountApi.java +++ b/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/api/ICustomerAccountApi.java @@ -20,7 +20,7 @@ import com.bms.customer.customermoney.vo.CustomerAccountStatusVO; *

  • 收款审核入账/退款:{@link #refundBalance} 加余额
  • * * - *

    注意(核销口径):应收账单的余额核销与反核销(含收款审核联动核销)不调用本接口, + *

    注意(核销口径):应收账单的余额核销与反核销(含历史收款审核联动核销)不调用本接口, * 只更新账单已核销/未核销金额与状态,客户余额与授信额度均不发生变动。

    * * @author bms diff --git a/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/domain/CustomerReceipt.java b/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/domain/CustomerReceipt.java index ebfc1722..cac14a36 100644 --- a/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/domain/CustomerReceipt.java +++ b/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/domain/CustomerReceipt.java @@ -30,10 +30,8 @@ public class CustomerReceipt extends BaseEntity /** 收款类型:预充值 */ public static final String TYPE_PREPAY = "PREPAY"; - /** 收款类型:还款核销 */ + /** 收款类型:还款 */ public static final String TYPE_REPAY = "REPAY"; - /** 收款类型:混合 */ - public static final String TYPE_MIXED = "MIXED"; /** 汇率来源:系统默认(本币CNY 1:1) */ public static final String RATE_SOURCE_SYSTEM = "SYSTEM"; @@ -60,7 +58,7 @@ public class CustomerReceipt extends BaseEntity /** 客户账户ID(预留) */ private Long accountId; - /** 收款类型:PREPAY预充值/REPAY还款核销/MIXED混合 */ + /** 收款类型:PREPAY预充值/REPAY还款 */ private String receiptType; /** 收款金额 */ @@ -131,7 +129,7 @@ public class CustomerReceipt extends BaseEntity /** 收款附件列表(存 ctr_customer_attachment,attachment_type='3',biz_id 关联本单) */ private List attachmentList; - /** 核销账单计划(登记时选择,审核通过后一并核销) */ + /** 历史收款单关联的核销计划;新登记收款不再创建计划 */ private List writeoffPlans; /** 收款附件数量(列表查询统计) */ diff --git a/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/domain/ReceiptWriteoffPlan.java b/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/domain/ReceiptWriteoffPlan.java index 5dd38c43..6431413a 100644 --- a/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/domain/ReceiptWriteoffPlan.java +++ b/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/domain/ReceiptWriteoffPlan.java @@ -10,9 +10,9 @@ import lombok.EqualsAndHashCode; /** * 收款单核销账单计划 ctr_receipt_writeoff_plan * - *

    登记收款时指定待核销的应收账单(PENDING);收款审核通过后在同一事务内逐张执行核销, - * 回写核销单ID并置 EFFECTIVE;待审核收款单被取消则置 CANCELLED; - * 已生效的核销单后续在“余额核销”页被反核销则置 REVERSED(核销/反核销均不改动客户余额与额度)。

    + *

    兼容历史收款单关联的账单核销记录。新收款不再创建联动核销计划; + * 历史待审核计划在收款确认或取消时置 CANCELLED;已执行记录保留用于审计, + * 已生效核销单在“余额核销”页反核销后置 REVERSED。

    * * @author bms * @date 2026-10-08 @@ -23,13 +23,13 @@ public class ReceiptWriteoffPlan extends BaseEntity { private static final long serialVersionUID = 1L; - /** 状态:待执行(收款单待审核) */ + /** 状态:历史待审核计划 */ public static final String STATUS_PENDING = "PENDING"; - /** 状态:已核销(收款审核通过并完成账单核销) */ + /** 状态:已核销(历史收款审核联动完成) */ public static final String STATUS_EFFECTIVE = "EFFECTIVE"; - /** 状态:已作废(待审核收款单被取消,计划未执行) */ + /** 状态:已作废(收款单取消或确认时清理历史待执行计划) */ public static final String STATUS_CANCELLED = "CANCELLED"; - /** 状态:已反核销(审核联动核销后,核销单在余额核销页被反核销) */ + /** 状态:已反核销(关联的核销单在余额核销页被反核销) */ public static final String STATUS_REVERSED = "REVERSED"; /** 主键 */ diff --git a/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/mapper/CustomerMoneyMapper.java b/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/mapper/CustomerMoneyMapper.java index 0c0185d3..241386a6 100644 --- a/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/mapper/CustomerMoneyMapper.java +++ b/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/mapper/CustomerMoneyMapper.java @@ -62,7 +62,7 @@ public interface CustomerMoneyMapper /** 新增收款单 */ int insertReceipt(CustomerReceipt receipt); - /** 审核通过:PENDING -> CONFIRMED(带状态+乐观锁条件) */ + /** 审核通过:PENDING -> CONFIRMED,回写未分配金额(带状态+乐观锁条件) */ int confirmReceipt(CustomerReceipt receipt); /** 取消收款单:PENDING -> CANCELLED */ diff --git a/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/mapper/ReceiptWriteoffPlanMapper.java b/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/mapper/ReceiptWriteoffPlanMapper.java index 86395941..e57e3baf 100644 --- a/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/mapper/ReceiptWriteoffPlanMapper.java +++ b/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/mapper/ReceiptWriteoffPlanMapper.java @@ -5,25 +5,17 @@ import org.apache.ibatis.annotations.Param; import com.bms.customer.customermoney.domain.ReceiptWriteoffPlan; /** - * 收款单核销账单计划 Mapper + * 历史收款单核销关联 Mapper * * @author bms * @date 2026-10-08 */ public interface ReceiptWriteoffPlanMapper { - /** 新增一条核销计划 */ - int insertPlan(ReceiptWriteoffPlan plan); - /** 按收款单查询全部计划(关联账单展示字段,按计划ID升序) */ List selectByReceiptId(@Param("receiptId") Long receiptId); - /** 执行成功回写:PENDING -> EFFECTIVE,记录核销单ID与核销日期 */ - int updateEffective(@Param("planId") Long planId, - @Param("writeoffId") Long writeoffId, - @Param("updateBy") String updateBy); - - /** 收款单取消:其全部 PENDING 计划置 CANCELLED */ + /** 收款确认或取消:其历史 PENDING 计划置 CANCELLED */ int cancelPendingByReceiptId(@Param("receiptId") Long receiptId, @Param("updateBy") String updateBy); diff --git a/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/service/impl/CustomerMoneyServiceImpl.java b/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/service/impl/CustomerMoneyServiceImpl.java index 9b2b7b77..3437ef1a 100644 --- a/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/service/impl/CustomerMoneyServiceImpl.java +++ b/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/service/impl/CustomerMoneyServiceImpl.java @@ -5,11 +5,8 @@ import java.math.RoundingMode; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.ArrayList; import java.util.Date; -import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.concurrent.ThreadLocalRandom; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -18,13 +15,8 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import com.bms.common.exception.ServiceException; import com.bms.common.utils.SecurityUtils; -import com.bms.ar.domain.ArBalanceWriteoff; import com.bms.ar.domain.ArBankAccount; -import com.bms.ar.domain.ArBill; -import com.bms.ar.enums.ArBillStatus; import com.bms.ar.mapper.ArBankAccountMapper; -import com.bms.ar.mapper.ArBillMapper; -import com.bms.ar.service.IArBalanceWriteoffService; import com.bms.customer.customerinfo.domain.BmsCustomer; import com.bms.customer.customerinfo.domain.BmsCustomerAttachment; import com.bms.customer.customerinfo.mapper.BmsCustomerMapper; @@ -36,7 +28,6 @@ import com.bms.customer.customermoney.domain.CustomerBalanceFlow; import com.bms.customer.customermoney.domain.CustomerCreditApply; import com.bms.customer.customermoney.domain.CustomerCreditFlow; import com.bms.customer.customermoney.domain.CustomerReceipt; -import com.bms.customer.customermoney.domain.ReceiptWriteoffPlan; import com.bms.customer.customermoney.mapper.CustomerCreditApplyMapper; import com.bms.customer.customermoney.mapper.CustomerMoneyMapper; import com.bms.customer.customermoney.mapper.ReceiptWriteoffPlanMapper; @@ -89,18 +80,10 @@ public class CustomerMoneyServiceImpl implements ICustomerMoneyService @Autowired private ArBankAccountMapper arBankAccountMapper; - /** 应收账单:登记收款选择核销账单时校验账单状态/未核销额 */ - @Autowired - private ArBillMapper arBillMapper; - - /** 收款核销计划 */ + /** 历史收款核销计划:仅用于查询及处理旧计划 */ @Autowired private ReceiptWriteoffPlanMapper receiptWriteoffPlanMapper; - /** 余额核销:收款审核通过事务内逐张核销账单 */ - @Autowired - private IArBalanceWriteoffService balanceWriteoffService; - @Override @Transactional(rollbackFor = Exception.class) public List selectAccountList(Long customerId) @@ -157,7 +140,7 @@ public class CustomerMoneyServiceImpl implements ICustomerMoneyService { throw new ServiceException("收款金额必须大于0"); } - // 统一金额口径:入口即规范为两位小数,后续本位币、核销合计、余额分配均基于该值计算 + // 统一金额口径:入口即规范为两位小数,后续本位币金额与客户余额入账均基于该值计算 receipt.setAmount(receipt.getAmount().setScale(MONEY_SCALE, RoundingMode.HALF_UP)); if (!StringUtils.hasText(receipt.getReceiptType())) { @@ -256,24 +239,12 @@ public class CustomerMoneyServiceImpl implements ICustomerMoneyService BigDecimal baseAmount = receipt.getAmount().multiply(rate).setScale(MONEY_SCALE, RoundingMode.HALF_UP); receipt.setBaseAmount(baseAmount); - // 核销账单计划校验:当前账单均为人民币(CNY)账单,计划金额即本位币 CNY 金额, - // 上限为收款按汇率折算后的本位币金额 baseAmount;核销本身不增减客户余额。 - List plans = validateWriteoffPlans(receipt); - BigDecimal allocatedBase = plans.stream() - .map(ReceiptWriteoffPlan::getWriteoffAmount) - .reduce(BigDecimal.ZERO, BigDecimal::add); - // 全额分配=还款核销,部分分配=混合,不选账单=预充值/保持所选类型(本位币口径比较) - if (!plans.isEmpty()) - { - receipt.setReceiptType(allocatedBase.compareTo(baseAmount) == 0 - ? CustomerReceipt.TYPE_REPAY : CustomerReceipt.TYPE_MIXED); - } - receipt.setReceiptNo(generateNo("SK")); receipt.setStatus(CustomerReceipt.STATUS_PENDING); - // 核销金额即本位币 CNY,无需再乘汇率 - receipt.setAllocatedAmount(allocatedBase); - receipt.setUnallocatedAmount(baseAmount.subtract(allocatedBase)); + // 登记收款只记录资金,不接受账单核销计划;新收款先全部作为未分配金额入账。 + receipt.setAllocatedAmount(BigDecimal.ZERO.setScale(MONEY_SCALE, RoundingMode.UNNECESSARY)); + receipt.setUnallocatedAmount(baseAmount); + receipt.setWriteoffPlans(null); if (!StringUtils.hasText(receipt.getInvoiceStatus())) { receipt.setInvoiceStatus("NONE"); @@ -281,146 +252,11 @@ public class CustomerMoneyServiceImpl implements ICustomerMoneyService receipt.setVersion(0); customerMoneyMapper.insertReceipt(receipt); - // 核销计划落 PENDING,审核通过事务内再逐张执行 - String operator = receipt.getCreateBy(); - for (ReceiptWriteoffPlan plan : plans) - { - plan.setReceiptId(receipt.getId()); - plan.setStatus(ReceiptWriteoffPlan.STATUS_PENDING); - plan.setCreateBy(operator); - receiptWriteoffPlanMapper.insertPlan(plan); - } - // 收款附件:复用客户附件表,业务模块挂 customer_receipt,biz_id 关联收款单 saveReceiptAttachments(receipt); return 1; } - /** - * 校验登记收款携带的核销账单计划并规范化。 - * 口径(暂不支持多币种账单): - * 账单必须属于当前客户、账单币种为人民币 CNY、状态可核销(已确认/部分核销); - * 每张本次核销额(CNY)大于0且不超过账单未核销额; - * 合计不超过收款按汇率折算后的本位币金额 baseAmount(CNY)。 - * 审核时会再次锁账单强校验,防止登记后账单被别处抢先核销。 - */ - private List validateWriteoffPlans(CustomerReceipt receipt) - { - List raw = receipt.getWriteoffPlans(); - if (CollectionUtils.isEmpty(raw)) - { - return new ArrayList<>(); - } - BigDecimal baseAmount = receipt.getBaseAmount() != null - ? receipt.getBaseAmount().setScale(MONEY_SCALE, RoundingMode.HALF_UP) - : receipt.getAmount().multiply(receipt.getExchangeRate()).setScale(MONEY_SCALE, RoundingMode.HALF_UP); - List plans = new ArrayList<>(); - Set billIds = new HashSet<>(); - BigDecimal total = BigDecimal.ZERO; - for (ReceiptWriteoffPlan item : raw) - { - if (item == null || item.getArBillId() == null) - { - continue; - } - BigDecimal amount = item.getWriteoffAmount(); - if (amount == null) - { - throw new ServiceException("请填写每张账单的本次核销金额"); - } - amount = amount.setScale(MONEY_SCALE, RoundingMode.HALF_UP); - if (amount.compareTo(BigDecimal.ZERO) <= 0) - { - throw new ServiceException("核销金额必须大于0"); - } - if (!billIds.add(item.getArBillId())) - { - throw new ServiceException("同一账单不能重复选择,请合并为一条并填写合计金额"); - } - ArBill bill = arBillMapper.selectArBillById(item.getArBillId()); - if (bill == null) - { - throw new ServiceException("所选应收账单不存在,请刷新后重新选择"); - } - if (!receipt.getCustomerId().equals(bill.getCustomerId())) - { - throw new ServiceException("账单【" + bill.getBillNo() + "】不属于当前客户"); - } - // 现阶段仅支持人民币账单核销;外币账单暂不在此入口处理 - String billCurrency = StringUtils.hasText(bill.getCurrency()) - ? bill.getCurrency().trim().toUpperCase() : BASE_CURRENCY; - if (!BASE_CURRENCY.equals(billCurrency)) - { - throw new ServiceException("账单【" + bill.getBillNo() + "】币种为 " + billCurrency - + ",当前仅支持人民币(CNY)账单核销"); - } - ArBillStatus billStatus = ArBillStatus.of(bill.getStatus()); - if (billStatus == null || !billStatus.canWriteOff()) - { - throw new ServiceException("账单【" + bill.getBillNo() + "】当前状态不允许核销:" - + (billStatus == null ? bill.getStatus() : billStatus.getLabel())); - } - BigDecimal unwritten = bill.getUnwrittenAmount() == null - ? BigDecimal.ZERO : bill.getUnwrittenAmount(); - if (amount.compareTo(unwritten) > 0) - { - throw new ServiceException("账单【" + bill.getBillNo() + "】本次核销金额 " - + amount.toPlainString() + " 超过其未核销金额 " + unwritten.toPlainString()); - } - total = total.add(amount); - if (total.compareTo(baseAmount) > 0) - { - throw new ServiceException("核销金额合计 " + total.toPlainString() - + " CNY 超过本收款单折算本位币金额 " + baseAmount.toPlainString() + " CNY"); - } - - ReceiptWriteoffPlan plan = new ReceiptWriteoffPlan(); - plan.setArBillId(bill.getArBillId()); - plan.setBillNo(bill.getBillNo()); - plan.setCustomerId(bill.getCustomerId()); - plan.setCurrency(BASE_CURRENCY); - plan.setWriteoffAmount(amount); - plan.setRemark(StringUtils.hasText(item.getRemark()) ? item.getRemark().trim() : null); - plans.add(plan); - } - return plans; - } - - /** - * 收款审核通过后执行核销计划:同一事务内逐张锁账单核销, - * 任一账单已被别处抢先核销导致超额时,整笔审核回滚(含余额入账),不产生半截数据。 - */ - private void executeReceiptWriteoffPlans(CustomerReceipt receipt, String operator) - { - List plans = receiptWriteoffPlanMapper.selectByReceiptId(receipt.getId()); - if (CollectionUtils.isEmpty(plans)) - { - return; - } - Date writeoffDate = new Date(); - for (ReceiptWriteoffPlan plan : plans) - { - if (!ReceiptWriteoffPlan.STATUS_PENDING.equals(plan.getStatus())) - { - continue; - } - ArBalanceWriteoff cmd = new ArBalanceWriteoff(); - cmd.setArBillId(plan.getArBillId()); - cmd.setCustomerId(plan.getCustomerId()); - cmd.setReceiptId(receipt.getId()); - cmd.setWriteoffAmount(plan.getWriteoffAmount()); - cmd.setWriteoffDate(writeoffDate); - cmd.setRemark("收款单审核联动核销:" + receipt.getReceiptNo()); - cmd.setCreateBy(operator); - // writeoff 内部锁账单行、复核状态与未核销额,冲突时抛异常由外层事务统一回滚 - ArBalanceWriteoff done = balanceWriteoffService.writeoff(cmd); - if (receiptWriteoffPlanMapper.updateEffective(plan.getPlanId(), done.getWriteoffId(), operator) != 1) - { - throw new ServiceException("收款核销计划状态已变化,请刷新后重试"); - } - } - } - /** * 构造汇率表来源说明:汇率来源(中国银行/央行等)+ 命中路径(正向/反向取倒数/经CNY交叉)。 * resolveRate 返回对象的 remark 带 __RATE_PATH__ 前缀标记命中路径。 @@ -511,14 +347,16 @@ public class CustomerMoneyServiceImpl implements ICustomerMoneyService receipt.setConfirmedAt(new Date()); receipt.setConfirmedBy(userId); receipt.setUpdateBy(username); + receipt.setAllocatedAmount(BigDecimal.ZERO.setScale(MONEY_SCALE, RoundingMode.UNNECESSARY)); + receipt.setUnallocatedAmount(baseAmount.setScale(MONEY_SCALE, RoundingMode.HALF_UP)); + + // 旧版本待审核收款可能已有未执行计划;转为取消并恢复为未分配金额,不再联动核销。 + receiptWriteoffPlanMapper.cancelPendingByReceiptId(id, username); int receiptRows = customerMoneyMapper.confirmReceipt(receipt); if (receiptRows == 0) { throw new ServiceException("收款单状态已变更,请刷新后重试"); } - - // 3. 登记时选择的账单在同一事务内一并核销;任一账单核销失败则整笔审核回滚 - executeReceiptWriteoffPlans(receipt, username); return receiptRows; } @@ -537,7 +375,7 @@ public class CustomerMoneyServiceImpl implements ICustomerMoneyService } String operator = SecurityUtils.getUsername(); int rows = customerMoneyMapper.cancelReceipt(id, operator); - // 尚未执行的核销计划一并作废 + // 旧版本待确认计划一并作废 receiptWriteoffPlanMapper.cancelPendingByReceiptId(id, operator); return rows; } diff --git a/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/vo/CustomerReceiptExportVO.java b/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/vo/CustomerReceiptExportVO.java index 9644a66f..c1cbb348 100644 --- a/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/vo/CustomerReceiptExportVO.java +++ b/bms-back/bms-system/src/main/java/com/bms/customer/customermoney/vo/CustomerReceiptExportVO.java @@ -83,8 +83,8 @@ public class CustomerReceiptExportVO implements Serializable private static String receiptTypeLabel(String v) { if ("PREPAY".equals(v)) return "预充值"; - if ("REPAY".equals(v)) return "还款核销"; - if ("MIXED".equals(v)) return "混合"; + if ("REPAY".equals(v)) return "还款"; + if ("MIXED".equals(v)) return "-"; return v; } diff --git a/bms-back/bms-system/src/main/resources/mapper/customer/CustomerMoneyMapper.xml b/bms-back/bms-system/src/main/resources/mapper/customer/CustomerMoneyMapper.xml index 1e082cc1..79b3b37a 100644 --- a/bms-back/bms-system/src/main/resources/mapper/customer/CustomerMoneyMapper.xml +++ b/bms-back/bms-system/src/main/resources/mapper/customer/CustomerMoneyMapper.xml @@ -385,6 +385,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update ctr_customer_receipt set status = 'CONFIRMED', + allocated_amount = #{allocatedAmount}, + unallocated_amount = #{unallocatedAmount}, confirmed_at = #{confirmedAt}, confirmed_by = #{confirmedBy}, version = version + 1, @@ -395,13 +397,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update ctr_customer_receipt - set status = 'CANCELLED', - update_by = #{updateBy}, - update_time = now() + set status = 'CANCELLED', + allocated_amount = 0.00, + unallocated_amount = ifnull(base_amount, amount), + update_by = #{updateBy}, + update_time = now() where id = #{id} and status = 'PENDING' and del_flag = '0' - + update ctr_customer_receipt set allocated_amount = #{allocatedAmount}, diff --git a/bms-back/bms-system/src/main/resources/mapper/customer/ReceiptWriteoffPlanMapper.xml b/bms-back/bms-system/src/main/resources/mapper/customer/ReceiptWriteoffPlanMapper.xml index 35365f10..3b531654 100644 --- a/bms-back/bms-system/src/main/resources/mapper/customer/ReceiptWriteoffPlanMapper.xml +++ b/bms-back/bms-system/src/main/resources/mapper/customer/ReceiptWriteoffPlanMapper.xml @@ -39,32 +39,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" left join ar_bill b on b.ar_bill_id = p.ar_bill_id - - insert into ctr_receipt_writeoff_plan ( - receipt_id, ar_bill_id, bill_no, customer_id, currency, writeoff_amount, - status, writeoff_id, remark, create_by, create_time, del_flag - ) values ( - #{receiptId}, #{arBillId}, #{billNo}, #{customerId}, #{currency}, #{writeoffAmount}, - #{status}, #{writeoffId}, #{remark}, #{createBy}, sysdate(), '0' - ) - - - - update ctr_receipt_writeoff_plan - set status = 'EFFECTIVE', - writeoff_id = #{writeoffId}, - update_by = #{updateBy}, - update_time = sysdate() - where plan_id = #{planId} and status = 'PENDING' and del_flag = '0' - - update ctr_receipt_writeoff_plan set status = 'CANCELLED', diff --git a/bms-back/sql/bms_init.sql b/bms-back/sql/bms_init.sql index 09709539..8cc6d792 100644 --- a/bms-back/sql/bms_init.sql +++ b/bms-back/sql/bms_init.sql @@ -659,7 +659,7 @@ CREATE TABLE `ctr_customer_receipt` ( `receipt_no` varchar(64) NOT NULL COMMENT '收款单号', `customer_id` bigint(20) NOT NULL COMMENT '客户ID', `account_id` bigint(20) DEFAULT NULL COMMENT '客户账户ID', - `receipt_type` varchar(32) NOT NULL DEFAULT 'PREPAY' COMMENT '收款类型:PREPAY预充值/REPAY还款核销/MIXED混合', + `receipt_type` varchar(32) NOT NULL DEFAULT 'PREPAY' COMMENT '收款类型:PREPAY预充值/REPAY还款', `amount` decimal(18,2) NOT NULL COMMENT '收款金额', `allocated_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '已核销金额', `unallocated_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '待核销金额', diff --git a/bms-front/src/views/ar/receipt/index.vue b/bms-front/src/views/ar/receipt/index.vue index 14c31e24..29f5ac67 100644 --- a/bms-front/src/views/ar/receipt/index.vue +++ b/bms-front/src/views/ar/receipt/index.vue @@ -69,7 +69,7 @@ @@ -295,7 +295,6 @@ v-model="receiptDialog.form.customerId" placeholder="请选择客户(必选)" :page-size="1000" - @change="handleReceiptCustomerChange" /> @@ -382,51 +381,6 @@ - - -
    - 选择账单核销 - - 本次核销合计:{{ formatMoney(receiptWriteoffTotal) }} CNY - ,收款折算本位币:{{ formatMoney(receiptBaseCny) }} CNY - -
    - - - - - - - - - - - - - - -
    - 当前仅支持人民币(CNY)账单核销;所选账单在收款单审核通过后一并核销, - 核销合计不能超过收款金额按汇率折算的本位币金额({{ formatMoney(receiptBaseCny) }} CNY); - 核销不扣减客户余额,正常计入客户余额。 -
    -
    -
    - - - - 当前仅支持人民币(CNY)账单核销,以下为状态已确认/部分核销的 CNY 账单; - 已选 {{ billPicker.selected.length }} 张,合计未核销 - {{ formatMoney(billPickerSelectedTotal) }} CNY, - 本收款单折算可核销上限 {{ formatMoney(receiptBaseCny) }} CNY - - - - - - - - - - - - - - - - - - - - - - @@ -521,7 +432,7 @@ {{ viewDialog.data.customerName || '-' }} {{ formatDateTime(viewDialog.data.receivedAt) }} - {{ formatOption(receiptTypeOptions, viewDialog.data.receiptType) }} + {{ formatReceiptType(viewDialog.data.receiptType) }} {{ viewDialog.data.currency }} {{ formatMoney(viewDialog.data.amount) }} @@ -676,7 +587,7 @@ import axios from 'axios' import { saveAs } from 'file-saver' import { listReceipt, getReceipt, addReceipt, confirmReceipt, cancelReceipt, - listUnsettledBill, listReceiptWriteoff, receiptWriteoff, cancelReceiptWriteoff + listReceiptWriteoff, receiptWriteoff, cancelReceiptWriteoff } from '@/api/ar/receipt' import { listArBill } from '@/api/ar/bill' import { convertToBase } from '@/api/data/exchangeRate' @@ -695,8 +606,7 @@ const activeTab = ref('receipt') /* ================= 枚举与格式化 ================= */ const receiptTypeOptions = [ { value: 'PREPAY', label: '预充值' }, - { value: 'REPAY', label: '还款核销' }, - { value: 'MIXED', label: '混合' } + { value: 'REPAY', label: '还款' } ] const receiptStatusOptions = [ { value: 'PENDING', label: '待确认' }, @@ -724,8 +634,11 @@ function formatOption(options, value) { const opt = options.find(o => String(o.value) === String(value)) return opt ? opt.label : value } +function formatReceiptType(value) { + return value === 'MIXED' ? '-' : formatOption(receiptTypeOptions, value) +} function receiptTypeTag(v) { - return { PREPAY: '', REPAY: 'warning', MIXED: 'info' }[v] || 'info' + return { PREPAY: '', REPAY: 'warning' }[v] || 'info' } function receiptStatusTag(v) { return { PENDING: 'warning', CONFIRMED: 'success', CANCELLED: 'danger' }[v] || 'info' @@ -860,15 +773,11 @@ function resetReceiptQuery() { /** 审核通过 */ function handleConfirmReceipt(row) { - proxy.$modal.confirm(`是否确认审核通过收款单「${row.receiptNo}」?审核通过后金额计入客户余额,登记时选择的账单将一并核销。`).then(() => { + proxy.$modal.confirm(`是否确认审核通过收款单「${row.receiptNo}」?`).then(() => { return confirmReceipt(row.id) }).then(() => { - proxy.$modal.msgSuccess('审核通过,余额与账单核销已更新') + proxy.$modal.msgSuccess('审核通过,收款已计入客户余额') getReceiptList() - if (writeoffLoaded) { - getBillList() - getWriteoffList() - } }).catch(() => {}) } @@ -908,8 +817,7 @@ function resetReceiptForm() { bankAccountNo: '', bankTransactionNo: '', remark: '', - attachmentList: [], - writeoffPlans: [] + attachmentList: [] } proxy.resetForm('receiptFormRef') } @@ -919,14 +827,6 @@ function handleAddReceipt() { receiptDialog.visible = true } -/** 切换客户:核销账单归属于客户,已选账单需清空重选 */ -function handleReceiptCustomerChange() { - const plans = receiptDialog.form.writeoffPlans || [] - if (plans.length) { - plans.splice(0, plans.length) - } -} - const rateEdited = ref(false) const rateSourceInfo = ref({ source: '', ratePath: '' }) @@ -978,22 +878,6 @@ watch(() => receiptDialog.form.receivedAt, () => { } }) -/* ============ 选择核销账单 ============ */ -const billPickerTableRef = ref(null) -const billPicker = reactive({ visible: false, loading: false, rows: [], selected: [] }) - -const receiptBaseCny = computed(() => { - const amt = Number(receiptDialog.form.amount) || 0 - const rate = Number(receiptDialog.form.exchangeRate) || 0 - return Math.round(amt * rate * 100) / 100 -}) -const receiptWriteoffTotal = computed(() => { - return (receiptDialog.form.writeoffPlans || []).reduce((s, r) => s + (Number(r.writeoffAmount) || 0), 0) -}) -const billPickerSelectedTotal = computed(() => { - return billPicker.selected.reduce((s, r) => s + (Number(r.unwrittenAmount) || 0), 0) -}) - const RECEIPT_PLAN_STATUS_MAP = { PENDING: { label: '待核销', type: 'warning' }, EFFECTIVE: { label: '已核销', type: 'success' }, @@ -1007,84 +891,6 @@ function receiptPlanStatusTag(s) { return RECEIPT_PLAN_STATUS_MAP[s]?.type || 'info' } -function openBillPicker() { - const customerId = receiptDialog.form.customerId - if (!customerId) { - proxy.$modal.msgError('请先选择客户') - return - } - billPicker.visible = true - billPicker.loading = true - billPicker.rows = [] - billPicker.selected = [] - listUnsettledBill(customerId).then(res => { - billPicker.rows = (res.data || []).filter(r => (r.currency || 'CNY') === 'CNY') - nextTick(() => { - billPickerTableRef.value?.clearSelection() - const chosen = receiptDialog.form.writeoffPlans || [] - billPicker.rows.forEach(r => { - if (chosen.some(p => p.arBillId === r.arBillId)) { - billPickerTableRef.value?.toggleRowSelection(r, true) - } - }) - }) - }).finally(() => { - billPicker.loading = false - }) -} - -function onPickerSelectionChange(rows) { - billPicker.selected = rows || [] -} - -function confirmBillPicker() { - const oldMap = new Map((receiptDialog.form.writeoffPlans || []).map(p => [p.arBillId, p])) - receiptDialog.form.writeoffPlans = billPicker.selected.map(r => { - const existed = oldMap.get(r.arBillId) - const unwritten = Number(r.unwrittenAmount) || 0 - const usedByOthers = (receiptDialog.form.writeoffPlans || []) - .filter(p => p.arBillId !== r.arBillId) - .reduce((s, p) => s + (Number(p.writeoffAmount) || 0), 0) - const remainCny = Math.max(receiptBaseCny.value - usedByOthers, 0) - return { - arBillId: r.arBillId, - billNo: r.billNo, - billName: r.billName, - currency: 'CNY', - unwrittenAmount: unwritten, - writeoffAmount: existed ? Number(existed.writeoffAmount) : Math.round(Math.min(unwritten, remainCny) * 100) / 100 - } - }) - billPicker.visible = false -} - -function removeReceiptBill(index) { - receiptDialog.form.writeoffPlans.splice(index, 1) -} - -function validateReceiptWriteoffPlans() { - const cap = receiptBaseCny.value - const list = receiptDialog.form.writeoffPlans || [] - let total = 0 - for (const p of list) { - const amt = Number(p.writeoffAmount) - if (!amt || amt <= 0) { - proxy.$modal.msgError(`账单【${p.billNo}】本次核销金额必须大于0`) - return false - } - if (amt > Number(p.unwrittenAmount)) { - proxy.$modal.msgError(`账单【${p.billNo}】核销金额超过其未核销金额`) - return false - } - total += amt - } - if (Math.round(total * 100) > Math.round(cap * 100)) { - proxy.$modal.msgError(`核销金额合计 ${total.toFixed(2)} CNY 超过收款折算本位币金额 ${cap.toFixed(2)} CNY`) - return false - } - return true -} - function submitReceipt() { receiptFormRef.value.validate(valid => { if (!valid) return @@ -1094,7 +900,6 @@ function submitReceipt() { proxy.$modal.msgError(`请录入 ${cur} 对 CNY 的汇率(汇率表未配置时可手工填写)`) return } - if (!validateReceiptWriteoffPlans()) return submitLoading.value = true addReceipt(receiptDialog.form).then(() => { proxy.$modal.msgSuccess('登记成功,等待审核') @@ -1393,12 +1198,6 @@ getReceiptList() font-size: 12px; line-height: 1.6; } -.receipt-wo-toolbar { - display: flex; - align-items: center; - gap: 12px; - margin-bottom: 8px; -} .attach-title { font-weight: 600; margin: 12px 0 8px; diff --git a/bms-front/src/views/customersuppliermanagement/customerinfo/customermoney/index.vue b/bms-front/src/views/customersuppliermanagement/customerinfo/customermoney/index.vue index ddf5ca74..613586d6 100644 --- a/bms-front/src/views/customersuppliermanagement/customerinfo/customermoney/index.vue +++ b/bms-front/src/views/customersuppliermanagement/customerinfo/customermoney/index.vue @@ -127,7 +127,7 @@ @@ -679,54 +679,6 @@ - - -
    - 选择账单核销 - - 本次核销合计:{{ formatMoney(receiptWriteoffTotal) }} CNY - ,收款折算本位币:{{ formatMoney(receiptBaseCny) }} CNY - - - - -
    - - - - - - - - - - - - - - -
    - 当前仅支持人民币(CNY)账单核销,账单行金额均按 CNY 填写; - 所选账单在收款单审核通过后一并核销,核销合计不能超过收款金额按汇率折算的本位币金额 - ({{ formatMoney(receiptBaseCny) }} CNY);核销不扣减客户余额,正常计入客户余额。 -
    -
    -
    {{ formatDateTime(viewDialog.data.receivedAt) }} - {{ formatOption(receiptTypeOptions, viewDialog.data.receiptType) }} + {{ formatReceiptType(viewDialog.data.receiptType) }} {{ viewDialog.data.currency }} {{ formatMoney(viewDialog.data.amount) }} @@ -997,49 +949,6 @@ - - - - 当前仅支持人民币(CNY)账单核销,以下为状态已确认/部分核销的 CNY 账单; - 已选 {{ billPicker.selected.length }} 张,合计未核销 - {{ formatMoney(billPickerSelectedTotal) }} CNY, - 本收款单折算可核销上限 {{ formatMoney(receiptBaseCny) }} CNY - - - - - - - - - - - - - - - - - - - - - - @@ -1142,8 +1051,7 @@ const customer = ref({}) /* ================= 枚举 ================= */ const receiptTypeOptions = [ { value: 'PREPAY', label: '预充值' }, - { value: 'REPAY', label: '还款核销' }, - { value: 'MIXED', label: '混合' } + { value: 'REPAY', label: '还款' } ] const receiptStatusOptions = [ { value: 'PENDING', label: '待确认' }, @@ -1184,8 +1092,11 @@ function formatOption(options, value) { const opt = options.find(o => String(o.value) === String(value)) return opt ? opt.label : value } +function formatReceiptType(value) { + return value === 'MIXED' ? '-' : formatOption(receiptTypeOptions, value) +} function receiptTypeTag(v) { - return { PREPAY: '', REPAY: 'warning', MIXED: 'info' }[v] || 'info' + return { PREPAY: '', REPAY: 'warning' }[v] || 'info' } function receiptStatusTag(v) { return { PENDING: 'warning', CONFIRMED: 'success', CANCELLED: 'danger' }[v] || 'info' @@ -1517,10 +1428,10 @@ function handleExportCreditFlow() { /** 审核通过 */ function handleConfirmReceipt(row) { - proxy.$modal.confirm(`是否确认审核通过收款单「${row.receiptNo}」?审核通过后金额计入客户余额,登记时选择的账单将一并核销。`).then(() => { + proxy.$modal.confirm(`是否确认审核通过收款单「${row.receiptNo}」?`).then(() => { return confirmReceipt(row.id) }).then(() => { - proxy.$modal.msgSuccess("审核通过,余额与账单核销已更新") + proxy.$modal.msgSuccess("审核通过,收款已计入客户余额") getReceiptList() loadAccounts() loadBillWriteoffData() @@ -1566,8 +1477,7 @@ function resetReceiptForm() { bankAccountNo: '', bankTransactionNo: '', remark: '', - attachmentList: [], - writeoffPlans: [] + attachmentList: [] } proxy.resetForm('receiptFormRef') } @@ -1609,7 +1519,7 @@ function fetchDefaultRate() { }) } -/** 切换币种:重置手工标记并重新取默认汇率;核销账单固定为CNY,只需按新汇率重算可核销上限,不清空已选 */ +/** 切换币种:重置手工标记并重新取默认汇率 */ function handleCurrencyChange() { rateEdited.value = false rateSourceInfo.value = { source: '', ratePath: '' } @@ -1635,35 +1545,6 @@ watch(() => receiptDialog.form.receivedAt, () => { } }) -/* ============ 登记收款-选择核销账单 ============ */ -const billPickerTableRef = ref(null) -const billPicker = reactive({ - visible: false, - loading: false, - rows: [], - selected: [] -}) - -/** 收款金额按汇率折算的本位币金额(CNY),即核销合计上限 */ -const receiptBaseCny = computed(() => { - const amt = Number(receiptDialog.form.amount) || 0 - const rate = Number(receiptDialog.form.exchangeRate) || 0 - return Math.round(amt * rate * 100) / 100 -}) -/** 已分配合计(账单均为CNY,此值即 CNY) */ -const receiptWriteoffTotal = computed(() => { - const list = receiptDialog.form.writeoffPlans || [] - return list.reduce((s, r) => s + (Number(r.writeoffAmount) || 0), 0) -}) -/** 核销后剩余入账金额(折算CNY - 已分配CNY) */ -const receiptWriteoffRemain = computed(() => { - return Math.round((receiptBaseCny.value - receiptWriteoffTotal.value) * 100) / 100 -}) -/** 选择器中勾选账单的未核销额合计(仅提示) */ -const billPickerSelectedTotal = computed(() => { - return billPicker.selected.reduce((s, r) => s + (Number(r.unwrittenAmount) || 0), 0) -}) - const RECEIPT_PLAN_STATUS_MAP = { PENDING: { label: '待核销', type: 'warning' }, EFFECTIVE: { label: '已核销', type: 'success' }, @@ -1677,88 +1558,6 @@ function receiptPlanStatusTag(s) { return RECEIPT_PLAN_STATUS_MAP[s]?.type || 'info' } -/** 打开账单选择器:只列与收款同币种的未核销账单,并回显已选 */ -function openBillPicker() { - const customerId = route.query.customerId - if (!customerId) { - proxy.$modal.msgError('缺少客户信息,请重新进入页面') - return - } - billPicker.visible = true - billPicker.loading = true - billPicker.rows = [] - billPicker.selected = [] - listUnsettledBill(customerId).then(res => { - // 现阶段只核销人民币账单,与收款币种无关;核销上限为收款折算 CNY - billPicker.rows = (res.data || []).filter(r => (r.currency || 'CNY') === 'CNY') - nextTick(() => { - billPickerTableRef.value?.clearSelection() - const chosen = receiptDialog.form.writeoffPlans || [] - billPicker.rows.forEach(r => { - if (chosen.some(p => p.arBillId === r.arBillId)) { - billPickerTableRef.value?.toggleRowSelection(r, true) - } - }) - }) - }).finally(() => { - billPicker.loading = false - }) -} - -function onPickerSelectionChange(rows) { - billPicker.selected = rows || [] -} - -/** 确认选择:新增行默认核销额=min(账单未核销额CNY, 收款折算CNY剩余可用),保留已填金额 */ -function confirmBillPicker() { - const oldMap = new Map((receiptDialog.form.writeoffPlans || []).map(p => [p.arBillId, p])) - receiptDialog.form.writeoffPlans = billPicker.selected.map(r => { - const existed = oldMap.get(r.arBillId) - const unwritten = Number(r.unwrittenAmount) || 0 - const usedByOthers = receiptDialog.form.writeoffPlans - .filter(p => p.arBillId !== r.arBillId) - .reduce((s, p) => s + (Number(p.writeoffAmount) || 0), 0) - const remainCny = Math.max(receiptBaseCny.value - usedByOthers, 0) - return { - arBillId: r.arBillId, - billNo: r.billNo, - billName: r.billName, - currency: 'CNY', - unwrittenAmount: unwritten, - writeoffAmount: existed ? Number(existed.writeoffAmount) : Math.round(Math.min(unwritten, remainCny) * 100) / 100 - } - }) - billPicker.visible = false -} - -function removeReceiptBill(index) { - receiptDialog.form.writeoffPlans.splice(index, 1) -} - -/** 提交前校验核销账单(金额口径均为 CNY) */ -function validateReceiptWriteoffPlans() { - const cap = receiptBaseCny.value - const list = receiptDialog.form.writeoffPlans || [] - let total = 0 - for (const p of list) { - const amt = Number(p.writeoffAmount) - if (!amt || amt <= 0) { - proxy.$modal.msgError(`账单【${p.billNo}】本次核销金额必须大于0`) - return false - } - if (amt > Number(p.unwrittenAmount)) { - proxy.$modal.msgError(`账单【${p.billNo}】核销金额超过其未核销金额`) - return false - } - total += amt - } - if (Math.round(total * 100) > Math.round(cap * 100)) { - proxy.$modal.msgError(`核销金额合计 ${total.toFixed(2)} CNY 超过收款折算本位币金额 ${cap.toFixed(2)} CNY`) - return false - } - return true -} - function submitReceipt() { receiptFormRef.value.validate(valid => { if (!valid) return @@ -1768,7 +1567,6 @@ function submitReceipt() { proxy.$modal.msgError(`请录入 ${cur} 对 CNY 的汇率(汇率表未配置时可手工填写)`) return } - if (!validateReceiptWriteoffPlans()) return submitLoading.value = true addReceipt(receiptDialog.form).then(() => { proxy.$modal.msgSuccess("登记成功,等待审核") @@ -2487,17 +2285,6 @@ watch(() => route.query.customerId, (newId, oldId) => { .writeoff-summary { margin-bottom: 12px; } -.receipt-wo-toolbar { - display: flex; - align-items: center; - gap: 14px; - flex-wrap: wrap; - margin-bottom: 8px; -} -.receipt-wo-summary { - font-size: 13px; - color: #606266; -} .wo-summary { display: flex; align-items: center; From d7f49cef58f1b96e43efe247e931cb6ae71f6d06 Mon Sep 17 00:00:00 2001 From: caojia <1301869380@qq.com> Date: Wed, 28 Oct 2026 20:30:28 +0800 Subject: [PATCH 2/3] =?UTF-8?q?:lipstick:=20=E4=BC=98=E5=8C=96=E8=B4=A6?= =?UTF-8?q?=E5=8D=95=E6=A0=B8=E9=94=80=E6=96=87=E6=A1=88=E5=92=8C=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bms-front/src/views/ar/bill/index.vue | 2 +- .../customerinfo/customermoney/index.vue | 30 +++---------------- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/bms-front/src/views/ar/bill/index.vue b/bms-front/src/views/ar/bill/index.vue index e9462e3b..39399dc0 100644 --- a/bms-front/src/views/ar/bill/index.vue +++ b/bms-front/src/views/ar/bill/index.vue @@ -47,7 +47,7 @@ 确认 作废 导出明细 - 去核销 + 核销 反核销 diff --git a/bms-front/src/views/customersuppliermanagement/customerinfo/customermoney/index.vue b/bms-front/src/views/customersuppliermanagement/customerinfo/customermoney/index.vue index 613586d6..936ee621 100644 --- a/bms-front/src/views/customersuppliermanagement/customerinfo/customermoney/index.vue +++ b/bms-front/src/views/customersuppliermanagement/customerinfo/customermoney/index.vue @@ -949,17 +949,14 @@ - - + + {{ woDialog.bill.billNo }} {{ woDialog.bill.billName || '-' }} CNY {{ formatMoney(woDialog.bill.unwrittenAmount) }} - - CNY {{ formatMoney(currentAccount.balance) }} - @@ -1904,10 +1901,9 @@ function loadBillWriteoffData() { /* ---- 核销弹窗 ---- */ const woSubmitLoading = ref(false) -const woDialog = reactive({ visible: false, bill: null, form: {}, accountLoading: false }) -let writeoffAccountRequestSerial = 0 +const woDialog = reactive({ visible: false, bill: null, form: {} }) -async function openWriteoffDialog(row) { +function openWriteoffDialog(row) { const customerId = Number(route.query.customerId) if (!customerId) { proxy.$modal.msgError('缺少客户ID,无法发起核销') @@ -1925,27 +1921,9 @@ async function openWriteoffDialog(row) { remark: '' } woDialog.visible = true - - // 仍刷新账户余额供展示,但不再限制核销金额 - const requestSerial = ++writeoffAccountRequestSerial - woDialog.accountLoading = true - try { - const res = await listAccount(customerId) - if (requestSerial !== writeoffAccountRequestSerial) return - accountList.value = res.data || [] - } catch (e) { - if (requestSerial !== writeoffAccountRequestSerial) return - proxy.$modal.msgError('账户余额刷新失败,请稍后重试') - } finally { - if (requestSerial === writeoffAccountRequestSerial) woDialog.accountLoading = false - } } function submitWriteoff() { - if (woDialog.accountLoading) { - proxy.$modal.msgWarning('正在刷新账户余额,请稍候') - return - } const bill = woDialog.bill const rawAmount = typeof woDialog.form.writeoffAmount === 'string' ? woDialog.form.writeoffAmount.trim() From 1688cddac772c98122346e1ab1026e6533ef0902 Mon Sep 17 00:00:00 2001 From: caojia <1301869380@qq.com> Date: Wed, 28 Oct 2026 20:47:42 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E6=B3=A8=E9=87=8A=E4=B8=8D=E5=BF=85?= =?UTF-8?q?=E8=A6=81=E7=9A=84=E4=B8=9C=E8=A5=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customerinfo/customeredit/index.vue | 6 +++--- .../supplierinfo/supplieredit/index.vue | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bms-front/src/views/customersuppliermanagement/customerinfo/customeredit/index.vue b/bms-front/src/views/customersuppliermanagement/customerinfo/customeredit/index.vue index 929af21c..9082a236 100644 --- a/bms-front/src/views/customersuppliermanagement/customerinfo/customeredit/index.vue +++ b/bms-front/src/views/customersuppliermanagement/customerinfo/customeredit/index.vue @@ -178,7 +178,7 @@
    - 绑定结果以产品代码逗号串存入客户主表 product_codes,产品代码在新旧库间稳定,用于产品对接映射 +
    @@ -216,7 +216,7 @@ {{ boundPriceSets.length ? '更换套餐' : '绑定套餐' }} - 绑定后写入客户套餐关系表 prc_customer_price_set,一个客户仅可绑定一个价格套餐,仅「生效中」的套餐可绑定 + 一个客户仅可绑定一个价格套餐,仅「生效中」的套餐可绑定 @@ -258,7 +258,7 @@
    新增公司主体 - 点击「绑定客户」后,主表的统一社会信用代码会自动同步为该公司的信用代码 +
    diff --git a/bms-front/src/views/customersuppliermanagement/supplierinfo/supplieredit/index.vue b/bms-front/src/views/customersuppliermanagement/supplierinfo/supplieredit/index.vue index d0bf61cd..016ad13b 100644 --- a/bms-front/src/views/customersuppliermanagement/supplierinfo/supplieredit/index.vue +++ b/bms-front/src/views/customersuppliermanagement/supplierinfo/supplieredit/index.vue @@ -186,7 +186,7 @@
    - 绑定结果以渠道编码逗号串存入供应商主表 channel_ids,渠道来源于老系统服务渠道镜像(每日自动同步) +
    @@ -217,7 +217,7 @@
    新增公司主体 - 点击「绑定供应商」后,主表的统一社会信用代码会自动同步为该公司的信用代码 +