diff --git a/hiver-admin/test-output/test-report.html b/hiver-admin/test-output/test-report.html index c286d0d1..2c238866 100644 --- a/hiver-admin/test-output/test-report.html +++ b/hiver-admin/test-output/test-report.html @@ -35,7 +35,7 @@ Hiver
  • -ÁùÔÂ 19, 2026 13:55:31 +ÁùÔÂ 21, 2026 16:41:05
  • @@ -84,7 +84,7 @@

    passTest

    -

    13:55:31 ÏÂÎç / 0.022 secs

    +

    16:41:06 ÏÂÎç / 0.024 secs

    @@ -92,9 +92,9 @@
    #test-id=1
    passTest
    -06.19.2026 13:55:31 -06.19.2026 13:55:31 -0.022 secs +06.21.2026 16:41:06 +06.21.2026 16:41:06 +0.024 secs
    @@ -104,7 +104,7 @@ Pass - 13:55:31 + 16:41:06 Test passed @@ -128,13 +128,13 @@

    Started

    -

    ÁùÔÂ 19, 2026 13:55:31

    +

    ÁùÔÂ 21, 2026 16:41:05

    Ended

    -

    ÁùÔÂ 19, 2026 13:55:31

    +

    ÁùÔÂ 21, 2026 16:41:06

    diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java index 8462b7c5..f220981a 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java @@ -464,6 +464,8 @@ public class MallDeliveryOrderController { Integer result = mallDeliveryOrderService.rejectDelivery(deliveryId); if(result == -1){ return ResultUtil.error("ä»Šæ—¥æ‹’å•æ¬¡æ•°å·²è¾¾ä¸Šé™ï¼Œæ— æ³•ç»§ç»­æ‹’å•ï¼"); + }else if(result == -2){ + return ResultUtil.success("预约é…é€å•æ‹’å•æˆåŠŸï¼Œä¸è®¡å…¥ä»Šæ—¥æ‹’啿¬¡æ•°"); }else{ return ResultUtil.success("æ‹’å•æˆåŠŸï¼ä»Šæ—¥å‰©ä½™æ‹’啿¬¡æ•°ï¼š" + result); } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallDeliveryOrder.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallDeliveryOrder.java index bdd794e7..cb0f8db4 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallDeliveryOrder.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallDeliveryOrder.java @@ -75,6 +75,8 @@ public class MallDeliveryOrder implements Serializable { private Date getTime; @ApiModelProperty(value = "å®¢æˆ·è¦æ±‚é€è¾¾æ—¶é—´") private Date mustFinishTime; + @ApiModelProperty(value = "是å¦é¢„约é…é€ 0å¦ 1是") + private Integer appointmentDelivery; @ApiModelProperty(value = "到店时间") private Date arriveTime; @ApiModelProperty(value = "é€è¾¾æ—¶é—´") diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallReturnOrderGoods.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallReturnOrderGoods.java index b8e28748..8ecb09a4 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallReturnOrderGoods.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallReturnOrderGoods.java @@ -34,6 +34,8 @@ public class MallReturnOrderGoods implements Serializable { private String specs; @ApiModelProperty(value = "商å“å•ä»·") private BigDecimal price; + @ApiModelProperty(value = "商å“é¤ç›’è´¹") + private BigDecimal packageFee; @ApiModelProperty(value = "商哿•°é‡") private Integer quantity; } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/dto/CreateOrderDTO.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/dto/CreateOrderDTO.java index cdc06e8a..43de1573 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/dto/CreateOrderDTO.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/dto/CreateOrderDTO.java @@ -57,6 +57,9 @@ public class CreateOrderDTO { @ApiModelProperty(value = "è¦æ±‚é€è¾¾æ—¶é—´ï¼ˆé¢„约é…逿—¶å¡«å†™ï¼‰") private Date mustFinishTime; + @ApiModelProperty(value = "是å¦é¢„约é…é€ 0å¦ 1是") + private Integer appointmentDelivery; + @ApiModelProperty(value = "加入已有拼团时传入groupId") private String groupId; diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java index 4d9e99bc..1c9d324b 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java @@ -266,10 +266,13 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl uw = new LambdaUpdateWrapper<>(); @@ -305,8 +310,10 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl uw = new LambdaUpdateWrapper<>(); uw.eq(MallDeliveryOrder::getId, deliveryId) .set(MallDeliveryOrder::getWorkerId, null).set(MallDeliveryOrder::getWorkerName, (String)null) diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderGroupServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderGroupServiceImpl.java index 2b83ecde..028d1737 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderGroupServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderGroupServiceImpl.java @@ -241,8 +241,22 @@ public class MallOrderGroupServiceImpl extends ServiceImpl duw = new LambdaUpdateWrapper<>(); + duw.eq(MallDeliveryOrder::getId, delivery.getId()) + .set(MallDeliveryOrder::getStatus, delivery.getStatus()) + .set(MallDeliveryOrder::getCreateTime, createTime) + .set(MallDeliveryOrder::getWorkerId, delivery.getWorkerId()) + .set(MallDeliveryOrder::getWorkerPhone, delivery.getWorkerPhone()) + .set(MallDeliveryOrder::getWorkerName, delivery.getWorkerName()); + if (!appointmentDelivery) { + duw.set(MallDeliveryOrder::getMustFinishTime, mustFinishTime); + } + mallDeliveryOrderMapper.update(null, duw); //抢å•大厅缓存 if (isFace2Face) { // é¢å¯¹é¢å›¢æŸ¥æ‰€æœ‰äººè®¢å•ï¼›ä¿æŒåŽŸæœ‰æŸ¥è¯¢æ¡ä»¶ï¼Œä¾èµ–ä¸Šæ–¹å…ˆå®Œæˆæ•´å›¢çŠ¶æ€æ¿€æ´»ã€‚ @@ -310,7 +324,10 @@ public class MallOrderGroupServiceImpl extends ServiceImpl qw = new LambdaQueryWrapper<>(); qw.eq(MallDeliveryOrder::getOrderId, orderId); MallDeliveryOrder deliveryOrder = mallDeliveryOrderMapper.selectOne(qw); - Date mustFinishTime = calculateActivatedMustFinishTime(order, deliveryOrder); + boolean appointmentDelivery = deliveryOrder != null && Integer.valueOf(1).equals(deliveryOrder.getAppointmentDelivery()); + Date mustFinishTime = appointmentDelivery ? deliveryOrder.getMustFinishTime() : calculateActivatedMustFinishTime(order, deliveryOrder); LambdaUpdateWrapper duw = new LambdaUpdateWrapper<>(); duw.eq(MallDeliveryOrder::getOrderId, orderId) - .set(MallDeliveryOrder::getStatus, 0).set(MallDeliveryOrder::getCreateTime, createTime).set(MallDeliveryOrder::getMustFinishTime, mustFinishTime); + .set(MallDeliveryOrder::getStatus, 0).set(MallDeliveryOrder::getCreateTime, createTime); + if (!appointmentDelivery) { + duw.set(MallDeliveryOrder::getMustFinishTime, mustFinishTime); + } mallDeliveryOrderMapper.update(null, duw); //抢å•大厅缓存 if (deliveryOrder != null) { deliveryOrder.setStatus(0); deliveryOrder.setCreateTime(createTime); - deliveryOrder.setMustFinishTime(mustFinishTime); + if (!appointmentDelivery) { + deliveryOrder.setMustFinishTime(mustFinishTime); + } } List goodsList = mallOrderGoodsMapper.selectByOrderId(orderId); if (deliveryOrder != null) { @@ -706,6 +712,7 @@ public class MallOrderServiceImpl extends ServiceImpl uq = new LambdaQueryWrapper<>(); - uq.eq(MallUserCoupon::getOrderId, record.getOrderId()); + uq.eq(MallUserCoupon::getOrderId, order.getId()); List coupons = mallUserCouponMapper.selectList(uq); - //è®¡ç®—å·²ç»“ç®—è®¢å• å•†å®¶åŒæ„å”®åŽæ—¶ï¼ŒæŒ‰ç…§å•†å“原价-抽佣金é¢ç»™å•†å®¶åР䏀æ¡è´Ÿæ•°å¾…结算记录, - // 未结算的订å•结算时需è¦å…³è”æ˜¯å¦æœ‰å”®åŽå‡æŽ‰å”®åŽé‡‘é¢ å•†å®¶éœ€è¦æœ‰è´¦å•结算记录 - //é…é€å‘˜åŒæ„å”®åŽæ—¶éœ€è¦åœ¨ä»–的账户余é¢å‡é€€æ¬¾é‡‘é¢ï¼Œè®¢å•é…é€å®Œæˆç»™åŠ é’± - if(coupons != null && coupons.size() > 0){ - BigDecimal totalCoupons = coupons.stream() - .map(item -> item.getDiscountAmount()) // æå– BigDecimal é‡‘é¢ + + BigDecimal ratio = null; + // 4. 分别计算优惠券总é¢å’Œå…å•é‡‘é¢ + BigDecimal totalCoupons = BigDecimal.ZERO; + if (coupons != null && !coupons.isEmpty()) { + totalCoupons = coupons.stream() + .map(MallUserCoupon::getDiscountAmount) .reduce(BigDecimal.ZERO, BigDecimal::add); - BigDecimal allAmount = amount.add(totalCoupons); - //计算比例 - ratio = totalCoupons.divide(allAmount, 4, RoundingMode.HALF_UP); + } + + // 获å–å…å•金é¢ï¼Œé˜²æ­¢ç©ºæŒ‡é’ˆ + BigDecimal freeAmount = order.getFreeAmount() != null ? order.getFreeAmount() : BigDecimal.ZERO; + + // 5. 分开判断并计算比例 + // åªè¦å­˜åœ¨ä¼˜æƒ åˆ¸æŠµæ‰£æˆ–å…å•金é¢ï¼Œå°±éœ€è¦è®¡ç®—比例 + if (totalCoupons.compareTo(BigDecimal.ZERO) > 0 || freeAmount.compareTo(BigDecimal.ZERO) > 0) { + BigDecimal allAmount = order.getTotalAmount() + .add(freeAmount) + .add(totalCoupons); + + // 防止除以 0 的异常 + if (allAmount.compareTo(BigDecimal.ZERO) > 0) { + ratio = totalCoupons.add(freeAmount) + .divide(allAmount, 4, RoundingMode.HALF_UP); + } } // å…¨é¢é€€æ¬¾ if(refundType == 3){ @@ -1988,6 +2013,7 @@ public class MallOrderServiceImpl extends ServiceImpl oUw = new LambdaUpdateWrapper<>(); oUw.eq(MallOrder::getId, mallRefundRecord.getOrderId()) .set(MallOrder::getStatus, 11); - mallOrderService.update(oUw); + // 注æ„:Service 层的 update 方法通常需è¦ä¼ å…¥å®žä½“对象,若åªä¼  Wrapper å¯èƒ½ä¼šæŠ¥é”™ï¼Œå»ºè®®ä¼  null + mallOrderService.update(null, oUw); + + // 2. 查询关è”的优惠券 + LambdaQueryWrapper uq = new LambdaQueryWrapper<>(); + uq.eq(MallUserCoupon::getOrderId, mallRefundRecord.getOrderId()); + List coupons = mallUserCouponMapper.selectList(uq); + + // 3. 釿–°èŽ·å–æœ€æ–°è®¢å•ä¿¡æ¯ MallOrder order = mallOrderService.getById(mallRefundRecord.getOrderId()); + BigDecimal ratio = null; - LambdaQueryWrapper uq = new LambdaQueryWrapper<>(); - uq.eq(MallUserCoupon::getOrderId, mallRefundRecord.getOrderId()); - List coupons = mallUserCouponMapper.selectList(uq); - //è®¡ç®—å·²ç»“ç®—è®¢å• å•†å®¶åŒæ„å”®åŽæ—¶ï¼ŒæŒ‰ç…§å•†å“原价-抽佣金é¢ç»™å•†å®¶åР䏀æ¡è´Ÿæ•°å¾…结算记录, - // 未结算的订å•结算时需è¦å…³è”æ˜¯å¦æœ‰å”®åŽå‡æŽ‰å”®åŽé‡‘é¢ å•†å®¶éœ€è¦æœ‰è´¦å•结算记录 - //é…é€å‘˜åŒæ„å”®åŽæ—¶éœ€è¦åœ¨ä»–的账户余é¢å‡é€€æ¬¾é‡‘é¢ï¼Œè®¢å•é…é€å®Œæˆç»™åŠ é’± - if(coupons != null && coupons.size() > 0){ - BigDecimal totalCoupons = coupons.stream() - .map(item -> item.getDiscountAmount()) // æå– BigDecimal é‡‘é¢ + // 4. 分别计算优惠券总é¢å’Œå…å•é‡‘é¢ + BigDecimal totalCoupons = BigDecimal.ZERO; + if (coupons != null && !coupons.isEmpty()) { + totalCoupons = coupons.stream() + .map(MallUserCoupon::getDiscountAmount) .reduce(BigDecimal.ZERO, BigDecimal::add); - BigDecimal allAmount = mallRefundRecord.getTotalAmount().add(totalCoupons); - //计算比例 - ratio = totalCoupons.divide(allAmount, 4, RoundingMode.HALF_UP); + } + + // 获å–å…å•金é¢ï¼Œé˜²æ­¢ç©ºæŒ‡é’ˆ + BigDecimal freeAmount = order.getFreeAmount() != null ? order.getFreeAmount() : BigDecimal.ZERO; + + // 5. 分开判断并计算比例 + // åªè¦å­˜åœ¨ä¼˜æƒ åˆ¸æŠµæ‰£æˆ–å…å•金é¢ï¼Œå°±éœ€è¦è®¡ç®—比例 + if (totalCoupons.compareTo(BigDecimal.ZERO) > 0 || freeAmount.compareTo(BigDecimal.ZERO) > 0) { + BigDecimal allAmount = mallRefundRecord.getTotalAmount() + .add(freeAmount) + .add(totalCoupons); + + // 防止除以 0 的异常 + if (allAmount.compareTo(BigDecimal.ZERO) > 0) { + ratio = totalCoupons.add(freeAmount) + .divide(allAmount, 4, RoundingMode.HALF_UP); + } } //如果是售åŽå•†å“ ç»™å•†å®¶åŠ ä¸€æ¡ å¦‚æžœæ˜¯é…é€ç»™é…é€å‘˜åŠ ä¸€æ¡ @@ -219,6 +239,7 @@ public class MallRefundRecordServiceImpl extends ServiceImpl qw = new LambdaQueryWrapper<>(); - qw.eq(MallDeliveryOrder::getOrderId, mallRefundRecord.getOrderId()); - MallDeliveryOrder deliveryOrder = mallDeliveryOrderMapper.selectOne(qw); - workerOrderCacheUtil.remove(deliveryOrder.getWorkerId(),deliveryOrder.getId()); + if(mallRefundRecord.getOrderType() == STATUS_WAIT_PICKUP){ + MallDeliveryOrder deliveryOrder = mallDeliveryOrderMapper.selectByGroupId(mallRefundRecord.getOrderId()); + workerOrderCacheUtil.remove(deliveryOrder.getWorkerId(),deliveryOrder.getId()); + }else{ + LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); + qw.eq(MallDeliveryOrder::getOrderId, mallRefundRecord.getOrderId()); + MallDeliveryOrder deliveryOrder = mallDeliveryOrderMapper.selectOne(qw); + workerOrderCacheUtil.remove(deliveryOrder.getWorkerId(),deliveryOrder.getId()); + } } BigDecimal totalRefund = result.getRecords().stream() .map(item -> item.getRefundAmount()) // æå– BigDecimal é‡‘é¢ diff --git a/hiver-modules/hiver-mall/src/main/resources/db/mall_delivery_appointment.sql b/hiver-modules/hiver-mall/src/main/resources/db/mall_delivery_appointment.sql new file mode 100644 index 00000000..16503be1 --- /dev/null +++ b/hiver-modules/hiver-mall/src/main/resources/db/mall_delivery_appointment.sql @@ -0,0 +1,2 @@ +ALTER TABLE mall_delivery_order + ADD COLUMN appointment_delivery TINYINT NOT NULL DEFAULT 0 COMMENT '是å¦é¢„约é…é€ 0å¦ 1是' AFTER must_finish_time; diff --git a/hiver-modules/hiver-mall/src/main/resources/mapper/MallDeliveryOrderMapper.xml b/hiver-modules/hiver-mall/src/main/resources/mapper/MallDeliveryOrderMapper.xml index d590029f..b54123a1 100644 --- a/hiver-modules/hiver-mall/src/main/resources/mapper/MallDeliveryOrderMapper.xml +++ b/hiver-modules/hiver-mall/src/main/resources/mapper/MallDeliveryOrderMapper.xml @@ -24,6 +24,7 @@ + @@ -53,7 +54,7 @@ SELECT d.id, d.order_id, d.group_id, d.worker_id, d.shop_id, d.get_area_id, d.put_area_id, d.delivery_fee, d.delivery_fee_marketplace, - d.status, d.create_time, d.accept_time, d.get_time, d.must_finish_time, d.finish_time, + d.status, d.create_time, d.accept_time, d.get_time, d.must_finish_time, d.appointment_delivery, d.finish_time, d.receiver_name, d.receiver_phone, d.receiver_address, d.shop_name, d.shop_phone, d.shop_address, d.delivery_type, d.number_code, d.region_id,d.remark, d.all_count, d.phone_number, d.get_codes, d.get_pictures, d.is_big, @@ -150,7 +151,7 @@ SELECT d.id, d.order_id, d.group_id, d.worker_id, d.shop_id, d.get_area_id, d.put_area_id, d.delivery_fee, d.delivery_fee_marketplace, - d.status, d.create_time, d.accept_time, d.get_time, d.must_finish_time, d.finish_time, + d.status, d.create_time, d.accept_time, d.get_time, d.must_finish_time, d.appointment_delivery, d.finish_time, d.receiver_name, d.receiver_phone, d.receiver_address, d.shop_name, d.shop_phone, d.shop_address, d.delivery_type, d.number_code, d.region_id,d.remark, d.all_count, d.phone_number, d.get_codes, d.get_pictures, @@ -215,7 +216,7 @@ SELECT d.id, d.order_id, d.group_id, d.worker_id, d.shop_id, d.get_area_id, d.put_area_id, d.delivery_fee, d.delivery_fee_marketplace, - d.status, d.create_time, d.accept_time, d.get_time, d.must_finish_time, d.finish_time, + d.status, d.create_time, d.accept_time, d.get_time, d.must_finish_time, d.appointment_delivery, d.finish_time, d.receiver_name, d.receiver_phone, d.receiver_address, d.shop_name, d.shop_phone, d.shop_address, d.delivery_type, d.number_code, d.region_id,d.remark, d.all_count, d.phone_number, d.get_codes, d.get_pictures, @@ -280,7 +281,7 @@ SELECT d.id, d.order_id, d.group_id, d.worker_id, d.shop_id, d.get_area_id, d.put_area_id, d.delivery_fee, d.delivery_fee_marketplace, - d.status, d.create_time, d.accept_time, d.get_time, d.must_finish_time, d.finish_time, + d.status, d.create_time, d.accept_time, d.get_time, d.must_finish_time, d.appointment_delivery, d.finish_time, d.receiver_name, d.receiver_phone, d.receiver_address, d.shop_name, d.shop_phone, d.shop_address, d.delivery_type, d.number_code, d.region_id,d.remark, d.all_count, d.phone_number, d.get_codes, d.get_pictures,