diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/IPrcOrderBillService.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/IPrcOrderBillService.java index 1678f4f2..18eb99e4 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/IPrcOrderBillService.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/IPrcOrderBillService.java @@ -50,14 +50,5 @@ public interface IPrcOrderBillService */ void clearCreditArrearsByAmount(String customerCode, BigDecimal amount); - /** - * 异步执行体:实际清欠并写 ES日志(供异步 Runner 调用)。 - * - * @return 已更新为 NORMAL 的订单数 - */ - int processClearCreditArrearsByAmount(String customerCode, BigDecimal amount); - - /** 异步清欠失败时写 ES 摘要日志 */ - void logClearCreditArrearsFail(String customerCode, BigDecimal amount, String errorMessage); } diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/impl/PrcOrderBillServiceImpl.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/impl/PrcOrderBillServiceImpl.java index 74a1fa42..a67119d4 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/impl/PrcOrderBillServiceImpl.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/impl/PrcOrderBillServiceImpl.java @@ -530,113 +530,6 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService } } - /** - * 异步执行:按下单时间升序 FIFO 清欠,逐单与摘要日志写入 ES。 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int processClearCreditArrearsByAmount(String customerCode, BigDecimal amount) - { - String code = StringUtils.trim(customerCode); - if (StringUtils.isEmpty(code)) - { - throw new ServiceException("客户代码不能为空"); - } - if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) - { - throw new ServiceException("入账金额必须大于0"); - } - BigDecimal remaining = amount; - List bills = orderBillMapper.selectArrearsByCustomerCode(code, - BillCreditArrearsStatus.ARREARS.getCode()); - if (bills == null || bills.isEmpty()) - { - saveArrearsClearSummaryEsLog(code, amount, 0, remaining, true, "no arrears orders"); - return 0; - } - String normal = BillCreditArrearsStatus.NORMAL.getCode(); - int updated = 0; - for (PrcOrderBill bill : bills) - { - BigDecimal orderAmt = nz(bill.getIncomeTotal()); - // 当前订单额度大于剩余金额:停止更新 - if (orderAmt.compareTo(remaining) > 0) - { - break; - } - orderBillMapper.updateCreditArrearsStatus(bill.getBillId(), normal, "receipt"); - remaining = remaining.subtract(orderAmt); - updated++; - saveArrearsClearOrderEsLog(bill, amount, orderAmt, remaining, true, null); - if (remaining.compareTo(BigDecimal.ZERO) <= 0) - { - break; - } - } - saveArrearsClearSummaryEsLog(code, amount, updated, remaining, true, null); - return updated; - } - - @Override - public void logClearCreditArrearsFail(String customerCode, BigDecimal amount, String errorMessage) - { - saveArrearsClearSummaryEsLog(StringUtils.trim(customerCode), amount, 0, amount, false, errorMessage); - } - - private void saveArrearsClearSummaryEsLog(String customerCode, BigDecimal amount, int updated, - BigDecimal remaining, boolean success, String note) - { - if (billSearchStore == null || StringUtils.isEmpty(customerCode)) - { - return; - } - JSONObject req = new JSONObject(); - req.put("action", "CLEAR_ARREARS"); - req.put("scope", "SUMMARY"); - req.put("customerCode", customerCode); - req.put("amount", amount); - JSONObject resp = new JSONObject(); - resp.put("success", Boolean.valueOf(success)); - resp.put("updatedCount", Integer.valueOf(updated)); - resp.put("remainingAmount", remaining); - if (StringUtils.isNotEmpty(note)) - { - resp.put("msg", note); - } - String status = success ? EsBizLogSupport.STATUS_SUCCESS : EsBizLogSupport.STATUS_FAIL; - String err = success ? null : EsBizLogSupport.cut(note); - billSearchStore.save(EsLogType.ARREARS, customerCode, req.toJSONString(), resp.toJSONString(), status, err); - } - - private void saveArrearsClearOrderEsLog(PrcOrderBill bill, BigDecimal batchAmount, BigDecimal orderAmt, - BigDecimal remaining, boolean success, String errorMessage) - { - if (billSearchStore == null || bill == null || StringUtils.isEmpty(bill.getOrderNo())) - { - return; - } - JSONObject req = new JSONObject(); - req.put("action", "CLEAR_ARREARS"); - req.put("scope", "ORDER"); - req.put("orderNo", bill.getOrderNo()); - req.put("billId", bill.getBillId()); - req.put("customerCode", bill.getCustomerCode()); - req.put("batchAmount", batchAmount); - req.put("orderIncomeTotal", orderAmt); - req.put("fromStatus", BillCreditArrearsStatus.ARREARS.getCode()); - req.put("toStatus", BillCreditArrearsStatus.NORMAL.getCode()); - JSONObject resp = new JSONObject(); - resp.put("success", Boolean.valueOf(success)); - resp.put("remainingAmount", remaining); - if (StringUtils.isNotEmpty(errorMessage)) - { - resp.put("msg", errorMessage); - } - String status = success ? EsBizLogSupport.STATUS_SUCCESS : EsBizLogSupport.STATUS_FAIL; - String err = success ? null : EsBizLogSupport.cut(errorMessage); - billSearchStore.save(EsLogType.ARREARS, bill.getOrderNo(), req.toJSONString(), resp.toJSONString(), status, err); - } - private TmsOrderBillMatchType resolveTmsMatchType(String identifier, PrcOrderBill bill) { if (identifier.equalsIgnoreCase(StringUtils.trim(bill.getOrderNo()))) diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/task/PrcCreditArrearsClearAsyncRunner.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/task/PrcCreditArrearsClearAsyncRunner.java index a57a9bfb..cf9c7d09 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/task/PrcCreditArrearsClearAsyncRunner.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/task/PrcCreditArrearsClearAsyncRunner.java @@ -1,16 +1,25 @@ package com.ruoyi.price.task; import java.math.BigDecimal; +import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import com.alibaba.fastjson2.JSONObject; import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.price.service.IPrcOrderBillService; +import com.ruoyi.price.domain.PrcOrderBill; +import com.ruoyi.price.enums.BillCreditArrearsStatus; +import com.ruoyi.price.mapper.PrcOrderBillMapper; +import com.ruoyi.price.search.EsBizLogSupport; +import com.ruoyi.price.search.EsLogType; +import com.ruoyi.price.search.IBillSearchStore; /** * 异步清除订单额度欠费状态(余额充值等审核入账后)。 + * 自行注入 Mapper / ES,避免与 IPrcOrderBillService 循环依赖。 */ @Component public class PrcCreditArrearsClearAsyncRunner @@ -18,27 +27,122 @@ public class PrcCreditArrearsClearAsyncRunner private static final Logger log = LoggerFactory.getLogger(PrcCreditArrearsClearAsyncRunner.class); @Autowired - private IPrcOrderBillService orderBillService; + private PrcOrderBillMapper orderBillMapper; + + @Autowired(required = false) + private IBillSearchStore billSearchStore; @Async("threadPoolTaskExecutor") + @Transactional(rollbackFor = Exception.class) public void run(String customerCode, BigDecimal amount) { + String code = StringUtils.trim(customerCode); try { - int updated = orderBillService.processClearCreditArrearsByAmount(customerCode, amount); + if (StringUtils.isEmpty(code) || amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) + { + return; + } + BigDecimal remaining = amount; + List bills = orderBillMapper.selectArrearsByCustomerCode(code, + BillCreditArrearsStatus.ARREARS.getCode()); + if (bills == null || bills.isEmpty()) + { + saveSummaryEsLog(code, amount, 0, remaining, true, "no arrears orders"); + return; + } + String normal = BillCreditArrearsStatus.NORMAL.getCode(); + int updated = 0; + for (PrcOrderBill bill : bills) + { + BigDecimal orderAmt = nz(bill.getIncomeTotal()); + if (orderAmt.compareTo(remaining) > 0) + { + break; + } + orderBillMapper.updateCreditArrearsStatus(bill.getBillId(), normal, "receipt"); + remaining = remaining.subtract(orderAmt); + updated++; + saveOrderEsLog(bill, amount, orderAmt, remaining, true, null); + if (remaining.compareTo(BigDecimal.ZERO) <= 0) + { + break; + } + } + saveSummaryEsLog(code, amount, updated, remaining, true, null); log.info("async clear credit arrears done, customerCode={}, amount={}, updated={}", - customerCode, amount, Integer.valueOf(updated)); + code, amount, Integer.valueOf(updated)); } catch (Exception e) { log.error("async clear credit arrears failed, customerCode={}, amount={}", - customerCode, amount, e); + code, amount, e); String msg = e.getMessage(); if (StringUtils.isEmpty(msg)) { msg = e.getClass().getSimpleName(); } - orderBillService.logClearCreditArrearsFail(customerCode, amount, msg); + saveSummaryEsLog(code, amount, 0, amount, false, msg); + throw e; } } + + private void saveSummaryEsLog(String customerCode, BigDecimal amount, int updated, + BigDecimal remaining, boolean success, String note) + { + if (billSearchStore == null || StringUtils.isEmpty(customerCode)) + { + return; + } + JSONObject req = new JSONObject(); + req.put("action", "CLEAR_ARREARS"); + req.put("scope", "SUMMARY"); + req.put("customerCode", customerCode); + req.put("amount", amount); + JSONObject resp = new JSONObject(); + resp.put("success", Boolean.valueOf(success)); + resp.put("updatedCount", Integer.valueOf(updated)); + resp.put("remainingAmount", remaining); + if (StringUtils.isNotEmpty(note)) + { + resp.put("msg", note); + } + String status = success ? EsBizLogSupport.STATUS_SUCCESS : EsBizLogSupport.STATUS_FAIL; + String err = success ? null : EsBizLogSupport.cut(note); + billSearchStore.save(EsLogType.ARREARS, customerCode, req.toJSONString(), resp.toJSONString(), status, err); + } + + private void saveOrderEsLog(PrcOrderBill bill, BigDecimal batchAmount, BigDecimal orderAmt, + BigDecimal remaining, boolean success, String errorMessage) + { + if (billSearchStore == null || bill == null || StringUtils.isEmpty(bill.getOrderNo())) + { + return; + } + JSONObject req = new JSONObject(); + req.put("action", "CLEAR_ARREARS"); + req.put("scope", "ORDER"); + req.put("orderNo", bill.getOrderNo()); + req.put("billId", bill.getBillId()); + req.put("customerCode", bill.getCustomerCode()); + req.put("batchAmount", batchAmount); + req.put("orderIncomeTotal", orderAmt); + req.put("fromStatus", BillCreditArrearsStatus.ARREARS.getCode()); + req.put("toStatus", BillCreditArrearsStatus.NORMAL.getCode()); + JSONObject resp = new JSONObject(); + resp.put("success", Boolean.valueOf(success)); + resp.put("remainingAmount", remaining); + if (StringUtils.isNotEmpty(errorMessage)) + { + resp.put("msg", errorMessage); + } + String status = success ? EsBizLogSupport.STATUS_SUCCESS : EsBizLogSupport.STATUS_FAIL; + String err = success ? null : EsBizLogSupport.cut(errorMessage); + billSearchStore.save(EsLogType.ARREARS, bill.getOrderNo(), req.toJSONString(), resp.toJSONString(), status, err); + } + + private static BigDecimal nz(BigDecimal v) + { + return v == null ? BigDecimal.ZERO : v; + } }