From 36837f94bf495ba13b3c53c9639d4d21dd8abf2c Mon Sep 17 00:00:00 2001 From: wuweihua <88888888> Date: Wed, 21 Oct 2026 10:45:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E8=AE=B0=E5=BD=95=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/PrcOrderBillServiceImpl.java | 3 +- .../PrcOrderBillLocalRebillAsyncRunner.java | 98 ++++++++++++++++++- .../components/OrderSourceSyncLogDrawer.vue | 7 +- 3 files changed, 102 insertions(+), 6 deletions(-) diff --git a/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcOrderBillServiceImpl.java b/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcOrderBillServiceImpl.java index 9685c0e1..ec5cc24c 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcOrderBillServiceImpl.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcOrderBillServiceImpl.java @@ -828,7 +828,8 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService String taskId = IdUtils.fastSimpleUUID(); localRebillAsyncRunner.put(taskId, BatchAddIncomeBillFeeTask.STATUS_PENDING, 0, "queued", null, billIds.size(), 0, 0); - localRebillAsyncRunner.run(taskId, billIds); + // One ES op-log per batch on finish (LOCAL_REBILL_DONE); fail orders go into detail.failDetails. + localRebillAsyncRunner.run(taskId, billIds, request); return taskId; } diff --git a/bms-back/bms-system/src/main/java/com/bms/price/task/PrcOrderBillLocalRebillAsyncRunner.java b/bms-back/bms-system/src/main/java/com/bms/price/task/PrcOrderBillLocalRebillAsyncRunner.java index 238608c3..0954bce3 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/task/PrcOrderBillLocalRebillAsyncRunner.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/task/PrcOrderBillLocalRebillAsyncRunner.java @@ -1,7 +1,10 @@ package com.bms.price.task; import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -20,6 +23,12 @@ import com.bms.common.core.redis.RedisCache; import com.bms.common.utils.StringUtils; import com.bms.price.config.BillingProperties; import com.bms.price.domain.BatchAddIncomeBillFeeTask; +import com.bms.price.domain.PrcOrderBill; +import com.bms.price.domain.vo.LocalRebillRequest; +import com.bms.price.mapper.PrcOrderBillMapper; +import com.bms.price.search.EsBizLogSupport; +import com.bms.price.search.IBillSearchStore; +import com.bms.price.search.TabOrderSyncEsLog; import com.bms.price.service.IPrcOrderBillService; /** @@ -37,6 +46,7 @@ public class PrcOrderBillLocalRebillAsyncRunner public static final int PAGE_SIZE = 500; public static final int MIN_THREADS = 2; public static final int MAX_THREADS = 16; + private static final int FAIL_DETAIL_MAX = 200; @Autowired @Lazy @@ -48,13 +58,26 @@ public class PrcOrderBillLocalRebillAsyncRunner @Autowired private BillingProperties billingProperties; + @Autowired + private IBillSearchStore billSearchStore; + + @Autowired + private PrcOrderBillMapper orderBillMapper; + @Async("threadPoolTaskExecutor") public void run(String taskId, List billIds) + { + run(taskId, billIds, null); + } + + @Async("threadPoolTaskExecutor") + public void run(String taskId, List billIds, LocalRebillRequest request) { int total = billIds == null ? 0 : billIds.size(); AtomicInteger success = new AtomicInteger(0); AtomicInteger fail = new AtomicInteger(0); StringBuilder failTips = new StringBuilder(); + List> failDetails = Collections.synchronizedList(new ArrayList>()); int threads = clampThreads(billingProperties == null ? null : billingProperties.getOrderSourceSyncThreads()); ExecutorService pool = newWorkerPool(threads, "local-rebill"); try @@ -63,6 +86,7 @@ public class PrcOrderBillLocalRebillAsyncRunner if (total == 0) { put(taskId, BatchAddIncomeBillFeeTask.STATUS_FAIL, 100, "failed", "no bills", 0, 0, 0); + saveDoneLog(taskId, request, total, 0, 0, threads, failDetails, "FAIL", "no bills"); return; } int processed = 0; @@ -85,7 +109,9 @@ public class PrcOrderBillLocalRebillAsyncRunner { fail.incrementAndGet(); appendFail(failTips, one, e); - log.warn("local rebill failed taskId={} billId={}", taskId, one, e); + collectFailDetail(failDetails, one, e); + log.warn("local rebill failed taskId={} billId={} msg={}", + taskId, one, e.getMessage()); return Boolean.FALSE; } }); @@ -98,17 +124,23 @@ public class PrcOrderBillLocalRebillAsyncRunner null, total, success.get(), fail.get()); } String msg = "success=" + success.get() + ", fail=" + fail.get(); - put(taskId, BatchAddIncomeBillFeeTask.STATUS_SUCCESS, 100, msg, - fail.get() > 0 && failTips.length() > 0 ? failTips.toString() : null, + String err = fail.get() > 0 && failTips.length() > 0 ? failTips.toString() : null; + put(taskId, BatchAddIncomeBillFeeTask.STATUS_SUCCESS, 100, msg, err, total, success.get(), fail.get()); + String doneStatus = fail.get() > 0 ? EsBizLogSupport.STATUS_FAIL : EsBizLogSupport.STATUS_SUCCESS; + String doneErr = fail.get() > 0 ? ("fail=" + fail.get() + ", ok=" + success.get()) : null; + saveDoneLog(taskId, request, total, success.get(), fail.get(), threads, failDetails, doneStatus, doneErr); log.info("local rebill done taskId={} total={} success={} fail={} threads={} pageSize={}", taskId, total, success.get(), fail.get(), threads, PAGE_SIZE); } catch (Exception e) { log.error("local rebill aborted taskId={}", taskId, e); - put(taskId, BatchAddIncomeBillFeeTask.STATUS_FAIL, 100, "failed", errorMessage(e), + String msg = errorMessage(e); + put(taskId, BatchAddIncomeBillFeeTask.STATUS_FAIL, 100, "failed", msg, total, success.get(), fail.get()); + saveDoneLog(taskId, request, total, success.get(), fail.get(), threads, failDetails, + EsBizLogSupport.STATUS_FAIL, msg); } finally { @@ -116,6 +148,64 @@ public class PrcOrderBillLocalRebillAsyncRunner } } + private void saveDoneLog(String taskId, LocalRebillRequest request, int total, int ok, int fail, + int threads, List> failDetails, String status, String errorMessage) + { + Map resp = new LinkedHashMap(); + resp.put("taskId", taskId); + resp.put("total", Integer.valueOf(total)); + resp.put("ok", Integer.valueOf(ok)); + resp.put("fail", Integer.valueOf(fail)); + resp.put("success", Integer.valueOf(ok)); + resp.put("threads", Integer.valueOf(threads)); + resp.put("pageSize", Integer.valueOf(PAGE_SIZE)); + if (failDetails != null && !failDetails.isEmpty()) + { + resp.put("failDetails", new ArrayList>(failDetails)); + } + TabOrderSyncEsLog.save(billSearchStore, taskId, "LOCAL_REBILL_DONE", request, resp, status, errorMessage); + } + + private void collectFailDetail(List> failDetails, String billId, Exception e) + { + if (failDetails == null) + { + return; + } + synchronized (failDetails) + { + if (failDetails.size() >= FAIL_DETAIL_MAX) + { + return; + } + Map item = new LinkedHashMap(); + item.put("billId", billId); + String orderNo = null; + String transferNo = null; + String trackingNo = null; + try + { + PrcOrderBill bill = orderBillMapper == null || StringUtils.isEmpty(billId) + ? null : orderBillMapper.selectPrcOrderBillById(billId.trim()); + if (bill != null) + { + orderNo = bill.getOrderNo(); + transferNo = bill.getTransferNo(); + trackingNo = bill.getTrackingNo(); + } + } + catch (Exception ignore) + { + // detail enrichment is best-effort + } + item.put("orderId", StringUtils.isEmpty(orderNo) ? billId : orderNo); + item.put("transferOrderId", transferNo); + item.put("trackingNo", trackingNo); + item.put("errorMessage", errorMessage(e)); + failDetails.add(item); + } + } + public void put(String taskId, String status, int percent, String message, String error, int total, int success, int fail) { diff --git a/bms-front/src/views/monitor/orderSource/components/OrderSourceSyncLogDrawer.vue b/bms-front/src/views/monitor/orderSource/components/OrderSourceSyncLogDrawer.vue index f8bf7b74..e5e824fd 100644 --- a/bms-front/src/views/monitor/orderSource/components/OrderSourceSyncLogDrawer.vue +++ b/bms-front/src/views/monitor/orderSource/components/OrderSourceSyncLogDrawer.vue @@ -39,8 +39,9 @@
失败明细(共 {{ failRows.length }} 单)
+ - +
@@ -113,6 +114,10 @@ function actionLabel(row) { if (action === 'COMPARE_DONE') { return row.status === 'FAIL' ? '比对完成(失败)' : '比对完成' } + if (action === 'LOCAL_REBILL') return '本地重新计费' + if (action === 'LOCAL_REBILL_DONE') { + return row.status === 'FAIL' ? '本地重新计费完成(有失败)' : '本地重新计费完成' + } return action || '-' }