Преглед изворни кода

对接微信官方收货和定时任务兜底

xw пре 4 дана
родитељ
комит
d2edec6b71

+ 4 - 0
fs-service/src/main/java/com/fs/hisStore/domain/FsStoreOrderScrm.java

@@ -360,6 +360,10 @@ public class FsStoreOrderScrm extends BaseEntity
     @TableField(exist = false)
     private String bankTransactionId;
 
+    /** 支付记录上的小程序 appId(联表查询时填入,用于微信发货等多小程序场景) */
+    @TableField(exist = false)
+    private String paymentAppId;
+
      // 是否审核,1-是,0-否
     private Integer isAudit;
 

+ 1 - 1
fs-service/src/main/java/com/fs/hisStore/service/IFsStoreOrderScrmService.java

@@ -309,7 +309,7 @@ public interface IFsStoreOrderScrmService
      * 查询app商城订单金额统计信息
      * */
     FsStoreOrderAmountScrmStatsVo selectFsStoreOrderAmountScrmStats(FsStoreOrderAmountScrmStatsQueryDto queryDto);
-    R queryReceiptType();
+    R queryReceiptType(Long orderId);
 
     /**
      * 刷新订单结算状态

+ 75 - 29
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreOrderScrmServiceImpl.java

@@ -17,8 +17,6 @@ import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.TypeReference;
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.api.param.OrderListParam;
 import com.fs.api.vo.OrderListVO;
 import com.fs.api.vo.ProductListVO;
@@ -37,7 +35,6 @@ import com.fs.common.utils.IpUtil;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.ip.IpUtils;
-import com.fs.common.utils.spring.SpringUtils;
 import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyDept;
 import com.fs.company.domain.CompanyMoneyLogs;
@@ -5591,7 +5588,7 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         }
     }
     @Override
-    public R queryReceiptType() {
+    public R queryReceiptType(Long orderId) {
         //获取商城配置
         String json = configService.selectConfigByKey("store.config");
         StoreConfig config = JSONUtil.toBean(json, StoreConfig.class);
@@ -5599,6 +5596,13 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
         if (config != null && config.getIsWeChatShipping() != null && config.getIsWeChatShipping()) {
             receiptType = config.getIsWeChatShipping();
         }
+        if (orderId != null) {
+            FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(orderId);
+            if (order != null && Objects.equals(order.getStatus(), OrderInfoEnum.STATUS_2.getValue())) {
+                order.setStatus(OrderInfoEnum.STATUS_3.getValue());
+                fsStoreOrderMapper.updateFsStoreOrder(order);
+            }
+        }
         return R.ok().put("data", receiptType);
     }
 
@@ -5611,50 +5615,92 @@ public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
             StoreConfig config = JSONUtil.toBean(json, StoreConfig.class);
             logger.info("进入微信结算订单定时任务--------------->{}", "start");
             if (config != null && config.getIsWeChatShipping() != null && config.getIsWeChatShipping()) {
-                // 获取未结算订单
+                // 订单主数据来自 fs_store_order_scrm;bank_transaction_id、paymentAppId 来自联表的 fs_store_payment_scrm
                 List<FsStoreOrderScrm> orderScrmList = fsStoreOrderMapper.getUnsettledOrder();
 
-                String payConfig = configService.selectConfigByKey("store.pay");
-                JSONObject js = JSON.parseObject(payConfig);
-                String appId = js.getString("appId");
-
-                if (ObjectUtil.isNotNull(appId) && !appId.isEmpty()) {
-                    final WxMaService wxService = WxMaConfiguration.getMaService(appId);
-
-                    if (!orderScrmList.isEmpty()) {
-                        for (FsStoreOrderScrm order : orderScrmList) {
-                            WxMaOrderShippingInfoGetRequest request = new WxMaOrderShippingInfoGetRequest();
-                            request.setTransactionId(order.getBankTransactionId());
-                            WxMaOrderShippingInfoGetResponse response;
+                if (!orderScrmList.isEmpty()) {
+                    for (FsStoreOrderScrm order : orderScrmList) {
+                        String wxAppId = StrUtil.trim(order.getPaymentAppId());
+                        if (StrUtil.isBlank(wxAppId)) {
+                            logger.warn("refreshOrderSettlementStatus 跳过订单 id={},支付记录未关联小程序 app_id",
+                                    order.getId());
+                            continue;
+                        }
+                        WxMaService wxService;
+                        try {
+                            wxService = WxMaConfiguration.getMaService(wxAppId);
+                        } catch (IllegalArgumentException ex) {
+                            logger.warn("refreshOrderSettlementStatus 跳过订单 id={} appId={}:{}", order.getId(), wxAppId,
+                                    ex.getMessage());
+                            continue;
+                        }
 
-                            try {
-                                response = wxService.getWxMaOrderShippingService().get(request);
+                        WxMaOrderShippingInfoGetRequest request = new WxMaOrderShippingInfoGetRequest();
+                        request.setTransactionId(order.getBankTransactionId());
+                        WxMaOrderShippingInfoGetResponse response;
 
-                                if (response.getErrCode().equals(0)) {
-                                    // 订单状态枚举:(1) 待发货;(2) 已发货;(3) 确认收货;(4) 交易完成;(5) 已退款
-                                    if (response.getOrder().getOrderState().equals(3) || response.getOrder().getOrderState().equals(4)) {
-                                        if (order.getStatus() == OrderInfoEnum.STATUS_2.getValue()) {
-                                            this.finishOrder(order.getId());
-                                        }
+                        try {
+                            response = wxService.getWxMaOrderShippingService().get(request);
+
+                            if (response != null && Objects.equals(response.getErrCode(), 0)) {
+                                // 订单状态枚举:(1) 待发货;(2) 已发货;(3) 确认收货;(4) 交易完成;(5) 已退款
+                                if (response.getOrder() != null
+                                        && (Objects.equals(response.getOrder().getOrderState(), 3)
+                                        || Objects.equals(response.getOrder().getOrderState(), 4))) {
+                                    if (order.getStatus() == OrderInfoEnum.STATUS_2.getValue()) {
+                                        this.finishOrder(order.getId());
                                     }
-                                    logger.info("请求信息------------------------》{}", response);
                                 }
+                                logger.info("refreshOrderSettlementStatus orderId={} appId={} 微信发货查询----------》{}", order.getId(),
+                                        wxAppId, response);
+                            } else if (response != null && isWxShippingGetFinishLocally(response.getErrCode())) {
+                                // 无法再依赖微信查询订单状态时本地办结:50002 账号受限;10060001 支付单不存在;40125 等凭证异常
+                                logger.warn(
+                                        "refreshOrderSettlementStatus 微信 errCode={},发货查询不可用,本地办结 orderId={} appId={} errMsg={}",
+                                        response.getErrCode(), order.getId(), wxAppId, response.getErrMsg());
+                                if (order.getStatus() == OrderInfoEnum.STATUS_2.getValue()) {
+                                    this.finishOrder(order.getId());
+                                }
+                            } else if (response != null) {
+                                logger.info("refreshOrderSettlementStatus orderId={} appId={} errCode={} errMsg={}",
+                                        order.getId(), wxAppId, response.getErrCode(), response.getErrMsg());
+                            }
 
-                            } catch (WxErrorException e) {
-                                logger.info("异常信息------------------------》{}", e.getMessage());
+                        } catch (WxErrorException e) {
+                            Integer wxErr = e.getError() != null ? e.getError().getErrorCode() : null;
+                            if (isWxShippingGetFinishLocally(wxErr)) {
+                                logger.warn("refreshOrderSettlementStatus 微信接口 errCode={},发货查询不可用,本地办结 orderId={} appId={}",
+                                        wxErr, order.getId(), wxAppId);
+                                if (order.getStatus() == OrderInfoEnum.STATUS_2.getValue()) {
+                                    this.finishOrder(order.getId());
+                                }
                                 continue;
                             }
+                            logger.info("refreshOrderSettlementStatus orderId={} appId={} 异常----------》{}", order.getId(),
+                                    wxAppId, e.getMessage());
+                            continue;
                         }
                     }
                 }
             }
         } catch (Exception e) {
-            e.getStackTrace();
+            logger.error("refreshOrderSettlementStatus 执行异常", e);
         } finally {
             logger.info("进入微信结算订单定时任务--------------->{}", "end");
         }
     }
 
+    /**
+     * 查询小程序发货信息时若微信返回下列错误,无法依赖接口同步状态,本地直接将待收货订单办结:<br>
+     * 50002 user limited(小程序/账号受限);10060001 支付单不存在;40125 常见为无效 appsecret 等凭证问题。
+     */
+    private static boolean isWxShippingGetFinishLocally(Integer errCode) {
+        if (errCode == null) {
+            return false;
+        }
+        return errCode == 50002 || errCode == 10060001 || errCode == 40125;
+    }
+
     private static final DateTimeFormatter CST_FORMATTER = DateTimeFormatter
             .ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US)
             .withZone(ZoneId.of("Asia/Shanghai"));

