Browse Source

对接拼团数据1

master
wangfukang 1 month ago
parent
commit
7debc284a9
  1. 16
      hiver-admin/test-output/test-report.html
  2. 53
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/AdminSeckillGroupController.java
  3. 10
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/UserAddressController.java
  4. 20
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/WechatPayController.java
  5. 2
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/MallRefundRecord.java
  6. 19
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/mq/OrderDelayConsumer.java
  7. 67
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java
  8. 50
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java
  9. 7
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallRefundRecordServiceImpl.java
  10. 2
      hiver-modules/hiver-mall/src/main/resources/db/mall_refund_record_reject_reason.sql
  11. 1
      hiver-modules/hiver-mall/src/main/resources/mapper/MallRefundRecordMapper.xml

16
hiver-admin/test-output/test-report.html

@ -35,7 +35,7 @@
<a href="#"><span class="badge badge-primary">Hiver</span></a> <a href="#"><span class="badge badge-primary">Hiver</span></a>
</li> </li>
<li class="m-r-10"> <li class="m-r-10">
<a href="#"><span class="badge badge-primary">六月 27, 2026 17:16:55</span></a> <a href="#"><span class="badge badge-primary">六月 28, 2026 16:54:23</span></a>
</li> </li>
</ul> </ul>
</div> </div>
@ -84,7 +84,7 @@
<div class="test-detail"> <div class="test-detail">
<span class="meta text-white badge badge-sm"></span> <span class="meta text-white badge badge-sm"></span>
<p class="name">passTest</p> <p class="name">passTest</p>
<p class="text-sm"><span>17:16:55 下午</span> / <span>0.037 secs</span></p> <p class="text-sm"><span>16:54:23 下午</span> / <span>0.026 secs</span></p>
</div> </div>
<div class="test-contents d-none"> <div class="test-contents d-none">
<div class="detail-head"> <div class="detail-head">
@ -92,9 +92,9 @@
<div class="info"> <div class="info">
<div class='float-right'><span class='badge badge-default'>#test-id=1</span></div> <div class='float-right'><span class='badge badge-default'>#test-id=1</span></div>
<h5 class="test-status text-pass">passTest</h5> <h5 class="test-status text-pass">passTest</h5>
<span class='badge badge-success'>06.27.2026 17:16:55</span> <span class='badge badge-success'>06.28.2026 16:54:23</span>
<span class='badge badge-danger'>06.27.2026 17:16:55</span> <span class='badge badge-danger'>06.28.2026 16:54:23</span>
<span class='badge badge-default'>0.037 secs</span> <span class='badge badge-default'>0.026 secs</span>
</div> </div>
<div class="m-t-10 m-l-5"></div> <div class="m-t-10 m-l-5"></div>
</div> </div>
@ -104,7 +104,7 @@
<tbody> <tbody>
<tr class="event-row"> <tr class="event-row">
<td><span class="badge log pass-bg">Pass</span></td> <td><span class="badge log pass-bg">Pass</span></td>
<td>17:16:55</td> <td>16:54:23</td>
<td> <td>
Test passed Test passed
</td> </td>
@ -128,13 +128,13 @@
<div class="col-md-3"> <div class="col-md-3">
<div class="card"><div class="card-body"> <div class="card"><div class="card-body">
<p class="m-b-0">Started</p> <p class="m-b-0">Started</p>
<h3>六月 27, 2026 17:16:55</h3> <h3>六月 28, 2026 16:54:23</h3>
</div></div> </div></div>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<div class="card"><div class="card-body"> <div class="card"><div class="card-body">
<p class="m-b-0">Ended</p> <p class="m-b-0">Ended</p>
<h3>六月 27, 2026 17:16:55</h3> <h3>六月 28, 2026 16:54:23</h3>
</div></div> </div></div>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">

