Browse Source

小程序订单调试

skyline 1 month ago
parent
commit
63160fcfdc

+ 16 - 17
haha-service/src/main/java/com/haha/service/impl/DoorRecordServiceImpl.java

@@ -19,7 +19,7 @@ import java.util.concurrent.TimeUnit;
 
 /**
  * 设备开关门记录服务实现类
- * 
+ *
  * @author haha
  */
 @Slf4j
@@ -33,11 +33,11 @@ public class DoorRecordServiceImpl extends ServiceImpl<DoorRecordMapper, DoorRec
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public DoorRecord saveDoorOpenRecord(String deviceId, Long userId, String activityId, 
+    public DoorRecord saveDoorOpenRecord(String deviceId, Long userId, String activityId,
                                          String doorIndex, String openType, String source) {
         try {
             LocalDateTime now = LocalDateTime.now();
-            
+
             // 1. 保存到数据库
             DoorRecord record = new DoorRecord();
             record.setActivityId(activityId);
@@ -49,10 +49,10 @@ public class DoorRecordServiceImpl extends ServiceImpl<DoorRecordMapper, DoorRec
             record.setNobuy(0); // 默认假设有消费,后续 AI 识别会更新
             record.setOpenTime(now);
             record.setSource(source);
-            
+
             boolean saved = this.save(record);
             if (saved) {
-                log.info("保存开门记录到数据库 - activityId: {}, deviceId: {}, userId: {}", 
+                log.info("保存开门记录到数据库 - activityId: {}, deviceId: {}, userId: {}",
                         activityId, deviceId, userId);
             } else {
                 log.error("保存开门记录到数据库失败 - activityId: {}", activityId);
@@ -62,7 +62,7 @@ public class DoorRecordServiceImpl extends ServiceImpl<DoorRecordMapper, DoorRec
             saveToRedis(activityId, deviceId, userId, doorIndex, openType, now, source);
 
             return record;
-            
+
         } catch (Exception e) {
             log.error("保存开门记录失败 - activityId: {}", activityId, e);
             throw new RuntimeException("保存开门记录失败", e);
@@ -87,11 +87,10 @@ public class DoorRecordServiceImpl extends ServiceImpl<DoorRecordMapper, DoorRec
 
             LocalDateTime closeTime = LocalDateTime.now();
             int result = baseMapper.updateDoorStatus(activityId, "CLOSED", closeTime);
-            
+
             if (result > 0) {
-                log.info("更新门状态为已关门 - activityId: {}, 持续时长:{}秒", 
-                        activityId, record.getDuration());
-                
+                log.info("更新门状态为已关门 - activityId: {}, 持续时长:{}秒", activityId, record.getDuration());
+
                 // 同时更新 Redis
                 updateRedisDoorStatus(activityId, "CLOSED", closeTime);
                 return true;
@@ -112,7 +111,7 @@ public class DoorRecordServiceImpl extends ServiceImpl<DoorRecordMapper, DoorRec
             int result = baseMapper.markNoConsume(activityId);
             if (result > 0) {
                 log.info("标记无消费记录 - activityId: {}", activityId);
-                
+
                 // 同时更新 Redis
                 updateRedisNobuy(activityId, 1);
                 return true;
@@ -133,7 +132,7 @@ public class DoorRecordServiceImpl extends ServiceImpl<DoorRecordMapper, DoorRec
             int result = baseMapper.linkOrderId(activityId, orderId);
             if (result > 0) {
                 log.info("关联订单 ID - activityId: {}, orderId: {}", activityId, orderId);
-                
+
                 // 同时更新 Redis
                 updateRedisOrderId(activityId, orderId);
                 return true;
@@ -170,13 +169,13 @@ public class DoorRecordServiceImpl extends ServiceImpl<DoorRecordMapper, DoorRec
         LambdaQueryWrapper<DoorRecord> wrapper = new LambdaQueryWrapper<>();
         wrapper.eq(DoorRecord::getDeviceId, deviceId)
                .orderByDesc(DoorRecord::getOpenTime);
-        
+
         return this.page(new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(page, pageSize), wrapper);
     }
 
     // ==================== Redis 操作方法 ====================
 
-    private void saveToRedis(String activityId, String deviceId, Long userId, 
+    private void saveToRedis(String activityId, String deviceId, Long userId,
                             String doorIndex, String openType, LocalDateTime openTime, String source) {
         try {
             String key = DOOR_RECORD_REDIS_KEY + activityId;
@@ -189,10 +188,10 @@ public class DoorRecordServiceImpl extends ServiceImpl<DoorRecordMapper, DoorRec
             record.put("openTime", String.valueOf(openTime.toEpochSecond(java.time.ZoneOffset.UTC)));
             record.put("source", source != null ? source : "");
             record.put("status", "OPENED");
-            
+
             stringRedisTemplate.opsForHash().putAll(key, record);
             stringRedisTemplate.expire(key, REDIS_EXPIRE_MINUTES, TimeUnit.MINUTES);
-            
+
             log.debug("保存开门记录到 Redis: activityId={}", activityId);
         } catch (Exception e) {
             log.error("保存开门记录到 Redis 失败 - activityId: {}", activityId, e);
@@ -204,7 +203,7 @@ public class DoorRecordServiceImpl extends ServiceImpl<DoorRecordMapper, DoorRec
         try {
             String key = DOOR_RECORD_REDIS_KEY + activityId;
             stringRedisTemplate.opsForHash().put(key, "doorStatus", doorStatus);
-            stringRedisTemplate.opsForHash().put(key, "closeTime", 
+            stringRedisTemplate.opsForHash().put(key, "closeTime",
                 String.valueOf(closeTime.toEpochSecond(java.time.ZoneOffset.UTC)));
             log.debug("更新 Redis 门状态 - activityId: {}, status: {}", activityId, doorStatus);
         } catch (Exception e) {

+ 28 - 21
haha-service/src/main/java/com/haha/service/impl/HahaCallbackServiceImpl.java

@@ -574,20 +574,27 @@ public class HahaCallbackServiceImpl implements HahaCallbackService {
     }
 
     /**
-     * 根据识别结果更新订单信息
+     * 根据AI识别结果更新订单信息
+     *
+     * 注意:
+     * - 此时只更新商品列表和视频URL,不更新金额
+     * - 金额由设备端在订单回调(handleOrderCallback)时提供
+     * - AI识别结果只包含商品编码和数量,不包含价格
      *
      * @param order          订单对象
-     * @param skuListStr     商品列表字符串
+     * @param skuListStr     商品列表字符串(包含code和quantity)
      * @param resourceInfoStr 资源信息字符串
      * @param confidence     置信度
      * @param activityId     活动ID
      */
     private void updateOrderFromRecognition(Order order, String skuListStr, String resourceInfoStr, BigDecimal confidence, String activityId) {
-        BigDecimal totalAmount = calculateTotalAmount(skuListStr);
+        // 解析视频URL
         String videoUrl = parseVideoUrl(resourceInfoStr);
 
+        // 更新订单信息:只更新商品列表和视频URL,不更新金额
         order.setItems(skuListStr);
-        order.setTotalAmount(totalAmount);
+        // 注意:不更新totalAmount,保持为0,等待订单回调时更新
+        
         if (videoUrl != null) {
             order.setVideoUrl(videoUrl);
         }
@@ -597,7 +604,7 @@ public class HahaCallbackServiceImpl implements HahaCallbackService {
 
         boolean updated = orderService.updateById(order);
         if (updated) {
-            log.info("订单信息更新成功 - orderId: {}, totalAmount: {}", order.getId(), totalAmount);
+            log.info("订单识别信息更新成功 - orderId: {}, 等待回调更新金额", order.getId());
         }
 
         saveOrderInfoToRedis(order, activityId);
@@ -727,23 +734,23 @@ public class HahaCallbackServiceImpl implements HahaCallbackService {
         return null;
     }
 
+    /**
+     * 计算订单总金额
+     * 
+     * 注意:
+     * - AI识别结果(sku_list)不包含价格信息,只包含商品编码和数量
+     * - 此方法目前已不使用,因为订单金额由设备端在回调时直接提供
+     * - 保留此方法以备后续可能的服务端价格校验需求
+     * 
+     * @param skuListStr 商品列表JSON字符串
+     * @return 总金额,如果无法计算则返回0
+     */
+    @Deprecated
     private BigDecimal calculateTotalAmount(String skuListStr) {
-        BigDecimal totalAmount = BigDecimal.ZERO;
-        if (skuListStr != null && !skuListStr.isEmpty()) {
-            JSONArray skuList = JSON.parseArray(skuListStr);
-            if (skuList != null) {
-                for (int i = 0; i < skuList.size(); i++) {
-                    JSONObject sku = skuList.getJSONObject(i);
-                    BigDecimal price = sku.getBigDecimal("price");
-                    Integer quantity = sku.getInteger("quantity");
-                    if (price != null && quantity != null) {
-                        totalAmount = totalAmount.add(price.multiply(BigDecimal.valueOf(quantity)));
-                    }
-                }
-                totalAmount = totalAmount.setScale(2, RoundingMode.HALF_UP);
-            }
-        }
-        return totalAmount;
+        // 注意:AI识别结果不包含price字段,此方法无法正确计算金额
+        // 订单金额应由设备端在回调时提供(order_money参数)
+        log.warn("calculateTotalAmount方法已废弃,AI识别结果不包含价格信息");
+        return BigDecimal.ZERO;
     }
 
     private String parseVideoUrl(String resourceInfoStr) {

+ 17 - 35
haha-service/src/main/java/com/haha/service/impl/OrderServiceImpl.java

@@ -305,19 +305,19 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
      * 
      * 业务流程:
      * 1. 幂等性检查:防止重复创建订单
-     * 2. 解析商品列表,计算订单总金额(price * quantity累加
+     * 2. 保存商品识别信息(此时不计算金额,因为AI识别结果不包含价格
      * 3. 解析视频URL等资源信息
-     * 4. 创建订单记录,状态为待支付
+     * 4. 创建订单记录,状态为待支付,金额为0(等待订单回调时由设备端提供实付金额)
      * 
      * 注意:
-     * - 此方法只计算商品原价总额,不涉及优惠计算
-     * - 优惠计算在订单结算时由MarketingRuleService处理
-     * - 如果使用优惠券,由UserCouponService处理
+     * - AI识别结果(sku_list)只包含商品编码(code)和数量(quantity),不包含价格
+     * - 商品价格在订单回调时由设备端计算并传来
+     * - 此方法只创建订单框架,实际金额在handleOrderCallback中更新
      * 
      * @param activityId 活动ID(设备开门会话ID)
      * @param deviceId 设备ID
      * @param userId 用户ID
-     * @param skuListStr 商品列表JSON字符串,格式:[{"price":10.5,"quantity":2}]
+     * @param skuListStr 商品列表JSON字符串,格式:[{"code":"C001","quantity":2}](不包含price)
      * @param resourceInfoStr 资源信息JSON字符串,包含视频URL等
      * @param confidence AI识别置信度
      * @return 创建的订单对象,失败返回null
@@ -335,43 +335,25 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
             }
         }
         
-        // 【步骤2】计算订单总金额:遍历商品列表,累加 price * quantity
-        BigDecimal totalAmount = BigDecimal.ZERO;
-        JSONArray skuList = null;
-        if (skuListStr != null && !skuListStr.isEmpty()) {
-            skuList = JSON.parseArray(skuListStr);
-            if (skuList != null) {
-                for (int i = 0; i < skuList.size(); i++) {
-                    JSONObject sku = skuList.getJSONObject(i);
-                    BigDecimal price = sku.getBigDecimal("price");      // 商品单价
-                    Integer quantity = sku.getInteger("quantity");      // 商品数量
-                    if (price != null && quantity != null) {
-                        // 累加每个商品的金额:单价 × 数量
-                        totalAmount = totalAmount.add(price.multiply(BigDecimal.valueOf(quantity)));
-                    }
-                }
-                // 保留两位小数,四舍五入
-                totalAmount = totalAmount.setScale(2, RoundingMode.HALF_UP);
-            }
-        }
-
-        // 【步骤3】解析视频URL等资源信息
+        // 【步骤2】解析视频URL等资源信息
         String videoUrl = null;
         if (resourceInfoStr != null && !resourceInfoStr.isEmpty()) {
             JSONObject resourceInfo = JSON.parseObject(resourceInfoStr);
             videoUrl = resourceInfo.getString("video_url");
         }
 
-        // 【步骤4】创建订单记录
-        // 注意:此时只保存商品原价总额(totalAmount),不计算优惠
-        // 优惠金额(discountAmount)在订单结算时由设备端或MarketingRuleService计算
-        if (userId != null && deviceId != null && totalAmount.compareTo(BigDecimal.ZERO) > 0) {
+        // 【步骤3】创建订单记录
+        // 注意:
+        // 1. AI识别结果不包含商品价格,只包含商品编码和数量
+        // 2. 此时订单金额设为0(或NULL),等待设备端回调时更新为实付金额
+        // 3. 设备端会根据商品编码查询价格,并计算优惠后得到最终实付金额
+        if (userId != null && deviceId != null) {
             Order order = new Order();
             order.setActivityId(activityId);                          // 开门会话ID
             order.setUserId(Long.parseLong(userId));                  // 用户ID
             order.setDeviceId(deviceId);                              // 设备ID
-            order.setTotalAmount(totalAmount);                        // 订单总金额(商品原价)
-            order.setItems(skuListStr);                               // 商品列表JSON
+            order.setTotalAmount(BigDecimal.ZERO);                    // 初始金额为0,等待回调更新
+            order.setItems(skuListStr);                               // 商品列表JSON(包含code和quantity)
             order.setStatus(OrderConstants.STATUS_PENDING_PAYMENT);   // 订单状态:待支付
             order.setPayStatus(OrderConstants.PAY_STATUS_UNPAID);     // 支付状态:未支付
             order.setCreateTime(LocalDateTime.now());                 // 创建时间
@@ -384,14 +366,14 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
 
             boolean saved = this.save(order);
             if (saved) {
-                log.info("订单创建成功 - 订单ID: {}, 用户: {}, 金额: {}", order.getId(), userId, totalAmount);
+                log.info("订单创建成功 - 订单ID: {}, 用户: {}, 等待回调更新金额", order.getId(), userId);
                 return order;
             } else {
                 log.error("订单创建失败 - 用户: {}, 设备: {}", userId, deviceId);
                 return null;
             }
         } else {
-            log.warn("订单创建跳过 - 缺少必要参数: userId={}, deviceId={}, amount={}", userId, deviceId, totalAmount);
+            log.warn("订单创建跳过 - 缺少必要参数: userId={}, deviceId={}", userId, deviceId);
             return null;
         }
     }