+ 4 - 19
fs-service/src/main/resources/mapper/hisStore/FsStoreOrderScrmMapper.xml

@@ -2085,24 +2085,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <select id="selectAddTuiMoney" resultType="java.lang.Long">
 
     </select>
-    <select id="getUnsettledOrder" resultType="com.fs.hisStore.domain.FsStoreOrderScrm">
-        SELECT
-            sos.*,
-            sps.bank_transaction_id
-        FROM
-            fs_store_order_scrm sos
-                INNER JOIN fs_store_payment_scrm sps ON sos.id = sps.order_id
-        WHERE
-            sos.is_del = 0 and
-            sos.paid = 1
-          AND sps.business_type = 2
-          AND sos.`status` = 2
-          AND sps.`status`=1
-          AND DATEDIFF(
-                      NOW(),
-                      sos.delivery_send_time
-                  ) >= 3
-    </select>
+
 
 <!--    <select id="getDeliveryNote1" resultType="com.fs.hisStore.vo.FsStoreOrderDeliveryNoteExportVO">-->
 <!--        SELECT-->
@@ -2455,10 +2438,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         AND  sps.`status` = 1
     </select>
 
+    <!-- 待同步微信收货状态的订单:主表 fs_store_order_scrm;微信支付单号、小程序 appId 均来自 fs_store_payment_scrm(按 order_id 关联) -->
     <select id="getUnsettledOrder" resultType="com.fs.hisStore.domain.FsStoreOrderScrm">
         SELECT
             sos.*,
-            sps.bank_transaction_id
+            sps.bank_transaction_id,
+            sps.app_id AS paymentAppId
         FROM
             fs_store_order_scrm sos
                 INNER JOIN fs_store_payment_scrm sps ON sos.id = sps.order_id

+ 6 - 1
fs-user-app/src/main/java/com/fs/app/controller/store/StoreOrderScrmController.java

@@ -777,5 +777,10 @@ public class StoreOrderScrmController extends AppBaseController {
         return R.ok().put("count0",count0).put("count1",count1).put("count2",count2).put("afterSalesCount",afterSalesCount);
     }
 
-
+    @Login
+    @ApiOperation("获取确认收货类型")
+    @GetMapping("/queryReceiptType")
+    public R queryReceiptType(@RequestParam(required = false) Long orderId){
+        return orderService.queryReceiptType(orderId);
+    }
 }