微信发货管理 bug 修改,更改下单的一些逻辑

This commit is contained in:
Jack 2025-06-11 23:26:39 +08:00
parent dcd8fe9b66
commit ca62541fdf
13 changed files with 294 additions and 187 deletions

View File

@ -72,7 +72,16 @@ public class PayConsumeTrade implements Serializable {
private Integer payment_channel_id; private Integer payment_channel_id;
@ApiModelProperty(value = "app_id") @ApiModelProperty(value = "app_id")
private Integer app_id; private String app_id;
@ApiModelProperty(value = "mch_id")
private String mch_id;
@ApiModelProperty(value = "transaction_id")
private String transaction_id;
@ApiModelProperty(value = "open_id")
private String open_id;
@ApiModelProperty(value = "服务器编号") @ApiModelProperty(value = "服务器编号")
private Integer server_id; private Integer server_id;

View File

@ -22,11 +22,13 @@ import java.io.Serializable;
*/ */
public class WxOrderBaseInfoDTO implements Serializable { public class WxOrderBaseInfoDTO implements Serializable {
private Integer store_id; // 店铺Id private Integer store_id; // 店铺Id
private String out_trade_no; // 商户订单号 private String app_id; // 应用Id
private String mch_id; // 商户号
private String transaction_id; // 原支付交易对应的微信订单号 private String transaction_id; // 原支付交易对应的微信订单号
private String out_trade_no; // 商户订单号
private String subject; // 订单标题 private String subject; // 订单标题
private Integer user_id; // 用户Id private Integer user_id; // 用户Id
private String openid; // 微信 openId private String open_id; // 微信 openId
private String lkl_merchant_no; // 拉卡拉商户号 private String lkl_merchant_no; // 拉卡拉商户号
private String lkl_term_no; // 拉卡拉终端号 private String lkl_term_no; // 拉卡拉终端号
private String da_mobile; // 收货人手机 private String da_mobile; // 收货人手机

View File

@ -40,7 +40,7 @@ public class ContextUtil {
public static UserDto getCurrentUser() { public static UserDto getCurrentUser() {
try { try {
UserDto loginUser = staticUserInfoService.getUser(); UserDto loginUser = staticUserInfoService.getUser();
log.info("##### 当前登录用户:{}###", JsonUtil.object2json(loginUser)); //log.warn("##### 当前登录用户:{}###", JsonUtil.object2json(loginUser));
return loginUser;//todo 测试去除 return loginUser;//todo 测试去除
// UserDto user= new UserDto(); // UserDto user= new UserDto();
// user.setStore_id("1"); // user.setStore_id("1");
@ -81,6 +81,7 @@ public class ContextUtil {
/** /**
* 传入的 * 传入的
*
* @param storeId * @param storeId
* @return * @return
*/ */

View File

@ -168,7 +168,7 @@ public class IndexController extends BaseControllerImpl {
@ApiImplicitParam(name = "pc_scancode_flag", value = "pc_scancode_flag", paramType = "query", required = false, dataType = "int"), @ApiImplicitParam(name = "pc_scancode_flag", value = "pc_scancode_flag", paramType = "query", required = false, dataType = "int"),
@ApiImplicitParam(name = "openid", value = "openid", paramType = "query", required = false, dataType = "String"), @ApiImplicitParam(name = "openid", value = "openid", paramType = "query", required = false, dataType = "String"),
}) })
@RequestMapping(value = "/pay", method = RequestMethod.GET) @RequestMapping(value = "/pay", method = {RequestMethod.GET, RequestMethod.POST})
public void pay(HttpServletRequest request, HttpServletResponse response, public void pay(HttpServletRequest request, HttpServletResponse response,
@RequestParam(name = "prepayapp_flag", defaultValue = "false") boolean prepayapp_flag, @RequestParam(name = "prepayapp_flag", defaultValue = "false") boolean prepayapp_flag,
@RequestParam(name = "return_flag", defaultValue = "false") boolean return_flag, @RequestParam(name = "return_flag", defaultValue = "false") boolean return_flag,

View File

@ -43,4 +43,22 @@ public interface PayConsumeTradeService extends IBaseService<PayConsumeTrade> {
*/ */
boolean changeOrderState(String orderId, Integer orderStateId, Integer tradeIsPaid); boolean changeOrderState(String orderId, Integer orderStateId, Integer tradeIsPaid);
/**
* 根据店铺ID和订单ID更新交易的关键字段mchIdopenIdappIdtransactionId
* 仅更新非空字段避免覆盖原有有效数据
*
* @param payConsumeTrade 包含待更新数据的实体对象
* @return 是否更新成功
*/
Boolean updateTradeByStoreAndOrderId(PayConsumeTrade payConsumeTrade);
/**
* 根据主键ID更新交易的关键字段mchIdopenIdappIdtransactionId
* 仅更新非空字段避免覆盖原有有效数据
*
* @param payConsumeTrade 包含待更新数据的实体对象
* @return 是否更新成功
*/
Boolean updateTradeByPrimaryKey(PayConsumeTrade payConsumeTrade);
} }

View File

@ -111,7 +111,7 @@ public class PayBaseRechargeLevelServiceImpl extends BaseServiceImpl<PayBaseRech
consume_trade_row.setTrade_is_paid(StateCode.ORDER_PAID_STATE_NO); // 未支付 consume_trade_row.setTrade_is_paid(StateCode.ORDER_PAID_STATE_NO); // 未支付
consume_trade_row.setTrade_type_id(StateCode.TRADE_TYPE_DEPOSIT); // 交易类型trade_mode_id consume_trade_row.setTrade_type_id(StateCode.TRADE_TYPE_DEPOSIT); // 交易类型trade_mode_id
consume_trade_row.setPayment_channel_id(0); // 支付渠道 consume_trade_row.setPayment_channel_id(0); // 支付渠道
consume_trade_row.setApp_id(0); // app_id consume_trade_row.setApp_id("0"); // app_id
consume_trade_row.setServer_id(0); // 服务器id consume_trade_row.setServer_id(0); // 服务器id
consume_trade_row.setTrade_mode_id(1); // 交易类型:1-担保交易; 2-直接交易 consume_trade_row.setTrade_mode_id(1); // 交易类型:1-担保交易; 2-直接交易
consume_trade_row.setOrder_payment_amount(pdr_amount); // 总付款额度: trade_payment_amount + trade_payment_money + trade_payment_recharge_card + trade_payment_points consume_trade_row.setOrder_payment_amount(pdr_amount); // 总付款额度: trade_payment_amount + trade_payment_money + trade_payment_recharge_card + trade_payment_points

View File

@ -23,6 +23,7 @@ import com.suisung.mall.common.utils.I18nUtil;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl; import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.pay.mapper.PayConsumeTradeMapper; import com.suisung.mall.pay.mapper.PayConsumeTradeMapper;
import com.suisung.mall.pay.service.*; import com.suisung.mall.pay.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -41,6 +42,7 @@ import static com.suisung.mall.common.utils.ContextUtil.getCurrentUser;
* @author Xinze * @author Xinze
* @since 2021-04-29 * @since 2021-04-29
*/ */
@Slf4j
@Service @Service
public class PayConsumeTradeServiceImpl extends BaseServiceImpl<PayConsumeTradeMapper, PayConsumeTrade> implements PayConsumeTradeService { public class PayConsumeTradeServiceImpl extends BaseServiceImpl<PayConsumeTradeMapper, PayConsumeTrade> implements PayConsumeTradeService {
@ -1393,4 +1395,94 @@ public class PayConsumeTradeServiceImpl extends BaseServiceImpl<PayConsumeTradeM
return update(updateWrapper); return update(updateWrapper);
} }
/**
* 根据店铺ID和订单ID更新交易的关键字段mchIdopenIdappIdtransactionId
* 仅更新非空字段避免覆盖原有有效数据
*
* @param payConsumeTrade 包含待更新数据的实体对象
* @return 是否更新成功
*/
@Override
public Boolean updateTradeByStoreAndOrderId(PayConsumeTrade payConsumeTrade) {
if (payConsumeTrade == null
|| ObjectUtil.isEmpty(payConsumeTrade.getStore_id())
|| StrUtil.isBlank(payConsumeTrade.getOrder_id())) {
return false;
}
try {
// 构建更新条件
UpdateWrapper<PayConsumeTrade> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("store_id", payConsumeTrade.getStore_id())
.eq("order_id", payConsumeTrade.getOrder_id());
// 仅设置非空字段避免无效更新
boolean hasUpdateField = false;
if (StrUtil.isNotBlank(payConsumeTrade.getMch_id())) {
updateWrapper.set("mch_id", payConsumeTrade.getMch_id());
hasUpdateField = true;
}
if (StrUtil.isNotBlank(payConsumeTrade.getOpen_id())) {
updateWrapper.set("open_id", payConsumeTrade.getOpen_id());
hasUpdateField = true;
}
if (StrUtil.isNotBlank(payConsumeTrade.getApp_id())) {
updateWrapper.set("app_id", payConsumeTrade.getApp_id());
hasUpdateField = true;
}
if (StrUtil.isNotBlank(payConsumeTrade.getTransaction_id())) {
updateWrapper.set("transaction_id", payConsumeTrade.getTransaction_id());
hasUpdateField = true;
}
// 没有需要更新的字段直接返回
if (!hasUpdateField) {
return false;
}
return update(updateWrapper);
} catch (Exception e) {
log.error("更新 PayConsumeTrade 关键字段失败:{}", e.getMessage(), e);
return false;
}
}
@Override
public Boolean updateTradeByPrimaryKey(PayConsumeTrade payConsumeTrade) {
if (payConsumeTrade == null
|| ObjectUtil.isEmpty(payConsumeTrade.getConsume_trade_id())) {
return false;
}
try {
// 构建更新条件
UpdateWrapper<PayConsumeTrade> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("consume_trade_id", payConsumeTrade.getConsume_trade_id());
// 仅设置非空字段避免无效更新
boolean hasUpdateField = false;
if (StrUtil.isNotBlank(payConsumeTrade.getMch_id())) {
updateWrapper.set("mch_id", payConsumeTrade.getMch_id());
hasUpdateField = true;
}
if (StrUtil.isNotBlank(payConsumeTrade.getOpen_id())) {
updateWrapper.set("open_id", payConsumeTrade.getOpen_id());
hasUpdateField = true;
}
if (StrUtil.isNotBlank(payConsumeTrade.getApp_id())) {
updateWrapper.set("app_id", payConsumeTrade.getApp_id());
hasUpdateField = true;
}
if (StrUtil.isNotBlank(payConsumeTrade.getTransaction_id())) {
updateWrapper.set("transaction_id", payConsumeTrade.getTransaction_id());
hasUpdateField = true;
}
// 没有需要更新的字段直接返回
if (!hasUpdateField) {
return false;
}
return update(updateWrapper);
} catch (Exception e) {
log.error("更新 PayConsumeTrade 关键字段失败:{}", e.getMessage(), e);
return false;
}
}
} }

View File

@ -602,6 +602,12 @@ public class PayUserPayServiceImpl extends BaseServiceImpl<PayUserPayMapper, Pay
Integer storeId = payConsumeTrade.getStore_id(); Integer storeId = payConsumeTrade.getStore_id();
// 更新消费支付交易记录
payConsumeTrade.setApp_id(appId);
payConsumeTrade.setMch_id(wxPayApiConfig.getMchId());
payConsumeTrade.setOpen_id(openId);
payConsumeTradeService.updateTradeByStoreAndOrderId(payConsumeTrade);
// 这里获取店铺的拉卡拉的商户号和终端号码 // 这里获取店铺的拉卡拉的商户号和终端号码
ShopStoreBase shopStoreBase = shopService.getLklMerchantNoAndTermNo(storeId); ShopStoreBase shopStoreBase = shopService.getLklMerchantNoAndTermNo(storeId);
if (shopStoreBase == null) { if (shopStoreBase == null) {
@ -1295,6 +1301,7 @@ public class PayUserPayServiceImpl extends BaseServiceImpl<PayUserPayMapper, Pay
cn.hutool.json.JSONObject lklNotifyRespJSON = JSONUtil.parseObj(body); cn.hutool.json.JSONObject lklNotifyRespJSON = JSONUtil.parseObj(body);
params = Convert.toMap(String.class, String.class, lklNotifyRespJSON); params = Convert.toMap(String.class, String.class, lklNotifyRespJSON);
String orderId = params.getOrDefault("out_trade_no", ""); String orderId = params.getOrDefault("out_trade_no", "");
String accTradeNo = params.getOrDefault("acc_trade_no", ""); // 需要跟拉卡拉确认这个字段是原支付交易对应的微信订单号吗
// 提取授权签名信息 // 提取授权签名信息
Map<String, String> authMap = LakalaUtil.getLakalaAuthorizationMap(authorization); Map<String, String> authMap = LakalaUtil.getLakalaAuthorizationMap(authorization);
@ -1319,6 +1326,13 @@ public class PayUserPayServiceImpl extends BaseServiceImpl<PayUserPayMapper, Pay
String orderSubject = trade_row_tmp != null ? trade_row_tmp.getTrade_title() : ""; String orderSubject = trade_row_tmp != null ? trade_row_tmp.getTrade_title() : "";
Integer userId = trade_row_tmp != null ? trade_row_tmp.getBuyer_id() : 0; Integer userId = trade_row_tmp != null ? trade_row_tmp.getBuyer_id() : 0;
// 更新交易记录的 原支付交易对应的微信订单号 transaction_id
if (trade_row_tmp != null && StrUtil.isNotBlank(accTradeNo)) {
PayConsumeTrade payConsumeTradeUpd = new PayConsumeTrade();
payConsumeTradeUpd.setConsume_trade_id(trade_row_tmp.getConsume_trade_id()).setTransaction_id(accTradeNo);
payConsumeTradeService.updateTradeByPrimaryKey(payConsumeTradeUpd);
}
// 查询支付渠道 // 查询支付渠道
QueryWrapper<PayPaymentChannel> channelQueryWrapper = new QueryWrapper<>(); QueryWrapper<PayPaymentChannel> channelQueryWrapper = new QueryWrapper<>();
channelQueryWrapper.eq("payment_channel_code", "lakala"); channelQueryWrapper.eq("payment_channel_code", "lakala");

View File

@ -15,19 +15,16 @@ import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.util.Pair; import org.springframework.data.util.Pair;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
/** /***
* 支付成功后微信和支付宝发出异步通知消息到 RabbitMQ * 支付成功后微信和支付宝发出异步通知消息到 mqmq监听到消息执行更改订单状态已支付
* 这里 MQ 监听到消息后执行更改订单状态为已支付
* <p>
* payConsumeDepositService.processDeposit 这个方法里发出 mq 消息
*/ */
@Service @Service
@Slf4j @Slf4j
@ -35,171 +32,111 @@ import java.util.List;
public class OrderPayedListener { public class OrderPayedListener {
private static final Logger logger = LoggerFactory.getLogger(OrderPayedListener.class); private static final Logger logger = LoggerFactory.getLogger(OrderPayedListener.class);
@Lazy
@Autowired @Autowired
private ShopOrderBaseService shopOrderBaseService; private ShopOrderBaseService shopOrderBaseService;
@Lazy
@Autowired @Autowired
private ShopOrderInfoService shopOrderInfoService; private ShopOrderInfoService shopOrderInfoService;
// @Autowired
@Lazy // private ShopStorePrinterService shopStorePrinterService;
// @Autowired
// private MqMessageService mqMessageService;
@Resource
@Autowired @Autowired
private SFExpressApiService sfExpressApiService; private SFExpressApiService sfExpressApiService;
/**
* RabbitMQ 消息监听入口方法
*
* @param data 消息体包含订单 ID 列表
* @param channel 当前 Channel
* @param message 消息对象
* @throws IOException IO 异常
*/
@RabbitHandler @RabbitHandler
public void listener(String data, Channel channel, Message message) throws IOException { public void listener(String data, Channel channel, Message message) throws IOException, InterruptedException {
List<String> orderIdList = Convert.toList(String.class, data); String messageId = message.getMessageProperties().getMessageId();
boolean flag = false;
List<String> order_id_row = Convert.toList(String.class, data);
try { try {
// 1. 记录接收到的消息内容
logger.info("收到微信异步通知消息data:{}-channel:{}-message:{},订单ID:{}", data, channel, message, orderIdList);
// 2. 执行订单状态更新逻辑支持批量处理
flag = updateOrderStatusBatch(orderIdList);
if (flag) {
// 3. 若订单更新成功执行后续操作取单号生成打票机打印顺丰下单等
handleSfExpressOrderActions(orderIdList);
}
// 4. 根据执行结果确认或拒绝消息
if (flag) {
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} else {
log.warn("订单状态更新失败,拒绝消息:{}", orderIdList);
channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
}
} catch (Exception e) {
// 5. 捕获异常并记录日志
log.error("消费消息失败:{},失败原因:", orderIdList, e);
// 6. 拒绝消息并重新入队
channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
}
}
/**
* 批量更新订单状态为已支付
*
* @param orderIdList 订单 ID 列表
* @return 是否全部更新成功
*/
private boolean updateOrderStatusBatch(List<String> orderIdList) {
if (orderIdList == null || orderIdList.isEmpty()) {
return false;
}
boolean flag = false; boolean flag = false;
logger.info("收到微信异步通知消息data:{}-chanel:{}-message:{},订单ID:{}", data, channel, message, order_id_row);
for (String orderId : orderIdList) { for (String orderId : order_id_row) {
//判断是否为线下支付订单
ShopOrderInfo orderInfoOld = shopOrderInfoService.get(orderId); ShopOrderInfo orderInfoOld = shopOrderInfoService.get(orderId);
if (orderInfoOld == null) { if (orderInfoOld == null) {
continue; continue;
} }
// 订单状态
int order_state_id = orderInfoOld.getOrder_state_id().intValue(); int order_state_id = orderInfoOld.getOrder_state_id().intValue();
logger.debug("#### 当前订单状态: {} ####", order_state_id); logger.info("#### 当前订单状态: {} ####", order_state_id);
// 如果是待支付状态则调用 setPaidYes
if (order_state_id == StateCode.ORDER_STATE_WAIT_PAY) { if (order_state_id == StateCode.ORDER_STATE_WAIT_PAY) {
logger.debug("#### 待支付业务分支 ####"); // 待支付状态
logger.info("#### 待支付业务分支 ####");
flag = shopOrderBaseService.setPaidYes(Collections.singletonList(orderId)); flag = shopOrderBaseService.setPaidYes(Collections.singletonList(orderId));
} } else {
// 非待支付状态判断是否为线下支付 //判断是否线下支付
else if (StateCode.PAYMENT_TYPE_OFFLINE == orderInfoOld.getPayment_type_id().intValue()) { if (StateCode.PAYMENT_TYPE_OFFLINE == orderInfoOld.getPayment_type_id().intValue()) {
logger.debug("#### 线下业务分支 ####"); //线下支付直接处理订单支付状态 不处理订单状态
logger.info("#### 线下业务分支 ####");
ShopOrderInfo orderInfo = new ShopOrderInfo(); ShopOrderInfo orderInfo = new ShopOrderInfo();
orderInfo.setOrder_id(orderId); orderInfo.setOrder_id(orderId);
orderInfo.setOrder_is_paid(StateCode.ORDER_PAID_STATE_YES); orderInfo.setOrder_is_paid(StateCode.ORDER_PAID_STATE_YES);
flag = shopOrderInfoService.edit(orderInfo); flag = shopOrderInfoService.edit(orderInfo);
} } else {
// 其他情况也调用 setPaidYes logger.info("#### 非线下业务分支 ####");
else {
logger.debug("#### 非线下业务分支 ####");
flag = shopOrderBaseService.setPaidYes(Collections.singletonList(orderId)); flag = shopOrderBaseService.setPaidYes(Collections.singletonList(orderId));
} }
}
logger.info("#### 支付异步通知回调处理是否成功:{} ####", flag); logger.info("#### 支付异步通知回调处理是否成功:{} ####", flag);
// 生成取单号和打印小票
if (flag) {
// TODO 以下仅处理下单打印的情况还需要处理退单打印分支
if (!flag) { // 原始状态 2010-待付款;2011--待订单审核;2013-待财务审核 变成 2020-待配货2016-已经付款 的时候
break; // 任意一个失败则中断处理 // 生成取单号打票机打印订单向顺丰同城下单
} if (order_state_id == StateCode.ORDER_STATE_WAIT_PAY
} || order_state_id == StateCode.ORDER_STATE_WAIT_REVIEW
|| order_state_id == StateCode.ORDER_STATE_WAIT_FINANCE_REVIEW) {
return flag; // 已支付的订单生成取单号打票机并打印订单
}
/**
* 处理支付完成后执行顺丰订单生成和取单号操作
* - 生成取单号
* - 打印小票
* - 顺丰同城下单等
*
* @param orderIdList 订单 ID 列表
*/
private void handleSfExpressOrderActions(List<String> orderIdList) {
if (orderIdList == null || orderIdList.isEmpty()) {
return;
}
for (String orderId : orderIdList) {
ShopOrderInfo orderInfoOld = shopOrderInfoService.get(orderId);
if (orderInfoOld == null) {
continue;
}
int order_state_id = orderInfoOld.getOrder_state_id().intValue();
// 只处理特定状态的订单待支付待审核待财务审核
if (!(order_state_id == StateCode.ORDER_STATE_WAIT_PAY ||
order_state_id == StateCode.ORDER_STATE_WAIT_REVIEW ||
order_state_id == StateCode.ORDER_STATE_WAIT_FINANCE_REVIEW)) {
continue;
}
Long orderPickupNum = shopOrderInfoService.isPaidOrderGenPickNumAndPrint(orderInfoOld.getStore_id(), orderId); Long orderPickupNum = shopOrderInfoService.isPaidOrderGenPickNumAndPrint(orderInfoOld.getStore_id(), orderId);
if (orderPickupNum == null || orderPickupNum <= 0) {
continue;
}
// 判断是否为顺丰同城配送方式
if (orderInfoOld.getDelivery_type_id() == null ||
!orderInfoOld.getDelivery_type_id().equals(StateCode.DELIVERY_TYPE_SAME_CITY)) {
continue;
}
// 如果配送方式是 顺丰同城下单
if (orderInfoOld.getDelivery_type_id() != null && orderInfoOld.getDelivery_type_id().equals(StateCode.DELIVERY_TYPE_SAME_CITY)
&& orderPickupNum > 0) {
// 发送顺丰同城快递
Pair<Boolean, String> pairCreateSfOrder = sfExpressApiService.innerCreateSfExpressOrder(orderId, orderPickupNum); Pair<Boolean, String> pairCreateSfOrder = sfExpressApiService.innerCreateSfExpressOrder(orderId, orderPickupNum);
if (pairCreateSfOrder == null) { if (pairCreateSfOrder == null) {
logger.error("顺丰同城下单失败pairCreateSfOrder 返回空值"); logger.error("顺丰同城下单失败pairCreateSfOrder 返回空值");
continue; return;
} }
if (!pairCreateSfOrder.getFirst()) { if (!pairCreateSfOrder.getFirst()) {
logger.error("顺丰同城下单失败:{}", pairCreateSfOrder.getSecond()); logger.error("顺丰同城下单失败:{}", pairCreateSfOrder.getSecond());
continue; return;
} }
logger.debug("顺丰同城下单成功"); logger.info("顺丰同城下单成功");
// 个推推送消息 // 个推推送消息
sfExpressApiService.pushMessageToStoreEmployee(null, orderId, "顺丰同城订单[" + orderId + "]已完成配送", ""); sfExpressApiService.pushMessageToStoreEmployee(null, orderId, "你有一笔同城订单[" + orderId + "],请及时处理。", "");
}
}
}
}
if (flag) {
// 操作成功标记消息消费成功
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} else {
log.error("消息消费失败执行setPaidYes异常当前订单编号{}", order_id_row);
channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
Thread.sleep(1000);
}
} catch (Exception e) {
log.error("消息消费失败执行setPaidYes异常当前订单编号{},失败原因:", order_id_row, e);
channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
Thread.sleep(1000);
} }
} }
} }

View File

@ -7549,7 +7549,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
consume_trade_row.setTrade_is_paid(StateCode.ORDER_PAID_STATE_NO); // 未支付 consume_trade_row.setTrade_is_paid(StateCode.ORDER_PAID_STATE_NO); // 未支付
consume_trade_row.setTrade_type_id(StateCode.TRADE_TYPE_SHOPPING); // 交易类型 consume_trade_row.setTrade_type_id(StateCode.TRADE_TYPE_SHOPPING); // 交易类型
consume_trade_row.setPayment_channel_id(usePoint ? StateCode.PAYMENT_POINTS : 0); // 支付渠道 consume_trade_row.setPayment_channel_id(usePoint ? StateCode.PAYMENT_POINTS : 0); // 支付渠道
consume_trade_row.setApp_id(0); // app_id consume_trade_row.setApp_id("0"); // app_id
consume_trade_row.setServer_id(0); // 服务器id consume_trade_row.setServer_id(0); // 服务器id
consume_trade_row.setTrade_mode_id(1); // 交易类型:1-担保交易; 2-直接交易 consume_trade_row.setTrade_mode_id(1); // 交易类型:1-担保交易; 2-直接交易
consume_trade_row.setCurrency_id((Integer) base_row.get("currency_id")); consume_trade_row.setCurrency_id((Integer) base_row.get("currency_id"));

View File

@ -169,6 +169,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
@Transactional @Transactional
@Override @Override
public Pair<Boolean, String> innerCreateSfExpressOrder(String shopOrderId, Long orderPickupNum) { public Pair<Boolean, String> innerCreateSfExpressOrder(String shopOrderId, Long orderPickupNum) {
logger.info("开始顺丰同城下单");
if (StrUtil.isBlank(shopOrderId) || orderPickupNum == null || orderPickupNum <= 0) { if (StrUtil.isBlank(shopOrderId) || orderPickupNum == null || orderPickupNum <= 0) {
return Pair.of(false, "顺丰同城下单时,缺少必要参数!"); return Pair.of(false, "顺丰同城下单时,缺少必要参数!");
} }
@ -225,7 +226,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
shopOrderInfoService.changeOrderStatus(shopOrderId, StateCode.ORDER_STATE_PICKING, 0, 0); shopOrderInfoService.changeOrderStatus(shopOrderId, StateCode.ORDER_STATE_PICKING, 0, 0);
// 上传发货信息到微信 // 上传发货信息到微信
wxOrderShippingService.uploadShippingInfoToWx(2, shopOrderId); // wxOrderShippingService.uploadShippingInfoToWx(2, shopStoreSfOrder.getShop_order_id());
return Pair.of(true, "顺丰同城下单成功!"); return Pair.of(true, "顺丰同城下单成功!");
} }
@ -614,6 +615,10 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
orderIsOutStatus = 0; orderIsOutStatus = 0;
orderIsShippedStatus = 0; orderIsShippedStatus = 0;
pushRemark = "配送员已接单。"; pushRemark = "配送员已接单。";
// 上传发货信息到微信
wxOrderShippingService.uploadShippingInfoToWx(2, shopStoreSfOrder.getShop_order_id());
} else if (shopStoreSfOrder.getOrder_status().equals(StateCode.SF_ORDER_STATUS_ARRIVED)) { } else if (shopStoreSfOrder.getOrder_status().equals(StateCode.SF_ORDER_STATUS_ARRIVED)) {
// 顺丰同城状态12-配送员到店; // 顺丰同城状态12-配送员到店;
// 商城订单状态 2020-待配货 2030; //待发货 // 商城订单状态 2020-待配货 2030; //待发货
@ -621,6 +626,9 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
orderIsOutStatus = StateCode.ORDER_PICKING_STATE_YES; // 已出库 orderIsOutStatus = StateCode.ORDER_PICKING_STATE_YES; // 已出库
orderIsShippedStatus = 0; orderIsShippedStatus = 0;
pushRemark = "配送员已到店。"; pushRemark = "配送员已到店。";
// 上传发货信息到微信
wxOrderShippingService.uploadShippingInfoToWx(2, shopStoreSfOrder.getShop_order_id());
} else if (shopStoreSfOrder.getOrder_status().equals(StateCode.SF_ORDER_STATUS_RECEIVED)) { } else if (shopStoreSfOrder.getOrder_status().equals(StateCode.SF_ORDER_STATUS_RECEIVED)) {
// 顺丰同城状态15-配送员配送中已取货 // 顺丰同城状态15-配送员配送中已取货
// 商城订单状态 2030-待发货 2040-已发货/待收货确认 // 商城订单状态 2030-待发货 2040-已发货/待收货确认
@ -630,9 +638,10 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
pushRemark = "配送员已取货。"; pushRemark = "配送员已取货。";
} else if (shopStoreSfOrder.getOrder_status().equals(StateCode.SF_ORDER_STATUS_FINISH)) { } else if (shopStoreSfOrder.getOrder_status().equals(StateCode.SF_ORDER_STATUS_FINISH)) {
// 顺丰同城状态17-配送员妥投完单; // 顺丰同城状态17-配送员妥投完单;
// 通知微信用户确认收货
wxOrderShippingService.notifyConfirmReceive(shopStoreSfOrder.getShop_order_id());
pushRemark = "已完成配送"; pushRemark = "已完成配送";
// 通知微信用户确认收货
// wxOrderShippingService.notifyConfirmReceive(shopStoreSfOrder.getShop_order_id());
} }
success = shopOrderInfoService.changeOrderStatus(shopStoreSfOrder.getShop_order_id(), orderStatus, orderIsOutStatus, orderIsShippedStatus); success = shopOrderInfoService.changeOrderStatus(shopStoreSfOrder.getShop_order_id(), orderStatus, orderIsOutStatus, orderIsShippedStatus);
@ -669,8 +678,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
return new ThirdApiRes().fail(2002, "请求签名sign校验失败"); return new ThirdApiRes().fail(2002, "请求签名sign校验失败");
} }
logger.info("接收顺丰订单完成回调返回的 JSON 数据:{}", jsonData); logger.debug("接收顺丰订单完成回调返回的 JSON 数据:{}", jsonData);
// 更改顺丰同城订单状态 // 更改顺丰同城订单状态
ShopStoreSfOrder shopStoreSfOrder = toShopStoreSfOrder(jsonData); ShopStoreSfOrder shopStoreSfOrder = toShopStoreSfOrder(jsonData);
@ -720,6 +728,9 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
// 个推消息推送 // 个推消息推送
pushMessageToStoreEmployee(null, shopStoreSfOrder.getShop_order_id(), "顺丰同城订单[" + shopStoreSfOrder.getShop_order_id() + "]已完成配送。", ""); pushMessageToStoreEmployee(null, shopStoreSfOrder.getShop_order_id(), "顺丰同城订单[" + shopStoreSfOrder.getShop_order_id() + "]已完成配送。", "");
// 通知微信用户确认收货
// wxOrderShippingService.notifyConfirmReceive(shopStoreSfOrder.getShop_order_id());
return new ThirdApiRes().success("success"); return new ThirdApiRes().success("success");
} }

View File

@ -63,6 +63,8 @@ public class WxOrderShippingServiceImpl implements WxOrderShippingService {
*/ */
@Override @Override
public Pair<Boolean, String> uploadShippingInfoToWx(Integer logisticsType, String orderId) { public Pair<Boolean, String> uploadShippingInfoToWx(Integer logisticsType, String orderId) {
log.debug("开始上传发货信息到微信订单ID: {}, 物流类型: {}", orderId, logisticsType);
if (StringUtils.isBlank(orderId)) { if (StringUtils.isBlank(orderId)) {
log.error("缺少订单Id"); log.error("缺少订单Id");
return Pair.of(false, "缺少订单Id"); return Pair.of(false, "缺少订单Id");
@ -108,33 +110,41 @@ public class WxOrderShippingServiceImpl implements WxOrderShippingService {
} }
shippingItem.set("tracking_no", shopOrderLogistics.getOrder_tracking_number()); shippingItem.set("tracking_no", shopOrderLogistics.getOrder_tracking_number());
shippingItem.set("express_company", shopOrderLogistics.getLogistics_number()); shippingItem.set("express_company", shopOrderLogistics.getLogistics_number());
shippingItem.set("contact.receiver_contact", receiverContact);
} else if (logisticsType == 2) { } else if (logisticsType == 2) {
ShopStoreSfOrder shopStoreSfOrder = shopStoreSfOrderService.getBySfOrderId(orderId); ShopStoreSfOrder shopStoreSfOrder = shopStoreSfOrderService.getByShopOrderId(orderId);
if (shopStoreSfOrder == null) { if (shopStoreSfOrder == null) {
log.error("无法获取顺丰同城订单记录订单ID: {}", orderId); log.error("无法获取顺丰同城订单记录订单ID: {}", orderId);
return Pair.of(false, "无法获取顺丰同城订单记录"); return Pair.of(false, "无法获取顺丰同城订单记录");
} }
shippingItem.set("tracking_no", shopStoreSfOrder.getSf_bill_id()); shippingItem.set("tracking_no", shopStoreSfOrder.getSf_bill_id());
shippingItem.set("express_company", "SF"); shippingItem.set("express_company", "SF");
shippingItem.set("contact.receiver_contact", receiverContact);
} }
shippingItem.putOpt("contact", new JSONObject()
.set("receiver_contact", receiverContact));
// Step 4: Prepare request payload // Step 4: Prepare request payload
JSONArray shippingList = new JSONArray().put(shippingItem); JSONArray shippingList = new JSONArray().put(shippingItem);
// String mchId = orderBaseInfo.getMch_id();
JSONObject paramsJSON = new JSONObject() JSONObject paramsJSON = new JSONObject()
.set("order_key.order_number_type", 2) .set("order_key", new JSONObject().set("order_number_type", 2).set("transaction_id", orderBaseInfo.getTransaction_id()))
.set("order_key.transaction_id", orderBaseInfo.getTransaction_id()) // .set("order_key", new JSONObject().set("order_number_type", 1).set("out_trade_no", orderBaseInfo.getOut_trade_no()).set("mchid", mchId))
.set("delivery_mode", 1) .set("delivery_mode", 1)
.set("logistics_type", logisticsType) .set("logistics_type", logisticsType)
.set("shipping_list", shippingList) .set("shipping_list", shippingList)
.set("upload_time", DateTimeUtils.formatDateTimeRFC3339(new Date())) .set("upload_time", DateTimeUtils.formatDateTimeRFC3339(new Date()))
.set("payer.openid", orderBaseInfo.getOpenid()); .set("payer", new JSONObject().set("openid", orderBaseInfo.getOpen_id()));
// Step 5: Send request to WeChat API // Step 5: Send request to WeChat API
String postUrl = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=" + accessToken;
log.debug("发货信息录入请求: {} \n {}", postUrl, paramsJSON);
JSONObject respObj = RestTemplateHttpUtil.sendPost( JSONObject respObj = RestTemplateHttpUtil.sendPost(
"https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=" + accessToken, postUrl,
null, paramsJSON, JSONObject.class null, paramsJSON, JSONObject.class
); );
@ -166,12 +176,17 @@ public class WxOrderShippingServiceImpl implements WxOrderShippingService {
/** /**
* 通知微信用户确认收货 * 通知微信用户确认收货
* 参考https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E4%BA%94%E3%80%81%E7%A1%AE%E8%AE%A4%E6%94%B6%E8%B4%A7%E6%8F%90%E9%86%92%E6%8E%A5%E5%8F%A3 * 参考https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/order-shipping/order-shipping.html#%E4%BA%94%E3%80%81%E7%A1%AE%E8%AE%A4%E6%94%B6%E8%B4%A7%E6%8F%90%E9%86%92%E6%8E%A5%E5%8F%A3
* <p>
* 通过交易单号或商户号+商户单号来指定订单
* 只有物流类型为物流快递时才能进行提醒
* 签收时间由商户传入在给用户发送提醒消息时会显示签收时间签收时间必须在发货时间之后
* *
* @param orderId 订单ID * @param orderId 订单ID
* @return 返回确认收货结果包含成功状态和错误消息 * @return 返回确认收货结果包含成功状态和错误消息
*/ */
@Override @Override
public Pair<Boolean, String> notifyConfirmReceive(String orderId) { public Pair<Boolean, String> notifyConfirmReceive(String orderId) {
log.debug("开始通知微信用户确认收货订单ID: {}", orderId);
if (StrUtil.isBlank(orderId)) { if (StrUtil.isBlank(orderId)) {
return Pair.of(false, "订单ID不能为空"); return Pair.of(false, "订单ID不能为空");
} }
@ -196,8 +211,11 @@ public class WxOrderShippingServiceImpl implements WxOrderShippingService {
.set("merchant_trade_no", orderId) .set("merchant_trade_no", orderId)
.set("received_time", System.currentTimeMillis() / 1000); .set("received_time", System.currentTimeMillis() / 1000);
String postUrl = "https://api.weixin.qq.com/wxa/sec/order/notify_confirm_receive?access_token=" + accessToken;
log.debug("通知微信用户确认收货请求: {} \n {}", postUrl, paramsJSON);
JSONObject respObj = RestTemplateHttpUtil.sendPost( JSONObject respObj = RestTemplateHttpUtil.sendPost(
"https://api.weixin.qq.com/wxa/sec/order/notify_confirm_receive?access_token=" + accessToken, postUrl,
null, paramsJSON, JSONObject.class null, paramsJSON, JSONObject.class
); );

View File

@ -12,10 +12,12 @@
<!--订单对象映射--> <!--订单对象映射-->
<result property="store_id" column="store_id"/> <result property="store_id" column="store_id"/>
<result property="out_trade_no" column="out_trade_no"/> <result property="out_trade_no" column="out_trade_no"/>
<result property="app_id" column="app_id"/>
<result property="mch_id" column="mch_id"/>
<result property="transaction_id" column="transaction_id"/> <result property="transaction_id" column="transaction_id"/>
<result property="subject" column="subject"/> <result property="subject" column="subject"/>
<result property="user_id" column="user_id"/> <result property="user_id" column="user_id"/>
<result property="openid" column="openid"/> <result property="open_id" column="open_id"/>
<result property="lkl_merchant_no" column="lkl_merchant_no"/> <result property="lkl_merchant_no" column="lkl_merchant_no"/>
<result property="lkl_term_no" column="lkl_term_no"/> <result property="lkl_term_no" column="lkl_term_no"/>
<result property="da_mobile" column="da_mobile"/> <result property="da_mobile" column="da_mobile"/>
@ -755,16 +757,19 @@
<select id="getWxOrderBaseInfo" resultMap="WxOrderBaseInfoResult"> <select id="getWxOrderBaseInfo" resultMap="WxOrderBaseInfoResult">
SELECT a.store_id, SELECT a.store_id,
a.order_id as out_trade_no, a.order_id as out_trade_no,
c.deposit_trade_no as transaction_id, f.transaction_id,
c.deposit_subject as subject, f.mch_id,
c.user_id, f.open_id,
c.deposit_buyer_id as openid, f.trade_title as subject,
f.buyer_id as user_id,
<!-- c.deposit_buyer_id as open_id2,-->
d.lkl_merchant_no, d.lkl_merchant_no,
d.lkl_term_no, d.lkl_term_no,
e.da_mobile, e.da_mobile,
e.da_name e.da_name
FROM shop_order_base a FROM shop_order_base a
JOIN pay_consume_deposit c on a.order_id = c.order_id <!-- JOIN pay_consume_deposit c on a.order_id = c.order_id-->
JOIN pay_consume_trade f on a.order_id = f.order_id
JOIN shop_store_base d on a.store_id = d.store_id JOIN shop_store_base d on a.store_id = d.store_id
LEFT JOIN shop_order_delivery_address e on a.order_id = e.order_id LEFT JOIN shop_order_delivery_address e on a.order_id = e.order_id
where a.order_id = #{orderId} where a.order_id = #{orderId}