53
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 class AdminSeckillGroupController {
public static final String GROUP_DELIVERY_TIME_KEY_PREFIX = "GROUP_DELIVERY_TIME:"; 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; public static final int DEFAULT_GROUP_DELIVERY_TIME = 30;
@Autowired @Autowired
@ -62,6 +63,25 @@ public class AdminSeckillGroupController {
return new ResultUtil<Integer>().setData(getDeliveryTimeByRegionId(redisTemplateHelper, regionId)); return new ResultUtil<Integer>().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<String> getCustomerPhone(@RequestParam(value = "regionId") String regionId) {
return new ResultUtil<String>().setData(getCustomerPhoneByRegionId(redisTemplateHelper, regionId));
}
public static Integer getDeliveryTimeByRegionId(RedisTemplateHelper redisTemplateHelper, String regionId) { public static Integer getDeliveryTimeByRegionId(RedisTemplateHelper redisTemplateHelper, String regionId) {
if (redisTemplateHelper == null || StringUtils.isBlank(regionId)) { if (redisTemplateHelper == null || StringUtils.isBlank(regionId)) {
return DEFAULT_GROUP_DELIVERY_TIME; 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) { public static Integer getTotalDeliveryTimeByRegionIdAndShopId(RedisTemplateHelper redisTemplateHelper, String regionId, String shopId) {
return getShopCookingTimeByRegionIdAndShopId(redisTemplateHelper, regionId, shopId) return getShopCookingTimeByRegionIdAndShopId(redisTemplateHelper, regionId, shopId)
+ getDeliveryTimeByRegionId(redisTemplateHelper, regionId); + getDeliveryTimeByRegionId(redisTemplateHelper, regionId);
@ -105,6 +133,10 @@ public class AdminSeckillGroupController {
return GROUP_DELIVERY_TIME_KEY_PREFIX + regionId; return GROUP_DELIVERY_TIME_KEY_PREFIX + regionId;
} }
public static String buildCustomerPhoneKey(String regionId) {
return GROUP_CUSTOMER_PHONE_KEY_PREFIX + regionId;
}
public static class DeliveryTimeSetting { public static class DeliveryTimeSetting {
private String regionId; private String regionId;
private Integer deliveryTime; 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) @RequestMapping(value = "/category/save", method = RequestMethod.POST)
@ApiOperation(value = "新增秒杀团分类") @ApiOperation(value = "新增秒杀团分类")
public Result saveCategory(@RequestBody SeckillGroupCategory category) { public Result saveCategory(@RequestBody SeckillGroupCategory category) {

10
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/UserAddressController.java

@ -88,6 +88,16 @@ public class UserAddressController {
List<UserAddressVo> list = userAddressService.getAddressListByUserId(userId); List<UserAddressVo> list = userAddressService.getAddressListByUserId(userId);
return new ResultUtil<List<UserAddressVo>>().setData(list); return new ResultUtil<List<UserAddressVo>>().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<UserAddress>().setData(address);
}
@RequestMapping(value = "/setDefault", method = RequestMethod.POST) @RequestMapping(value = "/setDefault", method = RequestMethod.POST)
@ApiOperation(value = "设置默认收货地址") @ApiOperation(value = "设置默认收货地址")

20
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.service.mybatis.MallOrderService;
import cc.hiver.mall.serviceimpl.UnifiedOrderService; import cc.hiver.mall.serviceimpl.UnifiedOrderService;
import cc.hiver.mall.utils.KeyUtils; import cc.hiver.mall.utils.KeyUtils;
import cc.hiver.mall.utils.MallOrderDeliveryFeeRefundHelper;
import cc.hiver.mall.utils.WechatPayConfig; import cc.hiver.mall.utils.WechatPayConfig;
import cc.hiver.mall.utils.WechatPaySigner; import cc.hiver.mall.utils.WechatPaySigner;
import com.fasterxml.jackson.databind.ObjectMapper; 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.Resource;
import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.ResourceLoader;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -57,6 +55,9 @@ public class WechatPayController {
@Autowired @Autowired
private MallDeliveryOrderService mallDeliveryOrderService; private MallDeliveryOrderService mallDeliveryOrderService;
@Autowired
private MallOrderDeliveryFeeRefundHelper mallOrderDeliveryFeeRefundHelper;
@Autowired @Autowired
private WechatPaySigner signer; private WechatPaySigner signer;
@ -133,10 +134,21 @@ public class WechatPayController {
// 2. 生成前端支付参数 // 2. 生成前端支付参数
Map<String, String> payParams = buildPaySign(prepayId); Map<String, String> payParams = buildPaySign(prepayId);
payParams.put("code","200"); payParams.put("code","200");
if(description.equals("增加配送佣金")){
payParams.put("wxOrderId", outTradeNo);
}
return ResponseEntity.ok(payParams); return ResponseEntity.ok(payParams);
} }
} }
@GetMapping("/delivery-fee-record/exists")
public ResponseEntity<Map<String, String>> existsDeliveryFeeRecord(@RequestParam String wxOrderId) {
Map<String, String> result = new HashMap<>();
result.put("code", "200");
result.put("exists", String.valueOf(mallOrderDeliveryFeeRefundHelper.existsAddedDeliveryFee(wxOrderId)));
return ResponseEntity.ok(result);
}
/** /**
* 微信支付异步回调通知接口 (API v3) * 微信支付异步回调通知接口 (API v3)
* 微信服务器会在支付成功后 POST 请求该接口 * 微信服务器会在支付成功后 POST 请求该接口

2
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; private BigDecimal refundAmount;
@ApiModelProperty(value = "退款原因") @ApiModelProperty(value = "退款原因")
private String reason; private String reason;
@ApiModelProperty(value = "拒绝原因")
private String rejectReason;
@ApiModelProperty(value = "区域id") @ApiModelProperty(value = "区域id")
private String regionId; private String regionId;
@ApiModelProperty(value = "退款图片") @ApiModelProperty(value = "退款图片")

19
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/mq/OrderDelayConsumer.java

@ -86,6 +86,9 @@ public class OrderDelayConsumer {
case "Shop_Cook_Timeout": case "Shop_Cook_Timeout":
handleShopCookTimeout(orderId); handleShopCookTimeout(orderId);
break; break;
case "Appointment_Shop_Cook_Notify":
handleAppointmentShopCookNotify(orderId);
break;
case "Transfer_Arrive_Timeout": case "Transfer_Arrive_Timeout":
handleTransferArriveTimeout(orderId); handleTransferArriveTimeout(orderId);
break; 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) { private void handleTransferArriveTimeout(String orderId) {
MallDeliveryOrder delivery = getDeliveryOrder(orderId); MallDeliveryOrder delivery = getDeliveryOrder(orderId);
if (delivery == null || !Integer.valueOf(1).equals(delivery.getTransferDelivery()) if (delivery == null || !Integer.valueOf(1).equals(delivery.getTransferDelivery())

67
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java

@ -189,22 +189,24 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl<MallDeliveryOrderM
} }
private Date calculateMustFinishTime(String regionId, String shopId, Integer deliveryType) { private Date calculateMustFinishTime(String regionId, String shopId, Integer deliveryType) {
Integer deliveryTime = 1 == (deliveryType == null ? 0 : deliveryType) Integer deliveryTime = getSchoolDeliveryTime(regionId, shopId, deliveryType);
? AdminSeckillGroupController.getTotalDeliveryTimeByRegionIdAndShopId(redisTemplateHelper, regionId, shopId)
: 40;
LocalDateTime futureTime = LocalDateTime.now().plusMinutes(deliveryTime); LocalDateTime futureTime = LocalDateTime.now().plusMinutes(deliveryTime);
return Date.from(futureTime.atZone(ZoneId.systemDefault()).toInstant()); return Date.from(futureTime.atZone(ZoneId.systemDefault()).toInstant());
} }
private Date calculateTransferMustFinishTime(String regionId, String shopId, Integer deliveryType) { private Date calculateTransferMustFinishTime(String regionId, String shopId, Integer deliveryType) {
Integer schoolDeliveryTime = 1 == (deliveryType == null ? 0 : deliveryType) Integer schoolDeliveryTime = getSchoolDeliveryTime(regionId, shopId, deliveryType);
? AdminSeckillGroupController.getTotalDeliveryTimeByRegionIdAndShopId(redisTemplateHelper, regionId, shopId)
: 40;
int totalMinutes = safeMinutes(getTransferDeliveryDuration(regionId, shopId)) + safeMinutes(schoolDeliveryTime); int totalMinutes = safeMinutes(getTransferDeliveryDuration(regionId, shopId)) + safeMinutes(schoolDeliveryTime);
LocalDateTime futureTime = LocalDateTime.now().plusMinutes(totalMinutes); LocalDateTime futureTime = LocalDateTime.now().plusMinutes(totalMinutes);
return Date.from(futureTime.atZone(ZoneId.systemDefault()).toInstant()); return Date.from(futureTime.atZone(ZoneId.systemDefault()).toInstant());
} }
private Integer getSchoolDeliveryTime(String regionId, String shopId, Integer deliveryType) {
return 1 == (deliveryType == null ? 0 : deliveryType)
? AdminSeckillGroupController.getTotalDeliveryTimeByRegionIdAndShopId(redisTemplateHelper, regionId, shopId)
: 40;
}
private Integer getTransferDeliveryDuration(String regionId, String shopId) { private Integer getTransferDeliveryDuration(String regionId, String shopId) {
Shop shop = getShopFromCache(regionId, shopId); Shop shop = getShopFromCache(regionId, shopId);
return shop == null || shop.getTransferDeliveryDuration() == null ? 0 : shop.getTransferDeliveryDuration(); return shop == null || shop.getTransferDeliveryDuration() == null ? 0 : shop.getTransferDeliveryDuration();
@ -282,14 +284,20 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl<MallDeliveryOrderM
mustFinishTime = calculateMustFinishTime(delivery.getRegionId(), delivery.getShopId(), delivery.getDeliveryType()); mustFinishTime = calculateMustFinishTime(delivery.getRegionId(), delivery.getShopId(), delivery.getDeliveryType());
} }
Date acceptTime = new Date(); Date acceptTime = new Date();
int transferArriveMinutes = 0; long transferDelayMillis = 0L;
if (transferDelivery) { if (transferDelivery) {
transferArriveMinutes = safeMinutes(getCookingTime(delivery.getRegionId(), delivery.getShopId()))
+ safeMinutes(getTransferDeliveryDuration(delivery.getRegionId(), delivery.getShopId()));
String transferName = StringUtils.defaultIfBlank(delivery.getTransferAddressName(), String transferName = StringUtils.defaultIfBlank(delivery.getTransferAddressName(),
order == null ? "" : StringUtils.defaultString(order.getTransferAddressName())); order == null ? "" : StringUtils.defaultString(order.getTransferAddressName()));
LocalDateTime transferArriveTime = LocalDateTime.ofInstant(acceptTime.toInstant(), ZoneId.systemDefault()) LocalDateTime transferArriveTime = calculateTransferArriveTime(
.plusMinutes(transferArriveMinutes); delivery.getRegionId(),
delivery.getShopId(),
delivery.getDeliveryType(),
mustFinishTime,
appointmentDelivery,
acceptTime
);
transferDelayMillis = Math.max(60 * 1000L,
Date.from(transferArriveTime.atZone(ZoneId.systemDefault()).toInstant()).getTime() - acceptTime.getTime());
String timeText = String.format("%02d:%02d", transferArriveTime.getHour(), transferArriveTime.getMinute()); String timeText = String.format("%02d:%02d", transferArriveTime.getHour(), transferArriveTime.getMinute());
delivery.setShopAddress("商家预计" + timeText + "配送到-" + transferName); delivery.setShopAddress("商家预计" + timeText + "配送到-" + transferName);
} }
@ -439,9 +447,12 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl<MallDeliveryOrderM
this.update(uw); this.update(uw);
// 出餐超时提醒只依赖本次接单成功的配送单,不依赖订单状态更新分支是否命中。 // 出餐超时提醒只依赖本次接单成功的配送单,不依赖订单状态更新分支是否命中。
triggerShopCookTimeoutEvent(cookTimeoutOrderIds, order); if (appointmentDelivery) {
triggerAppointmentShopCookEvent(cookTimeoutOrderIds, order, delivery);
} else {
triggerShopCookTimeoutEvent(cookTimeoutOrderIds, order);
}
if (transferDelivery && StringUtils.isNotBlank(delivery.getOrderId())) { if (transferDelivery && StringUtils.isNotBlank(delivery.getOrderId())) {
long transferDelayMillis = Math.max(1, transferArriveMinutes) * 60 * 1000L;
orderAsyncProducer.sendDelayMessage(delivery.getOrderId(), "Transfer_Arrive_Timeout", transferDelayMillis); orderAsyncProducer.sendDelayMessage(delivery.getOrderId(), "Transfer_Arrive_Timeout", transferDelayMillis);
} }
@ -474,6 +485,16 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl<MallDeliveryOrderM
return String.format("%04d", new Random().nextInt(10000)); return String.format("%04d", new Random().nextInt(10000));
} }
private LocalDateTime calculateTransferArriveTime(String regionId, String shopId, Integer deliveryType,
Date mustFinishTime, boolean appointmentDelivery, Date acceptTime) {
if (appointmentDelivery && mustFinishTime != null) {
return LocalDateTime.ofInstant(mustFinishTime.toInstant(), ZoneId.systemDefault())
.minusMinutes(safeMinutes(getSchoolDeliveryTime(regionId, shopId, deliveryType)));
}
return LocalDateTime.ofInstant(acceptTime.toInstant(), ZoneId.systemDefault())
.plusMinutes(safeMinutes(getCookingTime(regionId, shopId)) + safeMinutes(getTransferDeliveryDuration(regionId, shopId)));
}
/** /**
* 构建返回 VO * 构建返回 VO
*/ */
@ -534,6 +555,26 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl<MallDeliveryOrderM
} }
} }
private void triggerAppointmentShopCookEvent(List<String> 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);
}
}
/** /**
* 配送员取货状态待取货 -> 配送中 * 配送员取货状态待取货 -> 配送中
*/ */

50
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java

@ -616,7 +616,7 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void paySuccess(String orderId,BigDecimal totalFee) { public void paySuccess(String orderId,BigDecimal totalFee) {
if (orderId != null && orderId.startsWith("ORDER_")) { if (orderId != null && orderId.startsWith("ORDER_")) {
orderId = orderId.substring(6); orderId = orderId.substring(6);
MallOrder order = this.getById(orderId); MallOrder order = this.getById(orderId);
@ -1492,14 +1492,29 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
// 2. 一次 IN 查询所有商品明细 // 2. 一次 IN 查询所有商品明细
List<MallOrderGoods> allGoods = mallOrderGoodsMapper.selectPagesByOrderIds(orderIds); List<MallOrderGoods> allGoods = mallOrderGoodsMapper.selectPagesByOrderIds(orderIds);
List<MallDeliveryOrder> allDeliveryOrders = mallDeliveryOrderMapper.selectByOrderIds(orderIds);
if (allGoods == null) {
allGoods = java.util.Collections.emptyList();
}
if (allDeliveryOrders == null) {
allDeliveryOrders = java.util.Collections.emptyList();
}
// 3. 按 orderId 分组 // 3. 按 orderId 分组
java.util.Map<String, List<MallOrderGoods>> goodsMap = allGoods.stream() java.util.Map<String, List<MallOrderGoods>> goodsMap = allGoods.stream()
.collect(java.util.stream.Collectors.groupingBy(MallOrderGoods::getOrderId)); .collect(java.util.stream.Collectors.groupingBy(MallOrderGoods::getOrderId));
java.util.Map<String, MallDeliveryOrder> deliveryMap = allDeliveryOrders.stream()
.filter(delivery -> StringUtils.isNotBlank(delivery.getOrderId()))
.collect(java.util.stream.Collectors.toMap(
MallDeliveryOrder::getOrderId,
delivery -> delivery,
(first, second) -> first
));
// 4. 组装到每个 VO // 4. 组装到每个 VO
for (MallOrderVO vo : records) { for (MallOrderVO vo : records) {
vo.setGoodsList(goodsMap.getOrDefault(vo.getId(), java.util.Collections.emptyList())); 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<MallOrderMapper, MallOrder
delivery.setTransferAddressId(order.getTransferAddressId()); delivery.setTransferAddressId(order.getTransferAddressId());
delivery.setTransferAddressName(order.getTransferAddressName()); delivery.setTransferAddressName(order.getTransferAddressName());
if (transferDelivery) { if (transferDelivery) {
Integer duration = getTransferDeliveryDuration(order.getRegionId(), order.getShopId());
String transferName = StringUtils.defaultString(order.getTransferAddressName()); String transferName = StringUtils.defaultString(order.getTransferAddressName());
LocalDateTime arriveTime = LocalDateTime.now().plusMinutes(safeMinutes(getCookingTime(order.getRegionId(), order.getShopId())) + safeMinutes(duration)); LocalDateTime arriveTime = calculateTransferArriveTime(
order.getRegionId(),
order.getShopId(),
delivery.getDeliveryType(),
delivery.getMustFinishTime(),
Integer.valueOf(1).equals(delivery.getAppointmentDelivery())
);
String timeText = String.format("%02d:%02d", arriveTime.getHour(), arriveTime.getMinute()); String timeText = String.format("%02d:%02d", arriveTime.getHour(), arriveTime.getMinute());
delivery.setShopName(transferName + "取餐 - " + StringUtils.defaultString(order.getShopName())); delivery.setShopName(transferName + "取餐 - " + StringUtils.defaultString(order.getShopName()));
delivery.setShopAddress("商家预计" + timeText + "配送到-" + transferName); delivery.setShopAddress("商家预计" + timeText + "配送到-" + transferName);
@ -1885,10 +1905,18 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
mallDeliveryOrderMapper.insert(delivery); mallDeliveryOrderMapper.insert(delivery);
} }
private LocalDateTime calculateTransferArriveTime(String regionId, String shopId, Integer deliveryType,
Date mustFinishTime, boolean appointmentDelivery) {
if (appointmentDelivery && mustFinishTime != null) {
return LocalDateTime.ofInstant(mustFinishTime.toInstant(), ZoneId.systemDefault())
.minusMinutes(safeMinutes(getSchoolDeliveryTime(regionId, shopId, deliveryType)));
}
Integer duration = getTransferDeliveryDuration(regionId, shopId);
return LocalDateTime.now().plusMinutes(safeMinutes(getCookingTime(regionId, shopId)) + safeMinutes(duration));
}
private Date calculateTransferMustFinishTime(String regionId, String shopId, Integer deliveryType) { private Date calculateTransferMustFinishTime(String regionId, String shopId, Integer deliveryType) {
Integer schoolDeliveryTime = 1 == (deliveryType == null ? 0 : deliveryType) Integer schoolDeliveryTime = getSchoolDeliveryTime(regionId, shopId, deliveryType);
? AdminSeckillGroupController.getTotalDeliveryTimeByRegionIdAndShopId(redisTemplateHelper, regionId, shopId)
: 40;
Integer transferTime = getTransferDeliveryDuration(regionId, shopId); Integer transferTime = getTransferDeliveryDuration(regionId, shopId);
int totalMinutes = safeMinutes(transferTime) + safeMinutes(schoolDeliveryTime); int totalMinutes = safeMinutes(transferTime) + safeMinutes(schoolDeliveryTime);
LocalDateTime futureTime = LocalDateTime.now().plusMinutes(totalMinutes); LocalDateTime futureTime = LocalDateTime.now().plusMinutes(totalMinutes);
@ -1910,13 +1938,17 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
} }
private Date calculateMustFinishTime(String regionId, String shopId, Integer deliveryType) { private Date calculateMustFinishTime(String regionId, String shopId, Integer deliveryType) {
Integer deliveryTime = 1 == (deliveryType == null ? 0 : deliveryType) Integer deliveryTime = getSchoolDeliveryTime(regionId, shopId, deliveryType);
? AdminSeckillGroupController.getTotalDeliveryTimeByRegionIdAndShopId(redisTemplateHelper, regionId, shopId)
: 40;
LocalDateTime futureTime = LocalDateTime.now().plusMinutes(deliveryTime); LocalDateTime futureTime = LocalDateTime.now().plusMinutes(deliveryTime);
return Date.from(futureTime.atZone(ZoneId.systemDefault()).toInstant()); return Date.from(futureTime.atZone(ZoneId.systemDefault()).toInstant());
} }
private Integer getSchoolDeliveryTime(String regionId, String shopId, Integer deliveryType) {
return 1 == (deliveryType == null ? 0 : deliveryType)
? AdminSeckillGroupController.getTotalDeliveryTimeByRegionIdAndShopId(redisTemplateHelper, regionId, shopId)
: 40;
}
private Integer getTransferDeliveryDuration(String regionId, String shopId) { private Integer getTransferDeliveryDuration(String regionId, String shopId) {
Shop shop = getShopFromCache(regionId, shopId); Shop shop = getShopFromCache(regionId, shopId);
return shop == null || shop.getTransferDeliveryDuration() == null ? 0 : shop.getTransferDeliveryDuration(); return shop == null || shop.getTransferDeliveryDuration() == null ? 0 : shop.getTransferDeliveryDuration();

7
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallRefundRecordServiceImpl.java

@ -292,9 +292,16 @@ public class MallRefundRecordServiceImpl extends ServiceImpl<MallRefundRecordMap
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateStatus(MallRefundRecord mallRefundRecord) { public void updateStatus(MallRefundRecord mallRefundRecord) {
validateRefundRecordPending(mallRefundRecord); validateRefundRecordPending(mallRefundRecord);
boolean rejectStatus = mallRefundRecord.getStatus() != null
&& (mallRefundRecord.getStatus() == 2 || mallRefundRecord.getStatus() == 5);
String rejectReason = mallRefundRecord.getRejectReason() == null ? null : mallRefundRecord.getRejectReason().trim();
if (rejectStatus && (rejectReason == null || "".equals(rejectReason))) {
throw new RuntimeException("请输入拒绝原因");
}
LambdaUpdateWrapper<MallRefundRecord> uw = new LambdaUpdateWrapper<>(); LambdaUpdateWrapper<MallRefundRecord> uw = new LambdaUpdateWrapper<>();
uw.eq(MallRefundRecord::getId, mallRefundRecord.getId()) uw.eq(MallRefundRecord::getId, mallRefundRecord.getId())
.set(MallRefundRecord::getSuccessTime, new Date()) .set(MallRefundRecord::getSuccessTime, new Date())
.set(rejectStatus, MallRefundRecord::getRejectReason, rejectReason)
.set(MallRefundRecord::getStatus, mallRefundRecord.getStatus()); .set(MallRefundRecord::getStatus, mallRefundRecord.getStatus());
this.update(null, uw); this.update(null, uw);
//缓存去掉 //缓存去掉

2
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`;

1
hiver-modules/hiver-mall/src/main/resources/mapper/MallRefundRecordMapper.xml

@ -9,6 +9,7 @@
<result column="user_id" property="userId"/> <result column="user_id" property="userId"/>
<result column="refund_amount" property="refundAmount"/> <result column="refund_amount" property="refundAmount"/>
<result column="reason" property="reason"/> <result column="reason" property="reason"/>
<result column="reject_reason" property="rejectReason"/>
<result column="status" property="status"/> <result column="status" property="status"/>
<result column="create_time" property="createTime"/> <result column="create_time" property="createTime"/>
<result column="success_time" property="successTime"/> <result column="success_time" property="successTime"/>

Loading…
Cancel
Save