diff --git a/hiver-admin/test-output/test-report.html b/hiver-admin/test-output/test-report.html index 42f2d819..01a92d74 100644 --- a/hiver-admin/test-output/test-report.html +++ b/hiver-admin/test-output/test-report.html @@ -35,7 +35,7 @@ Hiver
  • -六月 27, 2026 17:16:55 +六月 28, 2026 16:54:23
  • @@ -84,7 +84,7 @@

    passTest

    -

    17:16:55 下午 / 0.037 secs

    +

    16:54:23 下午 / 0.026 secs

    @@ -92,9 +92,9 @@
    #test-id=1
    passTest
    -06.27.2026 17:16:55 -06.27.2026 17:16:55 -0.037 secs +06.28.2026 16:54:23 +06.28.2026 16:54:23 +0.026 secs
    @@ -104,7 +104,7 @@ Pass - 17:16:55 + 16:54:23 Test passed @@ -128,13 +128,13 @@

    Started

    -

    六月 27, 2026 17:16:55

    +

    六月 28, 2026 16:54:23

    Ended

    -

    六月 27, 2026 17:16:55

    +

    六月 28, 2026 16:54:23

    diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminSeckillGroupController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminSeckillGroupController.java index a59c9bbe..c3c58546 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminSeckillGroupController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminSeckillGroupController.java @@ -32,6 +32,7 @@ import java.util.List; public class AdminSeckillGroupController { public static final String GROUP_DELIVERY_TIME_KEY_PREFIX = "GROUP_DELIVERY_TIME:"; + public static final String GROUP_CUSTOMER_PHONE_KEY_PREFIX = "GROUP_CUSTOMER_PHONE:"; public static final int DEFAULT_GROUP_DELIVERY_TIME = 30; @Autowired @@ -62,6 +63,25 @@ public class AdminSeckillGroupController { return new ResultUtil().setData(getDeliveryTimeByRegionId(redisTemplateHelper, regionId)); } + @RequestMapping(value = "/customerPhone/save", method = RequestMethod.POST) + @ApiOperation(value = "淇濆瓨鍖哄煙瀹㈡湇鐢佃瘽") + public Result saveCustomerPhone(@RequestBody CustomerPhoneSetting setting) { + if (setting == null || StringUtils.isBlank(setting.getRegionId())) { + return ResultUtil.error("鍖哄煙ID涓嶈兘涓虹┖"); + } + if (StringUtils.isBlank(setting.getCustomerPhone())) { + return ResultUtil.error("瀹㈡湇鐢佃瘽涓嶈兘涓虹┖"); + } + redisTemplateHelper.set(buildCustomerPhoneKey(setting.getRegionId()), setting.getCustomerPhone().trim()); + return ResultUtil.success("淇濆瓨鎴愬姛"); + } + + @RequestMapping(value = "/customerPhone/get", method = RequestMethod.GET) + @ApiOperation(value = "鏌ヨ鍖哄煙瀹㈡湇鐢佃瘽") + public Result getCustomerPhone(@RequestParam(value = "regionId") String regionId) { + return new ResultUtil().setData(getCustomerPhoneByRegionId(redisTemplateHelper, regionId)); + } + public static Integer getDeliveryTimeByRegionId(RedisTemplateHelper redisTemplateHelper, String regionId) { if (redisTemplateHelper == null || StringUtils.isBlank(regionId)) { return DEFAULT_GROUP_DELIVERY_TIME; @@ -77,6 +97,14 @@ public class AdminSeckillGroupController { } } + public static String getCustomerPhoneByRegionId(RedisTemplateHelper redisTemplateHelper, String regionId) { + if (redisTemplateHelper == null || StringUtils.isBlank(regionId)) { + return ""; + } + String value = redisTemplateHelper.get(buildCustomerPhoneKey(regionId)); + return StringUtils.isBlank(value) ? "" : value; + } + public static Integer getTotalDeliveryTimeByRegionIdAndShopId(RedisTemplateHelper redisTemplateHelper, String regionId, String shopId) { return getShopCookingTimeByRegionIdAndShopId(redisTemplateHelper, regionId, shopId) + getDeliveryTimeByRegionId(redisTemplateHelper, regionId); @@ -105,6 +133,10 @@ public class AdminSeckillGroupController { return GROUP_DELIVERY_TIME_KEY_PREFIX + regionId; } + public static String buildCustomerPhoneKey(String regionId) { + return GROUP_CUSTOMER_PHONE_KEY_PREFIX + regionId; + } + public static class DeliveryTimeSetting { private String regionId; private Integer deliveryTime; @@ -126,6 +158,27 @@ public class AdminSeckillGroupController { } } + public static class CustomerPhoneSetting { + private String regionId; + private String customerPhone; + + public String getRegionId() { + return regionId; + } + + public void setRegionId(String regionId) { + this.regionId = regionId; + } + + public String getCustomerPhone() { + return customerPhone; + } + + public void setCustomerPhone(String customerPhone) { + this.customerPhone = customerPhone; + } + } + @RequestMapping(value = "/category/save", method = RequestMethod.POST) @ApiOperation(value = "鏂板绉掓潃鍥㈠垎绫") public Result saveCategory(@RequestBody SeckillGroupCategory category) { diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/UserAddressController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/UserAddressController.java index 5f4d3ea7..16e407dd 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/UserAddressController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/UserAddressController.java @@ -88,6 +88,16 @@ public class UserAddressController { List list = userAddressService.getAddressListByUserId(userId); return new ResultUtil>().setData(list); } + + @RequestMapping(value = "/get", method = RequestMethod.GET) + @ApiOperation(value = "鏍规嵁ID鑾峰彇鐢ㄦ埛鏀惰揣鍦板潃") + public Result get(@RequestParam("id") String id) { + if (StringUtils.isBlank(id)) { + return ResultUtil.error("鍦板潃ID涓嶈兘涓虹┖"); + } + UserAddress address = userAddressService.getById(id); + return new ResultUtil().setData(address); + } @RequestMapping(value = "/setDefault", method = RequestMethod.POST) @ApiOperation(value = "璁剧疆榛樿鏀惰揣鍦板潃") diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/WechatPayController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/WechatPayController.java index e378bef2..ec8fe6b2 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/WechatPayController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/WechatPayController.java @@ -5,6 +5,7 @@ import cc.hiver.mall.service.mybatis.MallDeliveryOrderService; import cc.hiver.mall.service.mybatis.MallOrderService; import cc.hiver.mall.serviceimpl.UnifiedOrderService; import cc.hiver.mall.utils.KeyUtils; +import cc.hiver.mall.utils.MallOrderDeliveryFeeRefundHelper; import cc.hiver.mall.utils.WechatPayConfig; import cc.hiver.mall.utils.WechatPaySigner; import com.fasterxml.jackson.databind.ObjectMapper; @@ -18,10 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.annotation.PostConstruct; import java.io.ByteArrayOutputStream; @@ -57,6 +55,9 @@ public class WechatPayController { @Autowired private MallDeliveryOrderService mallDeliveryOrderService; + @Autowired + private MallOrderDeliveryFeeRefundHelper mallOrderDeliveryFeeRefundHelper; + @Autowired private WechatPaySigner signer; @@ -133,10 +134,21 @@ public class WechatPayController { // 2. 鐢熸垚鍓嶇鏀粯鍙傛暟 Map payParams = buildPaySign(prepayId); payParams.put("code","200"); + if(description.equals("澧炲姞閰嶉佷剑閲")){ + payParams.put("wxOrderId", outTradeNo); + } return ResponseEntity.ok(payParams); } } + @GetMapping("/delivery-fee-record/exists") + public ResponseEntity> existsDeliveryFeeRecord(@RequestParam String wxOrderId) { + Map result = new HashMap<>(); + result.put("code", "200"); + result.put("exists", String.valueOf(mallOrderDeliveryFeeRefundHelper.existsAddedDeliveryFee(wxOrderId))); + return ResponseEntity.ok(result); + } + /** * 寰俊鏀粯寮傛鍥炶皟閫氱煡鎺ュ彛 (API v3) * 寰俊鏈嶅姟鍣ㄤ細鍦ㄦ敮浠樻垚鍔熷悗 POST 璇锋眰璇ユ帴鍙 diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallRefundRecord.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallRefundRecord.java index 19b39b2d..5c1a0989 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallRefundRecord.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallRefundRecord.java @@ -36,6 +36,8 @@ public class MallRefundRecord implements Serializable { private BigDecimal refundAmount; @ApiModelProperty(value = "閫娆惧師鍥") private String reason; + @ApiModelProperty(value = "鎷掔粷鍘熷洜") + private String rejectReason; @ApiModelProperty(value = "鍖哄煙id") private String regionId; @ApiModelProperty(value = "閫娆惧浘鐗") diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/mq/OrderDelayConsumer.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/mq/OrderDelayConsumer.java index c62913f2..1e2219e1 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/mq/OrderDelayConsumer.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/mq/OrderDelayConsumer.java @@ -86,6 +86,9 @@ public class OrderDelayConsumer { case "Shop_Cook_Timeout": handleShopCookTimeout(orderId); break; + case "Appointment_Shop_Cook_Notify": + handleAppointmentShopCookNotify(orderId); + break; case "Transfer_Arrive_Timeout": handleTransferArriveTimeout(orderId); break; @@ -221,6 +224,22 @@ public class OrderDelayConsumer { } } + private void handleAppointmentShopCookNotify(String orderId) { + MallOrder order = mallOrderMapper.selectById(orderId); + if (order == null || order.getShopMakeTime() != null || order.getStatus() == null || order.getStatus() >= 4) { + return; + } + MallDeliveryOrder delivery = getDeliveryOrder(orderId); + if (delivery == null || !Integer.valueOf(1).equals(delivery.getAppointmentDelivery())) { + return; + } + log.info("銆愯鍗曞欢鏃跺鐞嗐戦绾﹂厤閫佽鍗曞埌杈惧彲鍑洪鏃堕棿锛屽悜鍟嗗鍙戦佹瀬鍏夋帹閫 orderId={}", orderId); + Shop shop = shopMapper.selectById(order.getShopId()); + if (shop != null && StringUtils.isNotBlank(shop.getClientId())) { + jPushService.sendPushNotification(shop.getClientId(), "鎮ㄦ湁涓绗旈绾﹁鍗曞彲浠ュ嚭椁愬暒锛", orderId); + } + } + private void handleTransferArriveTimeout(String orderId) { MallDeliveryOrder delivery = getDeliveryOrder(orderId); if (delivery == null || !Integer.valueOf(1).equals(delivery.getTransferDelivery()) 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 4faf35c2..68ced18f 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 @@ -189,22 +189,24 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl orderIds, MallOrder knownOrder, MallDeliveryOrder delivery) { + if (orderIds == null || orderIds.isEmpty() || delivery == null || delivery.getMustFinishTime() == null) { + return; + } + String regionId = StringUtils.defaultIfBlank(delivery.getRegionId(), knownOrder == null ? null : knownOrder.getRegionId()); + String shopId = StringUtils.defaultIfBlank(delivery.getShopId(), knownOrder == null ? null : knownOrder.getShopId()); + boolean transferDelivery = Integer.valueOf(1).equals(delivery.getTransferDelivery()) + || (knownOrder != null && Integer.valueOf(1).equals(knownOrder.getTransferDelivery())); + int deliveryMinutes = safeMinutes(getSchoolDeliveryTime(regionId, shopId, delivery.getDeliveryType())); + if (transferDelivery) { + deliveryMinutes += safeMinutes(getTransferDeliveryDuration(regionId, shopId)); + } + int cookMinutes = safeMinutes(getCookingTime(regionId, shopId)); + long notifyTimeMillis = delivery.getMustFinishTime().getTime() - (long) (deliveryMinutes + cookMinutes) * 60 * 1000L; + long delayMillis = Math.max(1000L, notifyTimeMillis - System.currentTimeMillis()); + for (String id : orderIds) { + orderAsyncProducer.sendDelayMessage(id, "Appointment_Shop_Cook_Notify", delayMillis); + } + } + /** * 閰嶉佸憳鍙栬揣锛堢姸鎬侊細寰呭彇璐 -> 閰嶉佷腑锛 */ diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java index 076ce5a9..7f7b9e88 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java @@ -616,7 +616,7 @@ public class MallOrderServiceImpl extends ServiceImpl allGoods = mallOrderGoodsMapper.selectPagesByOrderIds(orderIds); + List allDeliveryOrders = mallDeliveryOrderMapper.selectByOrderIds(orderIds); + if (allGoods == null) { + allGoods = java.util.Collections.emptyList(); + } + if (allDeliveryOrders == null) { + allDeliveryOrders = java.util.Collections.emptyList(); + } // 3. 鎸 orderId 鍒嗙粍 java.util.Map> goodsMap = allGoods.stream() .collect(java.util.stream.Collectors.groupingBy(MallOrderGoods::getOrderId)); + java.util.Map deliveryMap = allDeliveryOrders.stream() + .filter(delivery -> StringUtils.isNotBlank(delivery.getOrderId())) + .collect(java.util.stream.Collectors.toMap( + MallDeliveryOrder::getOrderId, + delivery -> delivery, + (first, second) -> first + )); // 4. 缁勮鍒版瘡涓 VO for (MallOrderVO vo : records) { vo.setGoodsList(goodsMap.getOrDefault(vo.getId(), java.util.Collections.emptyList())); + vo.setDeliveryInfo(deliveryMap.get(vo.getId())); } } @@ -1874,9 +1889,14 @@ public class MallOrderServiceImpl extends ServiceImpl uw = new LambdaUpdateWrapper<>(); uw.eq(MallRefundRecord::getId, mallRefundRecord.getId()) .set(MallRefundRecord::getSuccessTime, new Date()) + .set(rejectStatus, MallRefundRecord::getRejectReason, rejectReason) .set(MallRefundRecord::getStatus, mallRefundRecord.getStatus()); this.update(null, uw); //缂撳瓨鍘绘帀 diff --git a/hiver-modules/hiver-mall/src/main/resources/db/mall_refund_record_reject_reason.sql b/hiver-modules/hiver-mall/src/main/resources/db/mall_refund_record_reject_reason.sql new file mode 100644 index 00000000..07a7ee72 --- /dev/null +++ b/hiver-modules/hiver-mall/src/main/resources/db/mall_refund_record_reject_reason.sql @@ -0,0 +1,2 @@ +ALTER TABLE `mall_refund_record` + ADD COLUMN `reject_reason` varchar(255) DEFAULT NULL COMMENT '鎷掔粷鍘熷洜' AFTER `reason`; diff --git a/hiver-modules/hiver-mall/src/main/resources/mapper/MallRefundRecordMapper.xml b/hiver-modules/hiver-mall/src/main/resources/mapper/MallRefundRecordMapper.xml index 288fd33e..fe539fb1 100644 --- a/hiver-modules/hiver-mall/src/main/resources/mapper/MallRefundRecordMapper.xml +++ b/hiver-modules/hiver-mall/src/main/resources/mapper/MallRefundRecordMapper.xml @@ -9,6 +9,7 @@ +