From 42fa82ce07f80de676e5bacf015f9a68f50f3eda Mon Sep 17 00:00:00 2001 From: cst61 Date: Sat, 11 Jul 2026 08:25:19 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8A=A2=E5=8D=95=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=20=E6=8C=87=E5=AE=9A=E8=B4=A7=E7=89=A9?= =?UTF-8?q?=E5=8C=85=E7=9A=84=E5=BC=80=E5=A7=8B=E6=97=A5=E6=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rj/controller/LbBuyAccountController.java | 4 +- .../rj/dto/LbBuyAccountRushBuyRequest.java | 3 ++ .../com/rj/service/ILbBuyAccountService.java | 4 +- .../java/com/rj/service/ILbGoodsService.java | 9 ++-- .../service/impl/LbBuyAccountServiceImpl.java | 17 +++---- .../rj/service/impl/LbGoodsServiceImpl.java | 46 +++++++++++++------ 6 files changed, 55 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/rj/controller/LbBuyAccountController.java b/src/main/java/com/rj/controller/LbBuyAccountController.java index 60b4223..b94dd04 100644 --- a/src/main/java/com/rj/controller/LbBuyAccountController.java +++ b/src/main/java/com/rj/controller/LbBuyAccountController.java @@ -90,11 +90,11 @@ public class LbBuyAccountController { "根据 ids 查询 lb_buy_account,按 tenant_id 关联 lb_third_integration_config 获取 URL 与 appStr;" + "各账号并发抢购(每账号一线程);accountResults 顺序与 ids 一致;同租户同货品 ID 仅允许一个账号尝试;" + "每个账号使用 token_front 作为 hxrd 请求 Token,max_grab_count 作为最大成功抢购笔数," - + "抢购逻辑同 LbGoodsController#rushBuy") + + "抢购逻辑同 LbGoodsController#rushBuy;goodsBeginTime 指定货物包开始时间,查询 lb_goods 时 updated_at 需大于此时间") public ResponseEntity> rushBuy( @Parameter(description = "抢单账号 ID 列表", required = true) @RequestBody LbBuyAccountRushBuyRequest request) { - Map result = lbBuyAccountService.rushBuyByIds(request.getIds()); + Map result = lbBuyAccountService.rushBuyByIds(request.getIds(), request.getGoodsBeginTime()); Boolean success = (Boolean) result.get("success"); if (success != null && success) { return ResponseEntity.ok(result); diff --git a/src/main/java/com/rj/dto/LbBuyAccountRushBuyRequest.java b/src/main/java/com/rj/dto/LbBuyAccountRushBuyRequest.java index 1713ed9..b263167 100644 --- a/src/main/java/com/rj/dto/LbBuyAccountRushBuyRequest.java +++ b/src/main/java/com/rj/dto/LbBuyAccountRushBuyRequest.java @@ -15,4 +15,7 @@ public class LbBuyAccountRushBuyRequest { @Schema(description = "抢单账号主键 ID 列表(lb_buy_account.id)", requiredMode = Schema.RequiredMode.REQUIRED) private List ids; + + @Schema(description = "货物包开始时间,格式 yyyy-MM-dd HH:mm:ss,查询 lb_goods 时 updated_at 需大于此时间") + private String goodsBeginTime; } diff --git a/src/main/java/com/rj/service/ILbBuyAccountService.java b/src/main/java/com/rj/service/ILbBuyAccountService.java index 9d6adbb..563f5b0 100644 --- a/src/main/java/com/rj/service/ILbBuyAccountService.java +++ b/src/main/java/com/rj/service/ILbBuyAccountService.java @@ -28,6 +28,8 @@ public interface ILbBuyAccountService extends IService { /** * 按账号 ID 列表批量抢购:每个账号使用其 token_front 与 max_grab_count, * tenant_id 关联 lb_third_integration_config 解析 URL 与 appStr。 + * + * @param goodsBeginTime 货物包开始时间,格式 yyyy-MM-dd HH:mm:ss,查询 lb_goods 时 updated_at 需大于此时间 */ - Map rushBuyByIds(List ids); + Map rushBuyByIds(List ids, String goodsBeginTime); } diff --git a/src/main/java/com/rj/service/ILbGoodsService.java b/src/main/java/com/rj/service/ILbGoodsService.java index c9b9251..4539ad0 100644 --- a/src/main/java/com/rj/service/ILbGoodsService.java +++ b/src/main/java/com/rj/service/ILbGoodsService.java @@ -54,11 +54,11 @@ public interface ILbGoodsService extends IService { * @param token 失效时,按账号凭证自动登录并刷新 {@code lb_buy_account.token_front} */ default Map rushBuy(String tenantId, String token, Integer maxBuyCount) { - return rushBuy(tenantId, token, maxBuyCount, null, null, null, null, null); + return rushBuy(tenantId, token, maxBuyCount, null, null, null, null, null, null); } default Map rushBuy(String tenantId, String token, Integer maxBuyCount, String rushBuyAccountLabel) { - return rushBuy(tenantId, token, maxBuyCount, rushBuyAccountLabel, null, null, null, null); + return rushBuy(tenantId, token, maxBuyCount, rushBuyAccountLabel, null, null, null, null, null); } default Map rushBuy( @@ -67,7 +67,7 @@ public interface ILbGoodsService extends IService { Integer maxBuyCount, String rushBuyAccountLabel, LbBuyAccountRushBuyContext tokenRefreshContext) { - return rushBuy(tenantId, token, maxBuyCount, rushBuyAccountLabel, tokenRefreshContext, null, null, null); + return rushBuy(tenantId, token, maxBuyCount, rushBuyAccountLabel, tokenRefreshContext, null, null, null, null); } Map rushBuy( @@ -78,5 +78,6 @@ public interface ILbGoodsService extends IService { LbBuyAccountRushBuyContext tokenRefreshContext, LbRushBuyGoodsCoordinator goodsCoordinator, String accountId, - Integer maxGrabAmount); + Integer maxGrabAmount, + String goodsBeginTime); } diff --git a/src/main/java/com/rj/service/impl/LbBuyAccountServiceImpl.java b/src/main/java/com/rj/service/impl/LbBuyAccountServiceImpl.java index 7e9ff52..b6b2020 100644 --- a/src/main/java/com/rj/service/impl/LbBuyAccountServiceImpl.java +++ b/src/main/java/com/rj/service/impl/LbBuyAccountServiceImpl.java @@ -212,7 +212,7 @@ public class LbBuyAccountServiceImpl } @Override - public Map rushBuyByIds(List ids) { + public Map rushBuyByIds(List ids, String goodsBeginTime) { Map result = new HashMap<>(); try { if (ids == null || ids.isEmpty()) { @@ -249,8 +249,8 @@ public class LbBuyAccountServiceImpl t.setDaemon(false); return t; }); - log.info("批量抢单启动,账号数={},并发线程数={}(每账号一线程),同租户同货品仅一个账号抢购", - normalizedIds.size(), poolSize); + log.info("批量抢单启动,账号数={},并发线程数={}(每账号一线程),同租户同货品仅一个账号抢购,goodsBeginTime={}", + normalizedIds.size(), poolSize, goodsBeginTime); List> accountResults; int successAccounts; @@ -260,7 +260,7 @@ public class LbBuyAccountServiceImpl for (String id : normalizedIds) { LbBuyAccount account = accountMap.get(id); futures.add(CompletableFuture.supplyAsync( - () -> runSingleAccountRushBuyTask(id, account, goodsCoordinator), + () -> runSingleAccountRushBuyTask(id, account, goodsCoordinator, goodsBeginTime), executor)); } CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new)).join(); @@ -309,9 +309,9 @@ public class LbBuyAccountServiceImpl } private Map runSingleAccountRushBuyTask( - String id, LbBuyAccount account, LbRushBuyGoodsCoordinator goodsCoordinator) { + String id, LbBuyAccount account, LbRushBuyGoodsCoordinator goodsCoordinator, String goodsBeginTime) { try { - return processSingleAccountRushBuy(id, account, goodsCoordinator); + return processSingleAccountRushBuy(id, account, goodsCoordinator, goodsBeginTime); } catch (Exception e) { log.error("抢单账号任务执行异常,accountId={},loginAccount={},thread={}", id, account != null ? account.getLoginAccount() : null, @@ -340,7 +340,7 @@ public class LbBuyAccountServiceImpl * 单账号抢单逻辑;批量入口为每账号一线程并发调用,共享 {@link LbRushBuyGoodsCoordinator}。 */ private Map processSingleAccountRushBuy( - String id, LbBuyAccount account, LbRushBuyGoodsCoordinator goodsCoordinator) { + String id, LbBuyAccount account, LbRushBuyGoodsCoordinator goodsCoordinator, String goodsBeginTime) { String accountLabel = formatRushBuyAccountLabel(id, account); log.info("抢单任务开始,{},thread={}", accountLabel, Thread.currentThread().getName()); Map item = new LinkedHashMap<>(); @@ -389,7 +389,8 @@ public class LbBuyAccountServiceImpl tokenRefreshContext, goodsCoordinator, account.getId(), - maxGrabAmount); + maxGrabAmount, + goodsBeginTime); item.put("rushBuyResult", rushBuyResult); rushSuccess = rushBuyResult.get("success") instanceof Boolean ? (Boolean) rushBuyResult.get("success") diff --git a/src/main/java/com/rj/service/impl/LbGoodsServiceImpl.java b/src/main/java/com/rj/service/impl/LbGoodsServiceImpl.java index 33bd7ed..102a541 100644 --- a/src/main/java/com/rj/service/impl/LbGoodsServiceImpl.java +++ b/src/main/java/com/rj/service/impl/LbGoodsServiceImpl.java @@ -529,7 +529,8 @@ public class LbGoodsServiceImpl extends ServiceImpl impl LbBuyAccountRushBuyContext tokenRefreshContext, LbRushBuyGoodsCoordinator goodsCoordinator, String accountId, - Integer maxGrabAmount) { + Integer maxGrabAmount, + String goodsBeginTime) { Map result = new HashMap<>(); String accountTag = formatRushBuyAccountLogTag(rushBuyAccountLabel); try { @@ -562,10 +563,13 @@ public class LbGoodsServiceImpl extends ServiceImpl impl TenantContextHolder.setTenantId(tid); try { log.info("查询-待抢购-货物列表......"); - List goodsList = resolveRushBuyGoodsList(tid, accountTag, goodsCoordinator);// + List goodsList = resolveRushBuyGoodsList(tid, accountTag, goodsCoordinator, goodsBeginTime); if (goodsList.isEmpty()) { result.put("success", false); - result.put("message", "lb_goods 中无可抢购货品(金额需大于25000且不超过38000,且更新时间需在24小时内)"); + String timeCondition = goodsBeginTime != null && !goodsBeginTime.trim().isEmpty() + ? "且更新时间需大于 goodsBeginTime(" + goodsBeginTime + ")" + : "且更新时间需在24小时内"; + result.put("message", "lb_goods 中无可抢购货品(金额需大于25000且不超过38000," + timeCondition + ")"); result.put("successCount", 0); result.put("failCount", 0); result.put("details", List.of()); @@ -849,9 +853,9 @@ public class LbGoodsServiceImpl extends ServiceImpl impl } private List resolveRushBuyGoodsList( - String tid, String accountTag, LbRushBuyGoodsCoordinator goodsCoordinator) { + String tid, String accountTag, LbRushBuyGoodsCoordinator goodsCoordinator, String goodsBeginTime) { if (goodsCoordinator == null) { - return loadRushBuyGoodsList(tid, accountTag); + return loadRushBuyGoodsList(tid, accountTag, goodsBeginTime); } List cached = goodsCoordinator.peekRushBuyGoodsList(tid); if (cached != null) { @@ -863,27 +867,43 @@ public class LbGoodsServiceImpl extends ServiceImpl impl } return cached; } - return goodsCoordinator.resolveRushBuyGoodsList(tid, () -> loadRushBuyGoodsList(tid, accountTag)); + return goodsCoordinator.resolveRushBuyGoodsList(tid, () -> loadRushBuyGoodsList(tid, accountTag, goodsBeginTime)); } - private List loadRushBuyGoodsList(String tid, String accountTag) { - LocalDateTime updatedAfter = resolveRushBuyUpdatedAfter(); + private List loadRushBuyGoodsList(String tid, String accountTag, String goodsBeginTime) { + LocalDateTime updatedAfter; + boolean useGoodsBeginTime = goodsBeginTime != null && !goodsBeginTime.trim().isEmpty(); + if (useGoodsBeginTime) { + try { + updatedAfter = LocalDateTime.parse(goodsBeginTime.trim(), DATETIME_FMT); + } catch (DateTimeParseException e) { + log.warn("goodsBeginTime 格式错误,忽略该参数,使用默认时间范围,goodsBeginTime={}", goodsBeginTime); + updatedAfter = resolveRushBuyUpdatedAfter(); + useGoodsBeginTime = false; + } + } else { + updatedAfter = resolveRushBuyUpdatedAfter(); + } LambdaQueryWrapper w = new LambdaQueryWrapper<>(); w.eq(LbGoods::getTenantId, tid); w.isNotNull(LbGoods::getSellerId); w.gt(LbGoods::getTotalMoney, RUSH_BUY_MIN_TOTAL_MONEY); w.le(LbGoods::getTotalMoney, RUSH_BUY_MAX_TOTAL_MONEY); - w.ge(LbGoods::getUpdatedAt, updatedAfter); + if (useGoodsBeginTime) { + w.gt(LbGoods::getUpdatedAt, updatedAfter); + } else { + w.ge(LbGoods::getUpdatedAt, updatedAfter); + } w.orderByDesc(LbGoods::getTotalMoney); long goodsQueryStartedAt = System.nanoTime(); List goodsList = this.list(w); long goodsQueryElapsedMs = (System.nanoTime() - goodsQueryStartedAt) / 1_000_000L; if (accountTag.isEmpty()) { - log.info("rushBuy 查询可抢货品耗时 {} ms,tenantId={},updatedAfter={},结果数量={}", - goodsQueryElapsedMs, tid, updatedAfter, goodsList.size()); + log.info("rushBuy 查询可抢货品耗时 {} ms,tenantId={},updatedAfter={},goodsBeginTime={},结果数量={}", + goodsQueryElapsedMs, tid, updatedAfter, goodsBeginTime, goodsList.size()); } else { - log.info("{} rushBuy 查询可抢货品耗时 {} ms,tenantId={},updatedAfter={},结果数量={}", - accountTag, goodsQueryElapsedMs, tid, updatedAfter, goodsList.size()); + log.info("{} rushBuy 查询可抢货品耗时 {} ms,tenantId={},updatedAfter={},goodsBeginTime={},结果数量={}", + accountTag, goodsQueryElapsedMs, tid, updatedAfter, goodsBeginTime, goodsList.size()); } return goodsList; }