Explorar o código

定时任务: 二手交易平台 - 约定交易时间满24小时未双方确认交易成功自动失败

lutong hai 1 semana
pai
achega
bc3877c67b
Modificáronse 1 ficheiros con 38 adicións e 22 borrados
  1. 38 22
      alien-second/src/main/java/shop/alien/second/task/Task.java

+ 38 - 22
alien-second/src/main/java/shop/alien/second/task/Task.java

@@ -27,7 +27,6 @@ import shop.alien.second.feign.AlienStoreFeign;
 
 import java.time.LocalDateTime;
 import java.time.ZoneId;
-import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -317,41 +316,58 @@ public class Task {
     }
 
     /**
-     * 二手交易平台 - 到达交易时间12个小时后,自动交易失败
+     * 二手交易平台 - 约定交易时间(transaction_time)起已满 24 小时,买卖双方仍未均确认「交易成功」则自动失败:
+     * buyer_transaction_status / seller_transaction_status 均为 1 表示该侧在成交确认里选了成功;否则(含 0 未确认、2 失败、仅一侧成功)满足时间条件则判败。
      */
+    private static final String SUCCESS_CONFIRM_TIMEOUT_FAIL_REASON = "约定交易时间起满24小时双方未完成交易成功确认,系统自动标记交易失败";
+
     @Scheduled(cron = "0 * * * * ?")
-    private void secondTradeTimeoutFail() {
+    private void secondTradeUnconfirmedSuccessTimeoutFail() {
         if (!isEnable) {
             return;
         }
 
-        log.info("开始执行定时任务: 二手交易平台 - 到达交易时间12个小时后,自动交易失败 - secondTradeTimeoutFail");
+        log.info("开始执行定时任务: 二手交易平台 - 约定交易时间满24小时未双方确认交易成功自动失败 - secondTradeUnconfirmedSuccessTimeoutFail");
         try {
-            Date twelveBefore = Date.from(LocalDateTime.now().plusHours(12).withSecond(0).withNano(0).atZone(ZoneId.systemDefault()).toInstant());
+            // 约定交易时间 <= (当前整分 - 24h),即约定时刻至今已至少经过 24 小时
+            Date cutoff = Date.from(LocalDateTime.now().minusHours(24).withSecond(0).withNano(0).atZone(ZoneId.systemDefault()).toInstant());
 
-            // 查询所有待确认
             LambdaQueryWrapper<SecondTradeRecord> queryWrapper = new LambdaQueryWrapper<>();
             queryWrapper.eq(SecondTradeRecord::getTradeStatus, 3);
-            queryWrapper.eq(SecondTradeRecord::getTransactionTime, twelveBefore);
+            queryWrapper.isNotNull(SecondTradeRecord::getTransactionTime);
+            queryWrapper.le(SecondTradeRecord::getTransactionTime, cutoff);
+            // 未双方均确认成功(1):任一侧非 1(未确认/已选失败/仅一侧成功)即命中
+            queryWrapper.apply("(IFNULL(buyer_transaction_status,0) <> 1 OR IFNULL(seller_transaction_status,0) <> 1)");
             List<SecondTradeRecord> tradeRecordList = secondTradeRecordMapper.selectList(queryWrapper);
-            List<Integer> tradeIdList = tradeRecordList.stream().map(SecondTradeRecord::getId).collect(Collectors.toList());
-            if (CollectionUtil.isNotEmpty(tradeIdList)) {
-                LambdaUpdateWrapper<SecondTradeRecord> updateWrapper = new LambdaUpdateWrapper<>();
-                updateWrapper.in(SecondTradeRecord::getId, tradeIdList)
-                        .set(SecondTradeRecord::getTradeStatus, 5);
-                secondTradeRecordMapper.update(null, updateWrapper);
-
-                for (Integer id : tradeIdList) {
-                    SecondTradeOperation operation = new SecondTradeOperation();
-                    operation.setTradeId(id);
-                    operation.setUserId(0);
-                    operation.setType(6);
-                    operation.setCreatedTime(new Date());
-                    secondTradeOperationMapper.insert(operation);
+            if (CollectionUtil.isEmpty(tradeRecordList)) {
+                return;
+            }
+            Date opTime = new Date();
+            // 按单条更新且要求仍为「待交易」,避免多实例 @Scheduled 重复插入操作流水(批量 IN 更新无法区分本实例是否真正抢到行)
+            for (SecondTradeRecord tr : tradeRecordList) {
+                Integer id = tr.getId();
+                if (id == null) {
+                    continue;
+                }
+                LambdaUpdateWrapper<SecondTradeRecord> uw = new LambdaUpdateWrapper<>();
+                uw.eq(SecondTradeRecord::getId, id)
+                        .eq(SecondTradeRecord::getTradeStatus, 3)
+                        .set(SecondTradeRecord::getTradeStatus, 5)
+                        .set(SecondTradeRecord::getFailureFlag, "1")
+                        .set(SecondTradeRecord::getFailureReason, SUCCESS_CONFIRM_TIMEOUT_FAIL_REASON);
+                int updated = secondTradeRecordMapper.update(null, uw);
+                if (updated != 1) {
+                    continue;
                 }
+                SecondTradeOperation operation = new SecondTradeOperation();
+                operation.setTradeId(id);
+                operation.setUserId(0);
+                operation.setType(6);
+                operation.setCreatedTime(opTime);
+                secondTradeOperationMapper.insert(operation);
             }
         } catch (Exception e) {
-            log.error("SecondGoodsTradeXxlJob.secondTradeTimeoutFail Error Mgs={}", e.getMessage());
+            log.error("Task.secondTradeUnconfirmedSuccessTimeoutFail Error Msg={}", e.getMessage(), e);
         }
     }