Procházet zdrojové kódy

完成优惠券改动

lutong před 1 měsícem
rodič
revize
cbc85b9664

+ 10 - 9
alien-dining/src/main/java/shop/alien/dining/controller/DiningCouponController.java

@@ -32,21 +32,22 @@ import java.util.Map;
 @ApiSort(3)
 @CrossOrigin
 @RestController
-@RequestMapping("/dining/coupon")
+@RequestMapping({"/dining/coupon"})
 @RequiredArgsConstructor
 public class DiningCouponController {
 
     private final DiningCouponService diningCouponService;
 
     /**
-     * 获取当前用户优惠券列表(分 tab:全部/即将过期/已使用/已过期)
+     * 获取该用户所有的优惠券列表
      */
-    @ApiOperation(value = "获取用户优惠券列表", notes = "需登录,请求头带 Authorization。tabType:0全部未使用,1即将过期,2已使用,3已过期。type:不传=优惠券+代金券,1=仅优惠券,4=仅代金券。couponType:1=仅满减券,2=仅折扣券,不传=全部优惠券")
-    @GetMapping("/userList")
+    @ApiOperation("获取该用户所有的优惠券列表。couponType=1仅满减券,couponType=2仅折扣券,不传返回全部优惠券")
+    @ApiOperationSupport(order = 9)
+    @GetMapping("/getUserCouponList")
     @ApiImplicitParams({
-            @ApiImplicitParam(name = "page", value = "页码", dataType = "int", paramType = "query", required = true),
-            @ApiImplicitParam(name = "size", value = "每页条数", dataType = "int", paramType = "query", required = true),
-            @ApiImplicitParam(name = "tabType", value = "tab类型:0全部未使用,1即将过期,2已使用,3已过期", dataType = "String", paramType = "query", required = true),
+            @ApiImplicitParam(name = "page", value = "分页页数", dataType = "Integer", paramType = "query", required = false),
+            @ApiImplicitParam(name = "size", value = "分页条数", dataType = "Integer", paramType = "query", required = false),
+            @ApiImplicitParam(name = "tabType", value = "分页类型(0:全部(未使用),1:即将过期,2:已使用,3:已过期)", dataType = "String", paramType = "query", required = true),
             @ApiImplicitParam(name = "type", value = "券类型(不传:优惠券+代金券都返回,1:仅优惠券查 life_discount_coupon,4:仅代金券查 life_coupon)", dataType = "Integer", paramType = "query", required = false),
             @ApiImplicitParam(name = "couponType", value = "优惠券类型:1=仅满减券,2=仅折扣券,不传=全部优惠券(可选,仅当type不为4时有效)", dataType = "Integer", paramType = "query", required = false)
     })
@@ -55,8 +56,8 @@ public class DiningCouponController {
             @RequestParam(value = "page", defaultValue = "1") int page,
             @RequestParam(value = "size", defaultValue = "10") int size,
             @RequestParam("tabType") String tabType,
-            @ApiParam(value = "券类型(不传:优惠券+代金券都返回,1:仅优惠券,4:仅代金券)") @RequestParam(value = "type", required = false) Integer type,
-            @ApiParam(value = "优惠券类型:1=仅满减券,2=仅折扣券,不传=全部优惠券(仅当type不为4时有效)") @RequestParam(value = "couponType", required = false) Integer couponType) {
+            @RequestParam(value = "type", required = false) Integer type,
+            @RequestParam(value = "couponType", required = false) Integer couponType) {
         String authorization = request.getHeader("Authorization");
         return diningCouponService.getUserCouponList(authorization, page, size, tabType, type, couponType);
     }

+ 4 - 4
alien-dining/src/main/java/shop/alien/dining/feign/AlienStoreFeign.java

@@ -49,9 +49,9 @@ public interface AlienStoreFeign {
      * 获取用户优惠券列表(分 tab:全部/即将过期/已使用/已过期)
      *
      * @param authorization 请求头 Authorization,供 store 解析当前用户
-     * @param page          页码
-     * @param size          每页条数
      * @param tabType       0:全部(未使用),1:即将过期,2:已使用,3:已过期
+     * @param page          页码(默认1)
+     * @param size          每页条数(默认10)
      * @param type          券类型(不传:优惠券+代金券都返回,1:仅优惠券查 life_discount_coupon,4:仅代金券查 life_coupon)(可选)
      * @param couponType    优惠券类型:1=仅满减券,2=仅折扣券,不传=全部优惠券(可选,仅当type不为4时有效)
      * @return R.data 为 List<LifeDiscountCouponVo>
@@ -59,9 +59,9 @@ public interface AlienStoreFeign {
     @GetMapping("life-discount-coupon/getUserCouponList")
     R<List<LifeDiscountCouponVo>> getUserCouponList(
             @RequestHeader(value = "Authorization", required = false) String authorization,
-            @RequestParam("page") int page,
-            @RequestParam("size") int size,
             @RequestParam("tabType") String tabType,
+            @RequestParam(value = "page", defaultValue = "1") int page,
+            @RequestParam(value = "size", defaultValue = "10") int size,
             @RequestParam(value = "type", required = false) Integer type,
             @RequestParam(value = "couponType", required = false) Integer couponType);
 

+ 22 - 4
alien-dining/src/main/java/shop/alien/dining/service/impl/DiningCouponServiceImpl.java

@@ -43,14 +43,32 @@ public class DiningCouponServiceImpl implements DiningCouponService {
     public R<List<LifeDiscountCouponVo>> getUserCouponList(String authorization, int page, int size, String tabType, Integer type, Integer couponType) {
         log.info("DiningCouponService.getUserCouponList page={}, size={}, tabType={}, type={}, couponType={}", page, size, tabType, type, couponType);
         try {
-            R<List<LifeDiscountCouponVo>> result = alienStoreFeign.getUserCouponList(authorization, page, size, tabType, type, couponType);
+            // 参数校验
+            if (StringUtils.isEmpty(tabType)) {
+                log.warn("tabType参数为空");
+                return R.fail("分页类型不能为空");
+            }
+            if (page < 1) {
+                page = 1;
+            }
+            if (size < 1 || size > 100) {
+                size = 10;
+            }
+            
+            R<List<LifeDiscountCouponVo>> result = alienStoreFeign.getUserCouponList(authorization, tabType, page, size, type, couponType);
             if (result == null) {
-                return R.fail("获取优惠券列表失败");
+                log.error("Feign调用返回null");
+                return R.fail("获取优惠券列表失败:服务返回为空");
+            }
+            // 如果 Feign 返回的是失败结果,直接返回
+            if (!result.isSuccess()) {
+                log.warn("Feign调用返回失败: code={}, msg={}", result.getCode(), result.getMsg());
+                return result;
             }
             return result;
         } catch (Exception e) {
-            log.error("DiningCouponService.getUserCouponList ERROR Msg={}", e.getMessage());
-            return R.fail("获取优惠券列表失败");
+            log.error("DiningCouponService.getUserCouponList ERROR: {}", e.getMessage(), e);
+            return R.fail("获取优惠券列表失败: " + e.getMessage());
         }
     }
 

+ 10 - 212
alien-dining/src/main/java/shop/alien/dining/service/impl/StoreOrderServiceImpl.java

@@ -43,44 +43,6 @@ import java.util.stream.Collectors;
 @Transactional(rollbackFor = Exception.class)
 public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOrder> implements StoreOrderService {
 
-    /**
-     * 金额验证误差阈值(0.01元)
-     */
-    private static final BigDecimal AMOUNT_TOLERANCE = new BigDecimal("0.01");
-
-    /**
-     * 订单金额信息封装类
-     */
-    private static class OrderAmountInfo {
-        private final BigDecimal totalAmount;      // 订单总金额(菜品总价)
-        private final BigDecimal tablewareFee;     // 餐具费
-        private final BigDecimal discountAmount;   // 优惠金额
-        private final BigDecimal payAmount;        // 实付金额
-
-        public OrderAmountInfo(BigDecimal totalAmount, BigDecimal tablewareFee, 
-                              BigDecimal discountAmount, BigDecimal payAmount) {
-            this.totalAmount = totalAmount;
-            this.tablewareFee = tablewareFee;
-            this.discountAmount = discountAmount;
-            this.payAmount = payAmount;
-        }
-
-        public BigDecimal getTotalAmount() {
-            return totalAmount;
-        }
-
-        public BigDecimal getTablewareFee() {
-            return tablewareFee;
-        }
-
-        public BigDecimal getDiscountAmount() {
-            return discountAmount;
-        }
-
-        public BigDecimal getPayAmount() {
-            return payAmount;
-        }
-    }
 
     private final StoreOrderDetailMapper orderDetailMapper;
     private final StoreTableMapper storeTableMapper;
@@ -155,25 +117,17 @@ public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOr
             throw new RuntimeException("购物车中没有新增商品或商品数量未增加,无法创建订单");
         }
 
-        // 验证并纠正前端传入的金额(订单总金额、餐具费、优惠金额、实付金额)
-        OrderAmountInfo amountInfo = validateAndCorrectOrderAmounts(dto, cart, storeInfo, table);
-        
-        // 使用验证后的金额
-        BigDecimal totalAmount = amountInfo.getTotalAmount();
-        BigDecimal tablewareFee = amountInfo.getTablewareFee();
-        BigDecimal discountAmount = amountInfo.getDiscountAmount();
-        BigDecimal payAmount = amountInfo.getPayAmount();
+        // 直接使用前端传入的值
+        BigDecimal totalAmount = dto.getTotalAmount() != null ? dto.getTotalAmount() : BigDecimal.ZERO;
+        BigDecimal tablewareFee = dto.getTablewareFee() != null ? dto.getTablewareFee() : BigDecimal.ZERO;
+        BigDecimal discountAmount = dto.getDiscountAmount() != null ? dto.getDiscountAmount() : BigDecimal.ZERO;
+        BigDecimal payAmount = dto.getPayAmount() != null ? dto.getPayAmount() : BigDecimal.ZERO;
         
         // 验证优惠券(可选,couponId 可以为 null)
-        // 注意:订单总金额、优惠金额、实付金额都由前端计算并传入,后端验证其正确性
-        LifeDiscountCoupon coupon = null; // 缓存优惠券对象,避免重复查询
+        // 注意:订单总金额、优惠金额、实付金额都由前端计算并传入,后端不再验证
+        LifeDiscountCoupon coupon = null;
         
         if (dto.getCouponId() != null) {
-            // 如果使用了优惠券,必须传入优惠金额
-            if (discountAmount == null || discountAmount.compareTo(BigDecimal.ZERO) < 0) {
-                throw new RuntimeException("使用优惠券时必须传入优惠金额");
-            }
-            
             // 检查桌号是否已使用优惠券,如果已使用则替换为新优惠券
             if (cartService.hasUsedCoupon(dto.getTableId())) {
                 // 获取旧的优惠券使用记录
@@ -217,45 +171,13 @@ public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOr
                 throw new RuntimeException("优惠券不属于该门店");
             }
 
-            // 验证前端计算的优惠金额是否合理(防止前端计算错误)
-            BigDecimal totalWithTableware = totalAmount.add(tablewareFee);
-            BigDecimal expectedDiscountAmount = calculateDiscountAmount(coupon, totalWithTableware);
-            
-            // 保存前端传入的实付金额(优先使用前端传入的值)
-            BigDecimal frontendPayAmount = payAmount;
-            
-            // 验证并纠正优惠金额
-            discountAmount = validateAndCorrectAmount(
-                    discountAmount, 
-                    expectedDiscountAmount, 
-                    "优惠金额"
-            );
-            
-            // 如果优惠金额被纠正了,重新计算实付金额用于验证
-            // 但始终优先使用前端传入的实付金额
-            BigDecimal recalculatedPayAmount = totalAmount.add(tablewareFee).subtract(discountAmount);
-            if (frontendPayAmount != null) {
-                // 如果前端传入了实付金额,验证其是否正确(仅用于记录日志)
-                BigDecimal payAmountDifference = frontendPayAmount.subtract(recalculatedPayAmount).abs();
-                if (payAmountDifference.compareTo(AMOUNT_TOLERANCE) > 0) {
-                    log.warn("优惠金额纠正后,前端传入的实付金额与重新计算的不一致, frontend={}, recalculated={}, difference={},将使用前端传入的值", 
-                            frontendPayAmount, recalculatedPayAmount, payAmountDifference);
-                }
-                // 始终使用前端传入的值
-                payAmount = frontendPayAmount;
-            } else {
-                // 如果前端没有传入实付金额,使用重新计算的值
-                payAmount = recalculatedPayAmount;
-            }
-
             // 标记桌号已使用新优惠券
             cartService.markCouponUsed(dto.getTableId(), dto.getCouponId());
         } else {
-            // 如果没有使用优惠券,优惠金额应该为0
-            if (discountAmount != null && discountAmount.compareTo(BigDecimal.ZERO) != 0) {
-                throw new RuntimeException("未使用优惠券时,优惠金额必须为0");
+            // 直接使用前端传入的值,如果为null则设为0
+            if (discountAmount == null) {
+                discountAmount = BigDecimal.ZERO;
             }
-            discountAmount = BigDecimal.ZERO;
         }
 
         Date now = new Date();
@@ -1860,40 +1782,6 @@ public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOr
         return "ORD" + timestamp + String.format("%04d", Integer.parseInt(random));
     }
 
-    /**
-     * 计算餐具费(从门店信息获取)
-     *
-     * @param storeInfo  门店信息
-     * @param dinerCount 就餐人数
-     * @return 餐具费总额
-     */
-    private BigDecimal calculateTablewareFee(StoreInfo storeInfo, Integer dinerCount) {
-        if (storeInfo == null) {
-            log.warn("门店信息为空,返回默认餐具费 0.00");
-            return BigDecimal.ZERO;
-        }
-
-        Integer tablewareFee = storeInfo.getTablewareFee();
-        if (tablewareFee == null || tablewareFee < 0) {
-            log.warn("门店餐具费未设置或无效, storeId={}, tablewareFee={},返回默认餐具费 0.00", 
-                    storeInfo.getId(), tablewareFee);
-            return BigDecimal.ZERO;
-        }
-
-        if (dinerCount == null || dinerCount <= 0) {
-            log.warn("就餐人数无效, dinerCount={},返回默认餐具费 0.00", dinerCount);
-            return BigDecimal.ZERO;
-        }
-
-        // tablewareFee 是单价(元),乘以就餐人数得到总费用
-        BigDecimal unitPrice = BigDecimal.valueOf(tablewareFee);
-        BigDecimal totalFee = unitPrice.multiply(BigDecimal.valueOf(dinerCount));
-        
-        log.info("计算餐具费, storeId={}, unitPrice={}, dinerCount={}, totalFee={}", 
-                storeInfo.getId(), unitPrice, dinerCount, totalFee);
-        
-        return totalFee;
-    }
 
     @Override
     public void migrateTableData(Integer fromTableId, Integer toTableId, Integer userId) {
@@ -2111,94 +1999,4 @@ public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOr
         return discountAmount;
     }
 
-    /**
-     * 验证并纠正前端传入的订单金额
-     * 包括:订单总金额、餐具费、优惠金额、实付金额
-     *
-     * @param dto       创建订单DTO
-     * @param cart      购物车信息
-     * @param storeInfo 门店信息
-     * @param table     餐桌信息
-     * @return 验证并纠正后的订单金额信息
-     */
-    private OrderAmountInfo validateAndCorrectOrderAmounts(
-            CreateOrderDTO dto, 
-            CartDTO cart, 
-            StoreInfo storeInfo, 
-            StoreTable table) {
-        
-        // 1. 获取前端传入的金额(如果为null则使用默认值)
-        BigDecimal frontendTotalAmount = dto.getTotalAmount() != null 
-                ? dto.getTotalAmount() 
-                : cart.getTotalAmount();
-        BigDecimal frontendTablewareFee = dto.getTablewareFee() != null 
-                ? dto.getTablewareFee() 
-                : BigDecimal.ZERO;
-        BigDecimal frontendDiscountAmount = dto.getDiscountAmount() != null 
-                ? dto.getDiscountAmount() 
-                : BigDecimal.ZERO;
-        BigDecimal frontendPayAmount = dto.getPayAmount();
-
-        // 2. 计算后端验证值
-        BigDecimal backendTotalAmount = cart.getTotalAmount();
-        BigDecimal backendTablewareFee = calculateTablewareFee(storeInfo, dto.getDinerCount());
-
-        // 3. 验证并纠正订单总金额
-        BigDecimal totalAmount = validateAndCorrectAmount(
-                frontendTotalAmount,
-                backendTotalAmount,
-                "订单总金额"
-        );
-
-        // 4. 验证并纠正餐具费
-        BigDecimal tablewareFee = validateAndCorrectAmount(
-                frontendTablewareFee,
-                backendTablewareFee,
-                "餐具费"
-        );
-
-        // 5. 计算期望的实付金额(订单总金额 + 餐具费 - 优惠金额)
-        BigDecimal expectedPayAmount = totalAmount.add(tablewareFee).subtract(frontendDiscountAmount);
-
-        // 6. 验证并纠正实付金额
-        BigDecimal payAmount = frontendPayAmount != null
-                ? validateAndCorrectAmount(frontendPayAmount, expectedPayAmount, "实付金额")
-                : expectedPayAmount;
-
-        // 7. 返回验证后的金额信息
-        return new OrderAmountInfo(totalAmount, tablewareFee, frontendDiscountAmount, payAmount);
-    }
-
-    /**
-     * 验证并纠正金额
-     * 如果前端金额与后端计算金额的误差超过阈值,则使用后端计算的金额
-     *
-     * @param frontendAmount 前端传入的金额
-     * @param backendAmount  后端计算的金额
-     * @param amountName     金额名称(用于日志)
-     * @return 验证并纠正后的金额
-     */
-    private BigDecimal validateAndCorrectAmount(
-            BigDecimal frontendAmount, 
-            BigDecimal backendAmount, 
-            String amountName) {
-        
-        if (frontendAmount == null || backendAmount == null) {
-            log.warn("{}验证失败:前端金额或后端金额为null, frontend={}, backend={}", 
-                    amountName, frontendAmount, backendAmount);
-            return backendAmount != null ? backendAmount : BigDecimal.ZERO;
-        }
-
-        BigDecimal difference = frontendAmount.subtract(backendAmount).abs();
-        
-        if (difference.compareTo(AMOUNT_TOLERANCE) > 0) {
-            log.warn("前端计算的{}与后端计算不一致, frontend={}, backend={}, difference={}", 
-                    amountName, frontendAmount, backendAmount, difference);
-            // 使用后端计算的金额,确保数据准确性
-            return backendAmount;
-        }
-
-        // 误差在允许范围内,使用前端金额
-        return frontendAmount;
-    }
 }