小程序自动发货
This commit is contained in:
1 parent
b7fe79b347
commit
88563423fa
3 files changed
+89
-4
No files matched your search
+2
@@ -38,6 +38,8 @@ public interface ErrorCodeConstants {
|
|||||||
ErrorCode STORE_ORDER_DESK_NOT = new ErrorCode(1008007023, "当前桌号不存在");
|
ErrorCode STORE_ORDER_DESK_NOT = new ErrorCode(1008007023, "当前桌号不存在");
|
||||||
ErrorCode STORE_ORDER_OUT_OF_DELIVERY_RANGE = new ErrorCode(1008007024, "当前收货地址不在配送范围内");
|
ErrorCode STORE_ORDER_OUT_OF_DELIVERY_RANGE = new ErrorCode(1008007024, "当前收货地址不在配送范围内");
|
||||||
ErrorCode STORE_ORDER_MIN_PRICE_NOT_MET = new ErrorCode(1008007025, "未达到外卖起送价");
|
ErrorCode STORE_ORDER_MIN_PRICE_NOT_MET = new ErrorCode(1008007025, "未达到外卖起送价");
|
||||||
|
ErrorCode WECHAT_SHIPPING_DELIVERY_NO_REQUIRED = new ErrorCode(1008007026, "请填写同城配送单号");
|
||||||
|
ErrorCode WECHAT_SHIPPING_UPLOAD_FAILED = new ErrorCode(1008007027, "微信发货信息上报失败");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+79
-4
@@ -3,6 +3,11 @@ package co.yixiang.yshop.module.order.service.storeorder;
|
|||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.binarywang.wx.miniapp.api.WxMaService;
|
||||||
|
import cn.binarywang.wx.miniapp.bean.shop.request.shipping.OrderKeyBean;
|
||||||
|
import cn.binarywang.wx.miniapp.bean.shop.request.shipping.PayerBean;
|
||||||
|
import cn.binarywang.wx.miniapp.bean.shop.request.shipping.ShippingListBean;
|
||||||
|
import cn.binarywang.wx.miniapp.bean.shop.request.shipping.WxMaOrderShippingInfoUploadRequest;
|
||||||
import co.yixiang.yshop.framework.common.constant.ShopConstants;
|
import co.yixiang.yshop.framework.common.constant.ShopConstants;
|
||||||
import co.yixiang.yshop.framework.common.enums.OrderInfoEnum;
|
import co.yixiang.yshop.framework.common.enums.OrderInfoEnum;
|
||||||
import co.yixiang.yshop.framework.common.enums.PayIdEnum;
|
import co.yixiang.yshop.framework.common.enums.PayIdEnum;
|
||||||
@@ -30,6 +35,8 @@ import co.yixiang.yshop.module.order.enums.OrderLogEnum;
|
|||||||
import co.yixiang.yshop.module.order.enums.PayTypeEnum;
|
import co.yixiang.yshop.module.order.enums.PayTypeEnum;
|
||||||
import co.yixiang.yshop.module.order.enums.UpdateOrderEnum;
|
import co.yixiang.yshop.module.order.enums.UpdateOrderEnum;
|
||||||
import co.yixiang.yshop.module.order.service.storeorderstatus.StoreOrderStatusService;
|
import co.yixiang.yshop.module.order.service.storeorderstatus.StoreOrderStatusService;
|
||||||
|
import co.yixiang.yshop.module.pay.dal.dataobject.merchantdetails.MerchantDetailsDO;
|
||||||
|
import co.yixiang.yshop.module.pay.service.merchantdetails.MerchantDetailsService;
|
||||||
import co.yixiang.yshop.module.product.service.storeproduct.AppStoreProductService;
|
import co.yixiang.yshop.module.product.service.storeproduct.AppStoreProductService;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.egzosn.pay.common.bean.RefundOrder;
|
import com.egzosn.pay.common.bean.RefundOrder;
|
||||||
@@ -37,6 +44,7 @@ import com.egzosn.pay.common.bean.RefundResult;
|
|||||||
import com.egzosn.pay.spring.boot.core.PayServiceManager;
|
import com.egzosn.pay.spring.boot.core.PayServiceManager;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import me.chanjar.weixin.common.error.WxErrorException;
|
||||||
import org.redisson.api.RBlockingDeque;
|
import org.redisson.api.RBlockingDeque;
|
||||||
import org.redisson.api.RDelayedQueue;
|
import org.redisson.api.RDelayedQueue;
|
||||||
import org.redisson.api.RedissonClient;
|
import org.redisson.api.RedissonClient;
|
||||||
@@ -48,6 +56,9 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -89,6 +100,10 @@ public class StoreOrderServiceImpl implements StoreOrderService {
|
|||||||
private AppStoreProductService appStoreProductService;
|
private AppStoreProductService appStoreProductService;
|
||||||
@Resource
|
@Resource
|
||||||
private PayServiceManager manager;
|
private PayServiceManager manager;
|
||||||
|
@Resource
|
||||||
|
private WxMaService wxMaService;
|
||||||
|
@Resource
|
||||||
|
private MerchantDetailsService merchantDetailsService;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private AsyncStoreOrderService asyncStoreOrderService;
|
private AsyncStoreOrderService asyncStoreOrderService;
|
||||||
@@ -119,22 +134,28 @@ public class StoreOrderServiceImpl implements StoreOrderService {
|
|||||||
|
|
||||||
//发货自取模式 直接收货
|
//发货自取模式 直接收货
|
||||||
if(UpdateOrderEnum.ORDER_SEND.getValue().equals(updateReqVO.getUpdateType())
|
if(UpdateOrderEnum.ORDER_SEND.getValue().equals(updateReqVO.getUpdateType())
|
||||||
&& updateObj.getOrderType().equals(OrderLogEnum.ORDER_TAKE_IN.getValue())){
|
&& updateObj2.getOrderType().equals(OrderLogEnum.ORDER_TAKE_IN.getValue())){
|
||||||
this.takeStoreOrder(updateObj.getId());
|
uploadWechatShippingInfo(updateObj2, null);
|
||||||
|
this.takeStoreOrder(updateObj.getId());
|
||||||
//todo 异步打印小票 商业版本才有 官网购买:https://www.yixiang.co
|
//todo 异步打印小票 商业版本才有 官网购买:https://www.yixiang.co
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//发货-外卖模式
|
//发货-外卖模式
|
||||||
if(UpdateOrderEnum.ORDER_SEND.getValue().equals(updateReqVO.getUpdateType())
|
if(UpdateOrderEnum.ORDER_SEND.getValue().equals(updateReqVO.getUpdateType())
|
||||||
&& updateObj.getOrderType().equals(OrderLogEnum.ORDER_TAKE_OUT.getValue())){
|
&& updateObj2.getOrderType().equals(OrderLogEnum.ORDER_TAKE_OUT.getValue())){
|
||||||
|
if (StrUtil.isBlank(updateObj.getDeliveryId())) {
|
||||||
|
throw exception(WECHAT_SHIPPING_DELIVERY_NO_REQUIRED);
|
||||||
|
}
|
||||||
|
updateObj.setDeliveryName(StrUtil.emptyToDefault(updateObj.getDeliveryName(), "同城配送"));
|
||||||
|
uploadWechatShippingInfo(updateObj2, updateObj.getDeliveryId());
|
||||||
updateObj.setStatus(OrderInfoEnum.STATUS_1.getValue());
|
updateObj.setStatus(OrderInfoEnum.STATUS_1.getValue());
|
||||||
//todo 异步打印小票 商业版本才有 官网购买:https://www.yixiang.co
|
//todo 异步打印小票 商业版本才有 官网购买:https://www.yixiang.co
|
||||||
|
|
||||||
}
|
}
|
||||||
//堂食模式
|
//堂食模式
|
||||||
if(UpdateOrderEnum.ORDER_SEND.getValue().equals(updateReqVO.getUpdateType())
|
if(UpdateOrderEnum.ORDER_SEND.getValue().equals(updateReqVO.getUpdateType())
|
||||||
&& updateObj.getOrderType().equals(OrderLogEnum.ORDER_TAKE_DESK.getValue())){
|
&& updateObj2.getOrderType().equals(OrderLogEnum.ORDER_TAKE_DESK.getValue())){
|
||||||
|
|
||||||
//todo 异步打印小票 商业版本才有 官网购买:https://www.yixiang.co
|
//todo 异步打印小票 商业版本才有 官网购买:https://www.yixiang.co
|
||||||
|
|
||||||
@@ -175,6 +196,60 @@ public class StoreOrderServiceImpl implements StoreOrderService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void uploadWechatShippingInfo(StoreOrderDO order, String deliveryNo) {
|
||||||
|
if (!PayTypeEnum.WEIXIN.getValue().equals(order.getPayType())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean sameCityDelivery = OrderLogEnum.ORDER_TAKE_OUT.getValue().equals(order.getOrderType());
|
||||||
|
if (sameCityDelivery && StrUtil.isBlank(deliveryNo)) {
|
||||||
|
throw exception(WECHAT_SHIPPING_DELIVERY_NO_REQUIRED);
|
||||||
|
}
|
||||||
|
|
||||||
|
MemberUserDO payer = userService.getUser(order.getUid());
|
||||||
|
if (payer == null || StrUtil.isBlank(payer.getRoutineOpenid())) {
|
||||||
|
log.warn("[uploadWechatShippingInfo][skip non-miniapp orderId={}]", order.getOrderId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MerchantDetailsDO merchant = merchantDetailsService.getMerchantDetails(PayIdEnum.WX_MINIAPP.getValue());
|
||||||
|
if (merchant == null || StrUtil.isBlank(merchant.getMchId())) {
|
||||||
|
log.warn("[uploadWechatShippingInfo][skip missing miniapp merchant config, orderId={}]", order.getOrderId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String itemDesc = buildItemDesc(order.getId());
|
||||||
|
ShippingListBean shipping = ShippingListBean.builder().itemDesc(itemDesc).build();
|
||||||
|
if (sameCityDelivery) {
|
||||||
|
shipping.setTrackingNo(deliveryNo);
|
||||||
|
}
|
||||||
|
WxMaOrderShippingInfoUploadRequest request = WxMaOrderShippingInfoUploadRequest.builder()
|
||||||
|
.orderKey(OrderKeyBean.builder().orderNumberType(1).mchId(merchant.getMchId()).outTradeNo(order.getOrderId()).build())
|
||||||
|
.logisticsType(sameCityDelivery ? 2 : 4)
|
||||||
|
.deliveryMode(1)
|
||||||
|
.shippingList(List.of(shipping))
|
||||||
|
.uploadTime(OffsetDateTime.now(ZoneId.of("Asia/Shanghai")).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME))
|
||||||
|
.payer(PayerBean.builder().openid(payer.getRoutineOpenid()).build())
|
||||||
|
.build();
|
||||||
|
try {
|
||||||
|
wxMaService.getWxMaOrderShippingService().upload(request);
|
||||||
|
} catch (WxErrorException e) {
|
||||||
|
log.error("[uploadWechatShippingInfo][orderId={} upload failed]", order.getOrderId(), e);
|
||||||
|
throw exception(WECHAT_SHIPPING_UPLOAD_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildItemDesc(Long orderId) {
|
||||||
|
List<StoreOrderCartInfoDO> items = storeOrderCartInfoMapper.selectList(new LambdaQueryWrapper<StoreOrderCartInfoDO>()
|
||||||
|
.eq(StoreOrderCartInfoDO::getOid, orderId));
|
||||||
|
StringBuilder desc = new StringBuilder();
|
||||||
|
for (StoreOrderCartInfoDO item : items) {
|
||||||
|
if (desc.length() > 0) {
|
||||||
|
desc.append('、');
|
||||||
|
}
|
||||||
|
desc.append(item.getTitle()).append('*').append(item.getNumber());
|
||||||
|
}
|
||||||
|
return StrUtil.subPre(StrUtil.emptyToDefault(desc.toString(), "商品"), 120);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteStoreOrder(Long id) {
|
public void deleteStoreOrder(Long id) {
|
||||||
// 校验存在
|
// 校验存在
|
||||||
|
|||||||
@@ -19,6 +19,14 @@
|
|||||||
<el-form-item label="地址" prop="orderType" v-if="formData.orderType == 'takeout'">
|
<el-form-item label="地址" prop="orderType" v-if="formData.orderType == 'takeout'">
|
||||||
<span>{{ formData.realName }}{{ formData.userPhone }}{{ formData.userAddress }}</span>
|
<span>{{ formData.realName }}{{ formData.userPhone }}{{ formData.userAddress }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
v-if="formData.orderType == 'takeout'"
|
||||||
|
label="同城配送单号"
|
||||||
|
prop="deliveryId"
|
||||||
|
:rules="[{ required: true, message: '同城配送单号不能为空', trigger: 'blur' }]"
|
||||||
|
>
|
||||||
|
<el-input v-model="formData.deliveryId" placeholder="请输入同城配送单号" class="input-width" />
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">打 印</el-button>
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">打 印</el-button>
|
||||||
|
|||||||
Reference in new issue
Block a user