Răsfoiți Sursa

feat(order): 优化订单处理和发货功能

- 修改AfterSaleApplyMessageHandler类,移除硬编码的测试数据,改为调用中车商城接口查询真实售后单信息
- 为多个中车售后相关的BO类添加serialVersionUID序列化版本ID
- 在ExternalProductDto类中新增税收编码和可用库存字段
- 在IOrderMainCrrcExtService接口中新增同步订单收货人信息、导出项目订单发货信息等功能方法
- 更新Kd100Util工具类中的测试快递单号和手机号
- 在MessageBo类中新增项目key字段
- 为OrderConfirmBo类添加序列化版本ID
- 重构OrderCreateMessageHandler类,增加省市区乡名称获取逻辑,通过区域查询接口动态获取地址名称
- 新增订单发货导入监听器OrderDeliverImportListener和导入视图对象OrderDeliverImportVo
- 在OrderDeliverServiceImpl类中完善发货逻辑,支持通过物流公司ID查询公司名称,并添加发货商品明细处理
- 扩展OrderDetailVo类,新增数据源和省市区乡镇名称字段
- 新增OrderItemDeliverVo类用于项目订单发货信息导出
肖路 1 săptămână în urmă
părinte
comite
30a82f5211
47 a modificat fișierele cu 1424 adăugiri și 163 ștergeri
  1. 10 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/domain/ExternalProductDto.java
  2. 4 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/service/RemoteExternalProductService.java
  3. 33 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/tongji/RemoteTongJiPullService.java
  4. 10 3
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/RemoteZhongChePullService.java
  5. 4 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/Area.java
  6. 4 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/OrderDeliverGoods.java
  7. 3 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/PendingOrderRecord.java
  8. 4 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/AreaQueryBo.java
  9. 5 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/MessageBo.java
  10. 1 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/OrderConfirmBo.java
  11. 4 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/OrderDetailBo.java
  12. 4 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/PendingOrderListBo.java
  13. 3 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/ZhongCheOrderDeliverBo.java
  14. 2 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/vo/AreaVo.java
  15. 3 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/vo/PendingOrderListVo.java
  16. 4 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/vo/ZhongCheOrderDeliverVo.java
  17. 7 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteComLogisticsCompanyService.java
  18. 33 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/vo/RemoteLogisticsCompanyVo.java
  19. 1 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/zhongche/aftersale/bo/AfterSaleConfirmBo.java
  20. 1 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/zhongche/aftersale/bo/AfterSaleRefundBo.java
  21. 1 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/zhongche/aftersale/bo/AfterSaleRejectBo.java
  22. 1 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/zhongche/aftersale/bo/AfterSaleReturnReceivedBo.java
  23. 21 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/zhongche/vo/OrderDetailVo.java
  24. 1 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/tongji/TongJiPushController.java
  25. 76 1
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/zhongche/ZhongChePullController.java
  26. 12 4
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/zhongche/ZhongChePushController.java
  27. 2 34
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/zhongche/handle/impl/AfterSaleApplyMessageHandler.java
  28. 46 2
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/zhongche/handle/impl/OrderCreateMessageHandler.java
  29. 21 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/dubbo/RemoteExternalProductServiceImpl.java
  30. 75 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/dubbo/RemoteTongJiPullServiceImpl.java
  31. 33 3
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/dubbo/RemoteZhongChePullServiceImpl.java
  32. 171 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderMainCrrcExtController.java
  33. 6 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderDeliverThird.java
  34. 20 8
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderMainCrrcExt.java
  35. 2 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderDeliverBo.java
  36. 52 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderDeliverImportVo.java
  37. 121 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderItemDeliverVo.java
  38. 20 15
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderMainCrrcExtVo.java
  39. 6 1
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/dubbo/RemoteExternalOrderServiceImpl.java
  40. 225 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/listener/OrderDeliverImportListener.java
  41. 28 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderMainCrrcExtService.java
  42. 38 5
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderDeliverServiceImpl.java
  43. 198 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderMainCrrcExtServiceImpl.java
  44. 87 74
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderMainServiceImpl.java
  45. 2 2
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/utils/kd100/Kd100Util.java
  46. 2 1
      ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderProductMapper.xml
  47. 17 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteComLogisticsCompanyServiceImpl.java

+ 10 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/domain/ExternalProductDto.java

@@ -98,4 +98,14 @@ public class ExternalProductDto implements Serializable {
     * */
     private Long minOrderQuantity;
 
+    /**
+     * 税收编码
+     * */
+    private String taxCode;
+
+    /**
+    * 库存
+    * */
+    private Integer availableInventory;
+
 }

+ 4 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/service/RemoteExternalProductService.java

@@ -25,5 +25,9 @@ public interface RemoteExternalProductService {
     * */
     void syncExternalProduct(List<ExternalProductDto> productIds);
 
+    /**
+    * 更新产品库存
+    * */
+    void syncExternalProductInventory(List<ExternalProductDto> products);
 
 }

+ 33 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/tongji/RemoteTongJiPullService.java

@@ -0,0 +1,33 @@
+package org.dromara.external.api.tongji;
+
+import org.dromara.common.core.domain.zhongche.aftersale.bo.AfterSaleConfirmBo;
+import org.dromara.common.core.domain.zhongche.aftersale.bo.AfterSaleRefundBo;
+import org.dromara.common.core.domain.zhongche.aftersale.bo.AfterSaleRejectBo;
+import org.dromara.common.core.domain.zhongche.aftersale.bo.AfterSaleReturnReceivedBo;
+import org.dromara.common.core.exception.api.ZhongcheException;
+import org.dromara.external.api.zhongche.domain.bo.OrderConfirmBo;
+import org.dromara.external.api.zhongche.domain.bo.OrderRejectBo;
+import org.dromara.external.api.zhongche.domain.bo.ZhongCheOrderDeliverBo;
+import org.dromara.external.api.zhongche.domain.vo.GoodsUpdateVo;
+import org.dromara.external.api.zhongche.domain.vo.ZhongCheOrderDeliverVo;
+
+/**
+ * author
+ * 时间:2026/2/25,17:49
+ */
+public interface RemoteTongJiPullService {
+    //接单
+    GoodsUpdateVo mallOrderConfirm(OrderConfirmBo bo) throws ZhongcheException;
+    //拒单
+    GoodsUpdateVo mallOrderReject( OrderRejectBo bo) throws ZhongcheException;
+    //售后接受
+    GoodsUpdateVo mallAftersaleConfirm( AfterSaleConfirmBo bo) throws ZhongcheException;
+    //售后拒绝
+    GoodsUpdateVo mallAftersaleReject(AfterSaleRejectBo bo) throws ZhongcheException;
+    //确认收到退货
+    GoodsUpdateVo mallAftersaleReturnGoodsReceived(AfterSaleReturnReceivedBo bo) throws ZhongcheException;
+    //确认退款
+    GoodsUpdateVo mallAftersaleRefund(AfterSaleRefundBo bo) throws ZhongcheException;
+    //发货
+    ZhongCheOrderDeliverVo mallOrderDeliverGoods(ZhongCheOrderDeliverBo bo) throws ZhongcheException;
+}

+ 10 - 3
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/RemoteZhongChePullService.java

@@ -4,11 +4,12 @@ import org.dromara.common.core.domain.zhongche.aftersale.bo.AfterSaleConfirmBo;
 import org.dromara.common.core.domain.zhongche.aftersale.bo.AfterSaleRefundBo;
 import org.dromara.common.core.domain.zhongche.aftersale.bo.AfterSaleRejectBo;
 import org.dromara.common.core.domain.zhongche.aftersale.bo.AfterSaleReturnReceivedBo;
+import org.dromara.common.core.domain.zhongche.vo.OrderDetailVo;
 import org.dromara.common.core.exception.api.ZhongcheException;
-import org.dromara.external.api.zhongche.domain.bo.OrderConfirmBo;
-import org.dromara.external.api.zhongche.domain.bo.OrderRejectBo;
-import org.dromara.external.api.zhongche.domain.bo.ZhongCheOrderDeliverBo;
+import org.dromara.external.api.zhongche.domain.bo.*;
+import org.dromara.external.api.zhongche.domain.vo.AreaVo;
 import org.dromara.external.api.zhongche.domain.vo.GoodsUpdateVo;
+import org.dromara.external.api.zhongche.domain.vo.PendingOrderListVo;
 import org.dromara.external.api.zhongche.domain.vo.ZhongCheOrderDeliverVo;
 import org.springframework.web.bind.annotation.RequestBody;
 
@@ -17,6 +18,8 @@ import org.springframework.web.bind.annotation.RequestBody;
  * 时间:2026/2/25,17:49
  */
 public interface RemoteZhongChePullService {
+    //获取地区
+    AreaVo areaQuery(AreaQueryBo bo);
     //接单
     GoodsUpdateVo mallOrderConfirm(OrderConfirmBo bo) throws ZhongcheException;
     //拒单
@@ -31,4 +34,8 @@ public interface RemoteZhongChePullService {
     GoodsUpdateVo mallAftersaleRefund(AfterSaleRefundBo bo) throws ZhongcheException;
     //发货
     ZhongCheOrderDeliverVo mallOrderDeliverGoods(ZhongCheOrderDeliverBo bo) throws ZhongcheException;
+    //查询待处理的订单
+    PendingOrderListVo mallOrderPendingList( PendingOrderListBo bo);
+    //查询订单详情
+    OrderDetailVo mallOrderDetail(OrderDetailBo bo);
 }

+ 4 - 1
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/Area.java

@@ -4,10 +4,13 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.io.Serializable;
+
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class Area {
+public class Area implements Serializable {
+    private static final long serialVersionUID = 1L;
     /**
      * 地区id
      */

+ 4 - 1
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/OrderDeliverGoods.java

@@ -3,6 +3,8 @@ package org.dromara.external.api.zhongche.domain;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
 import java.math.BigDecimal;
 
 /**
@@ -12,7 +14,8 @@ import java.math.BigDecimal;
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class OrderDeliverGoods {
+public class OrderDeliverGoods implements Serializable {
+    private static final long serialVersionUID = 1L;
     /**
      * 商品sku
      * 必填

+ 3 - 1
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/PendingOrderRecord.java

@@ -4,6 +4,7 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.io.Serializable;
 import java.math.BigDecimal;
 
 /**
@@ -13,7 +14,8 @@ import java.math.BigDecimal;
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class PendingOrderRecord {
+public class PendingOrderRecord implements Serializable {
+    private static final long serialVersionUID = 1L;
     /**
      * 中车电子商城订单号
      */

+ 4 - 1
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/AreaQueryBo.java

@@ -4,13 +4,16 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.io.Serializable;
+
 /**
  * 地区查询的业务请求参数 (发送给中车商城)
  */
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class AreaQueryBo {
+public class AreaQueryBo implements Serializable {
+    private static final long serialVersionUID = 1L;
     /**
      * 级次:1 省级,2市级,3县级, 4区级
      * 必填

+ 5 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/MessageBo.java

@@ -32,4 +32,9 @@ public class MessageBo {
     private String time;
 
     private String accountName;
+
+    /**
+    * 项目key
+    * */
+    private String itemKey;
 }

+ 1 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/OrderConfirmBo.java

@@ -14,6 +14,7 @@ import java.io.Serializable;
 @NoArgsConstructor
 @AllArgsConstructor
 public class OrderConfirmBo implements Serializable {
+    private static final long serialVersionUID = 1L;
     /**
      * 中车电子商城订单号
      * 必填

+ 4 - 1
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/OrderDetailBo.java

@@ -2,6 +2,8 @@ package org.dromara.external.api.zhongche.domain.bo;
 
 import lombok.*;
 
+import java.io.Serializable;
+
 /**
  * 查询订单详情的业务请求参数
  * 对应 5.3.1.4.1 业务参数
@@ -11,7 +13,8 @@ import lombok.*;
 //@AllArgsConstructor
 @Setter
 @Getter
-public class OrderDetailBo {
+public class OrderDetailBo implements Serializable {
+    private static final long serialVersionUID = 1L;
     /**
      * 中车电子商城订单号
      * 必填

+ 4 - 1
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/PendingOrderListBo.java

@@ -4,6 +4,8 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.io.Serializable;
+
 /**
  * 查询待处理订单列表的业务请求参数
  * 对应 5.3.6.4.1 业务参数
@@ -11,7 +13,8 @@ import lombok.NoArgsConstructor;
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class PendingOrderListBo {
+public class PendingOrderListBo implements Serializable {
+    private static final long serialVersionUID = 1L;
     /**
      * 当前页
      * 必填

+ 3 - 1
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/ZhongCheOrderDeliverBo.java

@@ -5,6 +5,7 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 import org.dromara.external.api.zhongche.domain.OrderDeliverGoods;
 
+import java.io.Serializable;
 import java.util.List;
 
 /**
@@ -14,7 +15,8 @@ import java.util.List;
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class ZhongCheOrderDeliverBo {
+public class ZhongCheOrderDeliverBo implements Serializable {
+    private static final long serialVersionUID = 1L;
     /**
      * 中车电子商城订单号
      * 必填

+ 2 - 1
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/vo/AreaVo.java

@@ -5,12 +5,13 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 import org.dromara.external.api.zhongche.domain.Area;
 
+import java.io.Serializable;
 import java.util.List;
 
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class AreaVo {
+public class AreaVo implements Serializable {
     /**
      * 地区列表
      */

+ 3 - 1
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/vo/PendingOrderListVo.java

@@ -5,6 +5,7 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 import org.dromara.external.api.zhongche.domain.PendingOrderRecord;
 
+import java.io.Serializable;
 import java.util.List;
 
 /**
@@ -14,7 +15,8 @@ import java.util.List;
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class PendingOrderListVo {
+public class PendingOrderListVo implements Serializable {
+    private static final long serialVersionUID = 1L;
     /**
      * 当前页
      */

+ 4 - 1
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/vo/ZhongCheOrderDeliverVo.java

@@ -4,6 +4,8 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.io.Serializable;
+
 /**
  * 发货的业务响应参数
  * 对应 5.3.5.5.1 业务参数
@@ -11,7 +13,8 @@ import lombok.NoArgsConstructor;
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class ZhongCheOrderDeliverVo {
+public class ZhongCheOrderDeliverVo implements Serializable {
+    private static final long serialVersionUID = 1L;
     /**
      * 发货单编号
      * 必填

+ 7 - 0
ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteComLogisticsCompanyService.java

@@ -2,6 +2,7 @@ package org.dromara.system.api;
 
 import org.dromara.common.core.domain.zhongche.domain.DeliveryTrack;
 import org.dromara.common.core.validate.enumd.EnumPattern;
+import org.dromara.system.api.domain.vo.RemoteLogisticsCompanyVo;
 
 import java.util.List;
 import java.util.Map;
@@ -14,4 +15,10 @@ public interface RemoteComLogisticsCompanyService {
     String selectLogisticsCompanyNameById(Long ids);
 
     Map<Long ,String> selectLogisticsCompanyNameByIds(List<Long> ids);
+
+
+    /**
+    * 通过名称获取id
+    * */
+    RemoteLogisticsCompanyVo selectLogisticsCompanyByName(String name);
 }

+ 33 - 0
ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/vo/RemoteLogisticsCompanyVo.java

@@ -0,0 +1,33 @@
+package org.dromara.system.api.domain.vo;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * @author
+ * @date 2026/5/21 上午2:42
+ */
+@Data
+public class RemoteLogisticsCompanyVo implements Serializable {
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 物流公司编号
+     */
+    private String logisticsNo;
+
+    /**
+     * 物流公司编码
+     */
+    private String logisticsCode;
+
+    /**
+     * 物流公司名称
+     */
+    private String logisticsName;
+}

+ 1 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/zhongche/aftersale/bo/AfterSaleConfirmBo.java

@@ -15,6 +15,7 @@ import java.io.Serializable;
 @NoArgsConstructor
 @AllArgsConstructor
 public class AfterSaleConfirmBo implements Serializable {
+    private static final long serialVersionUID = 1L;
     /**
      * 中车电子商城售后单号
      * 必填,长度20

+ 1 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/zhongche/aftersale/bo/AfterSaleRefundBo.java

@@ -14,6 +14,7 @@ import java.io.Serializable;
 @NoArgsConstructor
 @AllArgsConstructor
 public class AfterSaleRefundBo implements Serializable {
+    private static final long serialVersionUID = 1L;
     /**
      * 中车电子商城售后单号
      * 必填,长度20

+ 1 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/zhongche/aftersale/bo/AfterSaleRejectBo.java

@@ -10,6 +10,7 @@ import java.io.Serializable;
 @NoArgsConstructor
 @AllArgsConstructor
 public class AfterSaleRejectBo implements Serializable {
+    private static final long serialVersionUID = 1L;
     /**
      * 中车电子商城售后单号
      * 必填,长度20

+ 1 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/zhongche/aftersale/bo/AfterSaleReturnReceivedBo.java

@@ -14,6 +14,7 @@ import java.io.Serializable;
 @NoArgsConstructor
 @AllArgsConstructor
 public class AfterSaleReturnReceivedBo implements Serializable {
+    private static final long serialVersionUID = 1L;
     /**
      * 中车电子商城售后单号
      * 必填,长度20

+ 21 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/zhongche/vo/OrderDetailVo.java

@@ -15,6 +15,11 @@ import java.util.List;
 @NoArgsConstructor
 @AllArgsConstructor
 public class OrderDetailVo implements Serializable {
+    private static final long serialVersionUID = 1L;
+    /**
+    * 订单来源
+    * */
+    private String dataSource;
     /**
      * 中车电子商城订单号
      */
@@ -55,18 +60,34 @@ public class OrderDetailVo implements Serializable {
      * 一级地址编码:收货人省份地址编码
      */
     private String provinceId;
+    /**
+     * 省名称
+     */
+    private String provinceName;
     /**
      * 二级地址编码:收货人市级地址编码
      */
     private String cityId;
+    /**
+     * 市名称
+     */
+    private String cityName;
     /**
      * 三级地址编码:收货人县(区)级地址编码
      */
     private String countyId;
+    /**
+     * 区名称
+     */
+    private String countyName;
     /**
      * 四级地址编码:收货人乡镇地址编码(如果该地区有四级地址,则必须传递四级地址,没有四级地址则传 0)
      */
     private String townId;
+    /**
+     * 乡镇名称
+     */
+    private String townName;
     /**
      * 详细地址
      */

+ 1 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/tongji/TongJiPushController.java

@@ -724,6 +724,7 @@ public class TongJiPushController {
         // 5. 按消息类型处理业务
         MessageVo messageVo;
         try {
+            messageBo.setItemKey("zhongche");
             messageVo = mallMessageDispatcher.dispatch(messageBo);
         } catch (Exception e) {
             log.error("消息处理异常,messageId={}", messageBo.getId(), e);

+ 76 - 1
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/zhongche/ZhongChePullController.java

@@ -58,6 +58,7 @@ public class ZhongChePullController {
     private static final String CLIENT_ID = "KFZnKGiDsJ7";
     private static final String PRIVATE_KEY = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgQu0H97EPqkgz1YS5LkzZNmkG3mS5Er8rJ2LSoJtuOlGgCgYIKoEcz1UBgi2hRANCAARP6NYwTHpW2QTL8A2f2hpgunEpDVkJBhErBQPLqNS/Si5Q+9I9wUpCYdk1EvB5Hw6yzkE4bYk5IZM1j+/SnNFn"; // 电商平台私钥
     private static final String ZC_PUBLIC_KEY = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE9ITEKJdH9o1K9AeQYY7zNMo/q5/cdce+9jbawURTPEpBKAx4VkB+lRkb5e5YL+Be4pPM464rPvLyfqGNJvL6uQ=="; // 中车公钥
+    private final String username = "20240316001";
     //测试环境
     // 中车地区查询接口地址(替换为真实域名)
 //    private static final String AREA_QUERY_URL = "https://supply-test.crrcgo.cc/mallapi/";
@@ -78,6 +79,7 @@ public class ZhongChePullController {
         // 1. 校验业务请求参数(自身先校验,避免无效调用电商平台)
         //1 省级,2市级,3县级, 4区级
         //父级地址id	当查询省级时填0
+        log.info("中车地区查询 - 参数:{}", bo);
         if (bo.getLevel() == null || !List.of(1, 2, 3, 4).contains(bo.getLevel())) {
             throw new RuntimeException("级次(level)必填,且仅支持1/2/3/4");
         }
@@ -463,7 +465,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/order/detail")
     public OrderDetailVo mallOrderDetail(@RequestBody OrderDetailBo bo) {
         ZCR responseDto = doZcPost("/api/mall/order/detail", bo);
+        log.info("查询订单详情参数:{}",JSONUtil.toJsonStr(bo));
         OrderDetailVo orderDetailVo = parseZcResponse(responseDto, OrderDetailVo.class);
+        log.info("查询订单详情结果:{}", orderDetailVo);
         return orderDetailVo;
     }
 
@@ -471,7 +475,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/order/confirm")
     public GoodsUpdateVo mallOrderConfirm(@RequestBody OrderConfirmBo bo) throws ZhongcheException {
         ZCR responseDto = doZcPost("/api/mall/order/confirm", bo);
+        log.info("接单参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("接单结果:{}", zcr);
         return zcr;
     }
 
@@ -479,7 +485,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/order/goods/append")
     public GoodsUpdateVo mallOrderGoodsAppend(@RequestBody OrderGoodsAppendBo bo) {
         ZCR responseDto = doZcPost("/api/mall/order/goods/append", bo);
+        log.info("同步商品协商发货时间参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("同步商品协商发货时间结果:{}", zcr);
         return zcr;
     }
 
@@ -487,7 +495,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/order/reject")
     public GoodsUpdateVo mallOrderReject(@RequestBody OrderRejectBo bo) throws ZhongcheException {
         ZCR responseDto = doZcPost("/api/mall/order/reject", bo);
+        log.info("拒单参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("拒单结果:{}", zcr);
         return zcr;
     }
 
@@ -495,15 +505,20 @@ public class ZhongChePullController {
     @PostMapping("/mall/order/deliver/goods")
     public ZhongCheOrderDeliverVo mallOrderDeliverGoods(@RequestBody ZhongCheOrderDeliverBo bo) {
         ZCR responseDto = doZcPost("/api/mall/order/deliver/goods", bo);
+        log.info("发货参数:{}",JSONUtil.toJsonStr(bo));
         ZhongCheOrderDeliverVo zcr = parseZcResponse(responseDto, ZhongCheOrderDeliverVo.class);
+        log.info("发货结果:{}", zcr);
         return zcr;
     }
 
     //TODO 5.3.6	查询待处理订单列表
     @PostMapping("/mall/order/pending/list")
-    public PendingOrderListVo mallOrderPendingList(@RequestBody ZCTokenBo bo) {
+    public PendingOrderListVo mallOrderPendingList(@RequestBody PendingOrderListBo bo) {
+        bo.setAccount(username);
         ZCR responseDto = doZcPost("/api/mall/order/pending/list", bo);
+        log.info("查询待处理订单列表参数:{}",JSONUtil.toJsonStr(bo));
         PendingOrderListVo zcr = parseZcResponse(responseDto, PendingOrderListVo.class);
+        log.info("查询待处理订单列表结果:{}", zcr);
         return zcr;
     }
 
@@ -511,7 +526,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/order/delivered/notice")
     public GoodsUpdateVo mallOrderDeliveredNotice(@RequestBody OrderDeliveredNoticeBo bo) {
         ZCR responseDto = doZcPost("/api/mall/order/delivered/notice", bo);
+        log.info("妥投通知参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("妥投通知结果:{}", zcr);
         return zcr;
     }
 
@@ -519,7 +536,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/order/query/outgoing")
     public OutgoingVo mallOrderQueryOutgoing(@RequestBody OutgoingQueryBo bo) {
         ZCR responseDto = doZcPost("/api/mall/order/query/outgoing", bo);
+        log.info("查询发货单信息参数:{}",JSONUtil.toJsonStr(bo));
         OutgoingVo zcr = parseZcResponse(responseDto, OutgoingVo.class);
+        log.info("查询发货单信息结果:{}", zcr);
         return zcr;
     }
 
@@ -527,7 +546,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/prepare/order/detail")
     public PrepareOrderDetailRespVo mallPrepareOrderDetail(@RequestBody PrepareOrderDetailReqBo bo) {
         ZCR responseDto = doZcPost("/api/mall/prepare/order/detail", bo);
+        log.info("查询备货单详情参数:{}",JSONUtil.toJsonStr(bo));
         PrepareOrderDetailRespVo zcr = parseZcResponse(responseDto, PrepareOrderDetailRespVo.class);
+        log.info("查询备货单详情结果:{}", zcr);
         return zcr;
     }
 
@@ -535,7 +556,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/prepare/order/goods")
     public GoodsUpdateVo mallPrepareOrderGoods(@RequestBody PrepareOrderDataBo bo) {
         ZCR responseDto = doZcPost("/api/mall/prepare/order/goods", bo);
+        log.info("备货参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("备货结果:{}", zcr);
         return zcr;
     }
 
@@ -544,7 +567,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/prepare/order/confirm/cancel")
     public GoodsUpdateVo mallPrepareOrderConfirmCancel(@RequestBody PrepareOrderDetailReqBo bo) {
         ZCR responseDto = doZcPost("/api/mall/prepare/order/confirm/cancel", bo);
+        log.info("确认取消备货单参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("确认取消备货单结果:{}", zcr);
         return zcr;
     }
 
@@ -560,7 +585,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/order/cancel/audit/judge")
     public GoodsUpdateVo mallOrderCancelAuditJudge(@RequestBody OrderCancelAuditBo bo) {
         ZCR responseDto = doZcPost("/api/mall/order/cancel/audit/judge", bo);
+        log.info("审核订单取消参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("审核订单取消结果:{}", zcr);
         return zcr;
     }
     //5.4.1	查询售后单详情
@@ -578,7 +605,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/aftersale/detail")
     public AfterSaleDetailVo mallAftersaleDetail(@RequestBody AfterSaleDetailBo bo) {
         ZCR responseDto = doZcPost("/api/mall/aftersale/detail", bo);
+        log.info("查询售后单详情参数:{}",JSONUtil.toJsonStr(bo));
         AfterSaleDetailVo zcr = parseZcResponse(responseDto, AfterSaleDetailVo.class);
+        log.info("查询售后单详情结果:{}", zcr);
         return zcr;
     }
 
@@ -586,7 +615,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/aftersale/confirm")
     public GoodsUpdateVo mallAftersaleConfirm(@RequestBody AfterSaleConfirmBo bo) throws ZhongcheException{
         ZCR responseDto = doZcPost("/api/mall/aftersale/confirm", bo);
+        log.info("接受售后参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("接受售后结果:{}", zcr);
         return zcr;
     }
 
@@ -594,7 +625,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/aftersale/reject")
     public GoodsUpdateVo mallAftersaleReject(@RequestBody AfterSaleRejectBo bo) throws ZhongcheException{
         ZCR responseDto = doZcPost("/api/mall/aftersale/reject", bo);
+        log.info("拒绝售后参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("拒绝售后结果:{}", zcr);
         return zcr;
     }
 
@@ -602,7 +635,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/aftersale/return/goods/received")
     public GoodsUpdateVo mallAftersaleReturnGoodsReceived(@RequestBody AfterSaleReturnReceivedBo bo) throws ZhongcheException{
         ZCR responseDto = doZcPost("/api/mall/aftersale/return/goods/received", bo);
+        log.info("确认收到退货参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("确认收到退货结果:{}", zcr);
         return zcr;
     }
 
@@ -610,7 +645,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/aftersale/deliver/goods")
     public AfterSaleDeliverGoodsVo mallAftersaleDeliverGoods(@RequestBody AfterSaleDeliverGoodsBo bo) {
         ZCR responseDto = doZcPost("/api/mall/aftersale/deliver/goods", bo);
+        log.info("换货新品发货参数:{}",JSONUtil.toJsonStr(bo));
         AfterSaleDeliverGoodsVo zcr = parseZcResponse(responseDto, AfterSaleDeliverGoodsVo.class);
+        log.info("换货新品发货结果:{}", zcr);
         return zcr;
     }
 
@@ -618,7 +655,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/aftersale/pending/list")
     public AfterSalePendingListVo mallAftersalePendingList(@RequestBody AfterSalePendingListBo bo) {
         ZCR responseDto = doZcPost("/api/mall/aftersale/pending/list", bo);
+        log.info("查询待处理售后单列表参数:{}",JSONUtil.toJsonStr(bo));
         AfterSalePendingListVo zcr = parseZcResponse(responseDto, AfterSalePendingListVo.class);
+        log.info("查询待处理售后单列表结果:{}", zcr);
         return zcr;
     }
 
@@ -626,7 +665,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/aftersale/query/outgoing")
     public AfterSaleQueryOutgoingVo mallAftersaleQueryOutgoing(@RequestBody AfterSaleQueryOutgoingBo bo) {
         ZCR responseDto = doZcPost("/api/mall/aftersale/query/outgoing", bo);
+        log.info("查询换货新品发货单信息参数:{}",JSONUtil.toJsonStr(bo));
         AfterSaleQueryOutgoingVo zcr = parseZcResponse(responseDto, AfterSaleQueryOutgoingVo.class);
+        log.info("查询换货新品发货单信息结果:{}", zcr);
         return zcr;
     }
 
@@ -634,7 +675,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/aftersale/offline/create")
     public AfterSaleOfflineCreateVo mallAftersaleOfflineCreate(@RequestBody AfterSaleOfflineCreateBo bo) {
         ZCR responseDto = doZcPost("/api/mall/aftersale/offline/create", bo);
+        log.info("线下售后参数:{}",JSONUtil.toJsonStr(bo));
         AfterSaleOfflineCreateVo zcr = parseZcResponse(responseDto, AfterSaleOfflineCreateVo.class);
+        log.info("线下售后结果:{}", zcr);
         return zcr;
     }
 
@@ -642,7 +685,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/aftersale/refund")
     public GoodsUpdateVo mallAftersaleRefund(@RequestBody AfterSaleRefundBo bo) throws ZhongcheException{
         ZCR responseDto = doZcPost("/api/mall/aftersale/refund", bo);
+        log.info("确认退款参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("确认退款结果:{}", zcr);
         return zcr;
     }
 
@@ -651,7 +696,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/invoice/apply/detail")
     public InvoiceApplyDetailVo mallInvoiceApplyDetail(@RequestBody InvoiceApplyDetailBo bo) {
         ZCR responseDto = doZcPost("/api/mall/invoice/apply/detail", bo);
+        log.info("查询开票信息参数:{}",JSONUtil.toJsonStr(bo));
         InvoiceApplyDetailVo zcr = parseZcResponse(responseDto, InvoiceApplyDetailVo.class);
+        log.info("查询开票信息结果:{}", zcr);
         return zcr;
 
     }
@@ -660,7 +707,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/invoice/apply/orders")
     public InvoiceApplyOrdersVo mallInvoiceApplyOrders(@RequestBody InvoiceApplyOrdersBo bo) {
         ZCR responseDto = doZcPost("/api/mall/invoice/apply/orders", bo);
+        log.info("查询开票申请订单列表参数:{}",JSONUtil.toJsonStr(bo));
         InvoiceApplyOrdersVo zcr = parseZcResponse(responseDto, InvoiceApplyOrdersVo.class);
+        log.info("查询开票申请订单列表结果:{}", zcr);
         return zcr;
 
     }
@@ -669,7 +718,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/invoice/apply/reject")
     public GoodsUpdateVo mallInvoiceApplyReject(@RequestBody InvoiceApplyRejectBo bo) {
         ZCR responseDto = doZcPost("/api/mall/invoice/apply/reject", bo);
+        log.info("拒绝开票参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("拒绝开票结果:{}", zcr);
         return zcr;
     }
 
@@ -677,7 +728,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/invoice/sync/invoiceinfos")
     public GoodsUpdateVo mallInvoiceSyncInvoiceInfos(@RequestBody InvoiceSyncInvoiceInfosBo bo) {
         ZCR responseDto = doZcPost("/api/mall/invoice/sync/invoiceinfos", bo);
+        log.info("电商同步开票信息参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("电商同步开票信息结果:{}", zcr);
         return zcr;
     }
 
@@ -686,7 +739,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/invoice/sync/waybill")
     public GoodsUpdateVo mallInvoiceSyncWaybill(@RequestBody InvoiceSyncWaybillBo bo) {
         ZCR responseDto = doZcPost("/api/mall/invoice/sync/waybill", bo);
+        log.info("同步纸质发票邮寄信息参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("同步纸质发票邮寄信息结果:{}", zcr);
         return zcr;
     }
 
@@ -694,7 +749,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/invoice/delivered/notice")
     public GoodsUpdateVo mallInvoiceDeliveredNotice(@RequestBody InvoiceDeliveredNoticeBo bo) {
         ZCR responseDto = doZcPost("/api/mall/invoice/delivered/notice", bo);
+        log.info("发票妥投通知参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("发票妥投通知结果:{}", zcr);
         return zcr;
     }
 
@@ -702,7 +759,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/invoice/apply/waitlist")
     public InvoiceApplyWaitlistVo mallInvoiceApplyWaitList(@RequestBody InvoiceApplyWaitlistBo bo) {
         ZCR responseDto = doZcPost("/api/mall/invoice/apply/waitlist", bo);
+        log.info("查询待开票申请单列表参数:{}",JSONUtil.toJsonStr(bo));
         InvoiceApplyWaitlistVo zcr = parseZcResponse(responseDto, InvoiceApplyWaitlistVo.class);
+        log.info("查询待开票申请单列表结果:{}", zcr);
         return zcr;
     }
 
@@ -710,7 +769,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/invoice/refund/agree")
     public GoodsUpdateVo mallInvoiceRefundAgree(@RequestBody InvoiceRefundAgreeBo bo) {
         ZCR responseDto = doZcPost("/api/mall/invoice/refund/agree", bo);
+        log.info("电商同意退票参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("电商同意退票结果:{}", zcr);
         return zcr;
     }
 
@@ -719,7 +780,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/invoice/refund/finish")
     public GoodsUpdateVo mallInvoiceRefundFinish(@RequestBody InvoiceRefundFinishBo bo) {
         ZCR responseDto = doZcPost("/api/mall/invoice/refund/finish", bo);
+        log.info("电商确认完成退票参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo zcr = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("电商确认完成退票结果:{}", zcr);
         return zcr;
     }
 
@@ -727,7 +790,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/invoice/refund/reject")
     public GoodsUpdateVo mallInvoiceRefundReject(@RequestBody InvoiceRefundRejectBo bo) {
         ZCR responseDto = doZcPost("/api/mall/invoice/refund/reject", bo);
+        log.info("电商拒绝退票申请参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo goodsUpdateVo = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("电商拒绝退票申请结果:{}", goodsUpdateVo);
         return goodsUpdateVo;
     }
 
@@ -735,7 +800,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/settlement/detail")
     public SettlementDetailVo mallSettlementDetail(@RequestBody SettlementDetailBo bo) {
         ZCR responseDto = doZcPost("/api/mall/settlement/detail", bo);
+        log.info("查询结算单详情参数:{}",JSONUtil.toJsonStr(bo));
         SettlementDetailVo settlementDetailVo = parseZcResponse(responseDto, SettlementDetailVo.class);
+        log.info("查询结算单详情结果:{}", settlementDetailVo);
         return settlementDetailVo;
     }
 
@@ -743,7 +810,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/settlement/apply/orders")
     public SettlementApplyOrdersVo mallSettlementApplyOrders(@RequestBody SettlementApplyOrdersBo bo) {
         ZCR responseDto = doZcPost("/api/mall/settlement/apply/orders", bo);
+        log.info("查询结算单订单列表参数:{}",JSONUtil.toJsonStr(bo));
         SettlementApplyOrdersVo settlementApplyOrdersVo = parseZcResponse(responseDto, SettlementApplyOrdersVo.class);
+        log.info("查询结算单订单列表结果:{}", settlementApplyOrdersVo);
         return settlementApplyOrdersVo;
     }
 
@@ -752,7 +821,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/settlement/confirm")
     public GoodsUpdateVo mallSettlementConfirm(@RequestBody SettlementConfirmBo bo) {
         ZCR responseDto = doZcPost("/api/mall/settlement/confirm", bo);
+        log.info("结算单确认结算参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo goodsUpdateVo = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("结算单确认结算结果:{}", goodsUpdateVo);
         return goodsUpdateVo;
     }
 
@@ -760,7 +831,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/settlement/payment/detail")
     public SettlementPaymentDetailVo mallSettlementPaymentDetail( @RequestBody SettlementPaymentDetailBo bo) {
         ZCR responseDto = doZcPost("/api/mall/settlement/payment/detail", bo);
+        log.info("结算单付款详情参数:{}",JSONUtil.toJsonStr(bo));
         SettlementPaymentDetailVo settlementPaymentDetailVo = parseZcResponse(responseDto, SettlementPaymentDetailVo.class);
+        log.info("结算单付款详情结果:{}", settlementPaymentDetailVo);
         return settlementPaymentDetailVo;
 
     }
@@ -769,7 +842,9 @@ public class ZhongChePullController {
     @PostMapping("/mall/settlement/confirm/payment")
     public GoodsUpdateVo mallSettlementConfirmPayment( @RequestBody SettlementConfirmPaymentBo bo) {
         ZCR responseDto = doZcPost("/api/mall/settlement/confirm/payment", bo);
+        log.info("结算单确认收款参数:{}",JSONUtil.toJsonStr(bo));
         GoodsUpdateVo goodsUpdateVo = parseZcResponse(responseDto, GoodsUpdateVo.class);
+        log.info("结算单确认收款结果:{}", goodsUpdateVo);
         return goodsUpdateVo;
     }
 

+ 12 - 4
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/zhongche/ZhongChePushController.java

@@ -318,13 +318,17 @@ public class ZhongChePushController {
             stocksResult.setAreaId(areaId == null ? "" : areaId); // 地区id为空时赋值空字符串,保证格式统一
 
             if (nowInventory > 0){
-                //有货
-                stocksResult.setStockState("1");
-                stocksResult.setStockStateDesc("下单立即发货");
+
                 if (goodsNum <= nowInventory){
+                    //有货
+                    stocksResult.setStockState("1");
+                    stocksResult.setStockStateDesc("下单立即发货");
                     stocksResult.setRemainNum(nowInventory.intValue());
                 }else {
-                    stocksResult.setRemainNum(0);
+                    //无货
+                    stocksResult.setStockState("5");
+                    stocksResult.setStockStateDesc("无货");
+                    stocksResult.setRemainNum(-999);
                 }
             }else {
                 //无货
@@ -497,6 +501,7 @@ public class ZhongChePushController {
     // 4.5查询物流信息(物流信息尚未实现)
     @PostMapping("/get/track")
     public ZCR getTrack(@RequestBody ZCTokenBo zcTokenBo) {
+        log.info("物流信息查询 - 接口请求参数:{}", JSONUtil.toJsonStr(zcTokenBo));
         // 1. 公共请求参数校验(含签名、版本、clientId等,复用已有逻辑)
         ZCR checkResult = checkPublicParams(zcTokenBo);
         if (!"0".equals(checkResult.getRespCode())) {
@@ -562,6 +567,7 @@ public class ZhongChePushController {
     //4.6 查询电商平台订单号
     @PostMapping("/get/mallOrderNo")
     public ZCR getMallOrderNo(@RequestBody ZCTokenBo zcTokenBo) {
+        log.info("查询电商订单号 - 请求参数:{}", JSONUtil.toJsonStr(zcTokenBo));
         //1. 公共请求参数校验
         ZCR checkResult = checkPublicParams(zcTokenBo);
         if (!"0".equals(checkResult.getRespCode())) {
@@ -629,6 +635,7 @@ public class ZhongChePushController {
     //4.7 查询电商平台售后单号
     @PostMapping("/get/mallAfterSaleNo")
     public ZCR getMallAfterSaleNo(@RequestBody ZCTokenBo zcTokenBo) {
+        log.info("查询售后单号 - 请求参数:{}", JSONUtil.toJsonStr(zcTokenBo));
         // 1. 公共请求参数校验
         ZCR checkResult = checkPublicParams(zcTokenBo);
         if (!"0".equals(checkResult.getRespCode())) {
@@ -725,6 +732,7 @@ public class ZhongChePushController {
         // 5. 按消息类型处理业务
         MessageVo messageVo;
         try {
+            messageBo.setItemKey("zhongche");
             messageVo = mallMessageDispatcher.dispatch(messageBo);
         } catch (Exception e) {
             log.error("消息处理异常,messageId={}", messageBo.getId(), e);

+ 2 - 34
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/zhongche/handle/impl/AfterSaleApplyMessageHandler.java

@@ -57,40 +57,8 @@ public class AfterSaleApplyMessageHandler implements MallMessageHandler {
         String afterSaleNo = (String) messageBo.getContent().get("afterSaleNo");
         AfterSaleDetailBo bo = new AfterSaleDetailBo();
         bo.setAfterSaleNo(afterSaleNo);
-
-        AfterSaleGoods goods = new AfterSaleGoods();
-        goods.setGoodsId("362032");
-        goods.setNum(new BigDecimal("1.0000"));
-        goods.setNeedDetectionReport(0);
-        goods.setHasPackage(1);
-        goods.setPackageDesc("10");
-
-        AfterSaleReason reason = new AfterSaleReason();
-        reason.setReasonTypeName("错发");
-        reason.setReasonTypeCode("1");
-        reason.setReason("1111");
-        reason.setImageList(new ArrayList<>());
-
-        AfterSalePick pick = new AfterSalePick();
-        pick.setPickType("3");
-        pick.setTownId("0");
-
-        AfterSaleDetailVo afterSaleDetailVo = new AfterSaleDetailVo();
-
-        afterSaleDetailVo.setAfterSaleNo("1471137739549315072");
-        afterSaleDetailVo.setPurchaserAfterSaleNo("1471137739675144192");
-        afterSaleDetailVo.setOrderNo("20260210110174131");
-
-        afterSaleDetailVo.setAfterSaleType("1");
-        afterSaleDetailVo.setAfterSaleStatus("10");
-        afterSaleDetailVo.setGoodsReturnStatus("1");
-        afterSaleDetailVo.setApplyTime("20260211133610");
-
-        afterSaleDetailVo.setAfterSaleReason(reason);
-        afterSaleDetailVo.setAfterSaleGoods(goods);
-        afterSaleDetailVo.setAfterSalePick(pick);
-
-
+        //查询售后单
+        AfterSaleDetailVo afterSaleDetailVo = zhongChePullController.mallAftersaleDetail(bo);
         OrderReturnDto orderReturnDto = remoteExternalOrderService.createReturnOrder(afterSaleDetailVo);
 
         if (orderReturnDto.getSuccess() == true){

+ 46 - 2
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/zhongche/handle/impl/OrderCreateMessageHandler.java

@@ -1,5 +1,6 @@
 package org.dromara.external.controller.zhongche.handle.impl;
 
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
@@ -8,25 +9,32 @@ import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.common.core.domain.zhongche.domain.OrderGoodsItem;
 import org.dromara.common.core.domain.zhongche.domain.ZhongCheOrderInvoice;
 import org.dromara.common.core.domain.zhongche.vo.OrderDetailVo;
+import org.dromara.external.api.zhongche.domain.bo.AreaQueryBo;
 import org.dromara.external.api.zhongche.domain.bo.MessageBo;
 import org.dromara.external.api.zhongche.domain.bo.OrderConfirmBo;
 import org.dromara.external.api.zhongche.domain.bo.OrderDetailBo;
+import org.dromara.external.api.zhongche.domain.vo.AreaVo;
 import org.dromara.external.api.zhongche.domain.vo.GoodsUpdateVo;
 import org.dromara.external.api.zhongche.domain.vo.MessageVo;
 import org.dromara.external.controller.zhongche.ZhongChePullController;
 import org.dromara.external.controller.zhongche.handle.MallMessageHandler;
+import org.dromara.external.domain.ExternalItem;
 import org.dromara.external.domain.ExternalProduct;
 import org.dromara.external.enums.MallMessageTypeEnum;
 import org.dromara.external.mapper.ExternalProductMapper;
+import org.dromara.external.service.IExternalItemService;
 import org.dromara.external.service.IExternalProductService;
 import org.dromara.product.api.RemoteExternalOrderService;
 import org.dromara.product.api.domain.dto.OrderNoDto;
 import org.springframework.stereotype.Component;
+import org.dromara.external.api.zhongche.domain.Area;
 import org.springframework.web.bind.annotation.RequestBody;
 
 import java.math.BigDecimal;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 @Component
 @Slf4j
@@ -37,6 +45,8 @@ public class OrderCreateMessageHandler implements MallMessageHandler {
 
     private final IExternalProductService externalProductService;
 
+    private final IExternalItemService externalItemService;
+
     @DubboReference
     private final RemoteExternalOrderService remoteExternalOrderService;
 
@@ -71,6 +81,7 @@ public class OrderCreateMessageHandler implements MallMessageHandler {
         OrderDetailBo orderDetailBo = new OrderDetailBo();
         orderDetailBo.setOrderNo(orderNo);
         OrderDetailVo orderDetailVo = zhongChePullController.mallOrderDetail(orderDetailBo);
+        orderDetailVo.setDataSource(messageBo.getItemKey());
 //        OrderDetailVo orderDetailVo = new OrderDetailVo();
 //
 //// ===== 基本信息 =====
@@ -134,18 +145,51 @@ public class OrderCreateMessageHandler implements MallMessageHandler {
 //        invoice.setRegBank("中国工商银行股份有限公司北京玉渊潭支行测试");
 //        invoice.setRegBankAccount("111111111");
 //        orderDetailVo.setOrderInvoice(invoice);
+        //获取省市区乡的名称
+        //省
+        AreaQueryBo provinceNameAreaQueryBo = new AreaQueryBo();
+        provinceNameAreaQueryBo.setLevel(1);
+        provinceNameAreaQueryBo.setPid("0");
+        AreaVo provinceNameAreaVo = zhongChePullController.areaQuery(provinceNameAreaQueryBo);
+        Map<String, String> provinceNameMap = provinceNameAreaVo.getAreas().stream().collect(Collectors.toMap(Area::getId, Area::getName));
+        //市
+        AreaQueryBo cityNameAreaQueryBo = new AreaQueryBo();
+        cityNameAreaQueryBo.setLevel(2);
+        cityNameAreaQueryBo.setPid(orderDetailVo.getProvinceId());
+        AreaVo cityNameAreaVo = zhongChePullController.areaQuery(cityNameAreaQueryBo);
+        Map<String, String> cityNameMap = cityNameAreaVo.getAreas().stream().collect(Collectors.toMap(Area::getId, Area::getName));
+        //区
+        AreaQueryBo countyNameAreaQueryBo = new AreaQueryBo();
+        countyNameAreaQueryBo.setLevel(3);
+        countyNameAreaQueryBo.setPid(orderDetailVo.getCityId());
+        AreaVo countyNameAreaVo = zhongChePullController.areaQuery(countyNameAreaQueryBo);
+        Map<String, String> countyNameMap = countyNameAreaVo.getAreas().stream().collect(Collectors.toMap(Area::getId, Area::getName));
+        //乡
+        AreaQueryBo townNameAreaQueryBo = new AreaQueryBo();
+        townNameAreaQueryBo.setLevel(4);
+        townNameAreaQueryBo.setPid(orderDetailVo.getCountyId());
+        AreaVo townNameAreaVo = zhongChePullController.areaQuery(townNameAreaQueryBo);
+        Map<String, String> townNameMap = townNameAreaVo.getAreas().stream().collect(Collectors.toMap(Area::getId, Area::getName));
+
+        orderDetailVo.setProvinceName(provinceNameMap.get(orderDetailVo.getProvinceId()));
+        orderDetailVo.setCityName(cityNameMap.get(orderDetailVo.getCityId()));
+        orderDetailVo.setCountyName(countyNameMap.get(orderDetailVo.getCountyId()));
+        orderDetailVo.setTownName(townNameMap.get(orderDetailVo.getTownId()));
         OrderNoDto orderNoDto = remoteExternalOrderService.createZhongCheOrder(orderDetailVo);
+        log.info("新订单执行结果,orderNoDto={}", JSONUtil.toJsonStr(orderNoDto));
         if (orderNoDto.getSuccess()){
             List<OrderGoodsItem> orderGoods = orderDetailVo.getOrderGoods();
+            ExternalItem externalItem = externalItemService.getOne(Wrappers.lambdaQuery(ExternalItem.class).eq(ExternalItem::getItemKey, messageBo.getItemKey()));
+            //更新商品库存
             for (OrderGoodsItem orderGoodsItem : orderGoods) {
                 ExternalProduct one = externalProductService.getOne(Wrappers.<ExternalProduct>lambdaQuery().
                     eq(ExternalProduct::getProductNo, orderGoodsItem.getGoodsId())
-                    .eq(ExternalProduct::getItemId, "2028409445955592193")
+                    .eq(ExternalProduct::getItemId, ObjectUtil.isNotEmpty(externalItem)?externalItem.getId():"2028409445955592193")
                 );
                 one.setAvailableInventory(one.getAvailableInventory()-orderGoodsItem.getNum().intValue());
                 externalProductService.updateById(one);
             }
-            //更新商品库存
+
 
             return new MessageVo("1");
         }else {

+ 21 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/dubbo/RemoteExternalProductServiceImpl.java

@@ -97,7 +97,28 @@ public class RemoteExternalProductServiceImpl implements RemoteExternalProductSe
             }
 
         }
+    }
 
+    /**
+     * 更新产品库存
+     *
+     * @param products
+     */
+    @Override
+    public void syncExternalProductInventory(List<ExternalProductDto> products) {
+        for (ExternalProductDto product : products) {
+            ExternalProduct one = externalProductService.getOne(Wrappers.lambdaQuery(ExternalProduct.class)
+                .eq(ExternalProduct::getProductId, product.getProductId())
+                .eq(ExternalProduct::getItemId, product.getItemId())
+                .last("limit 1")
+            );
 
+            externalProductService.update(
+                Wrappers.lambdaUpdate(ExternalProduct.class)
+                    .set(ExternalProduct::getAvailableInventory,one.getAvailableInventory() - product.getAvailableInventory())
+                    .eq(ExternalProduct::getProductId, product.getProductId())
+                    .eq(ExternalProduct::getItemId, product.getItemId())
+            );
+        }
     }
 }

+ 75 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/dubbo/RemoteTongJiPullServiceImpl.java

@@ -0,0 +1,75 @@
+package org.dromara.external.dubbo;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.dromara.common.core.domain.zhongche.aftersale.bo.AfterSaleConfirmBo;
+import org.dromara.common.core.domain.zhongche.aftersale.bo.AfterSaleRefundBo;
+import org.dromara.common.core.domain.zhongche.aftersale.bo.AfterSaleRejectBo;
+import org.dromara.common.core.domain.zhongche.aftersale.bo.AfterSaleReturnReceivedBo;
+import org.dromara.common.core.exception.api.ZhongcheException;
+import org.dromara.external.api.tongji.RemoteTongJiPullService;
+
+import org.dromara.external.api.zhongche.domain.bo.OrderConfirmBo;
+import org.dromara.external.api.zhongche.domain.bo.OrderRejectBo;
+import org.dromara.external.api.zhongche.domain.bo.ZhongCheOrderDeliverBo;
+import org.dromara.external.api.zhongche.domain.vo.GoodsUpdateVo;
+import org.dromara.external.api.zhongche.domain.vo.ZhongCheOrderDeliverVo;
+import org.dromara.external.controller.tongji.TongJiPullController;
+import org.dromara.external.controller.zhongche.ZhongChePullController;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author
+ * @date 2026/5/18 下午4:32
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+@DubboService
+public class RemoteTongJiPullServiceImpl implements RemoteTongJiPullService {
+
+    private final TongJiPullController tongJiPullController;
+    @Override
+    public GoodsUpdateVo mallOrderConfirm(OrderConfirmBo bo) throws ZhongcheException {
+        GoodsUpdateVo goodsUpdateVo = tongJiPullController.mallOrderConfirm(bo);
+        return goodsUpdateVo;
+    }
+
+    @Override
+    public GoodsUpdateVo mallOrderReject(OrderRejectBo bo) throws ZhongcheException {
+        GoodsUpdateVo goodsUpdateVo = tongJiPullController.mallOrderReject(bo);
+        return goodsUpdateVo;
+    }
+
+    @Override
+    public GoodsUpdateVo mallAftersaleConfirm(AfterSaleConfirmBo bo) throws ZhongcheException {
+        GoodsUpdateVo goodsUpdateVo = tongJiPullController.mallAftersaleConfirm(bo);
+        return goodsUpdateVo;
+    }
+
+    @Override
+    public GoodsUpdateVo mallAftersaleReject(AfterSaleRejectBo bo) throws ZhongcheException {
+        return tongJiPullController.mallAftersaleReject(bo);
+    }
+
+    @Override
+    public GoodsUpdateVo mallAftersaleReturnGoodsReceived(AfterSaleReturnReceivedBo bo) throws ZhongcheException {
+        return tongJiPullController.mallAftersaleReturnGoodsReceived(bo);
+    }
+
+    @Override
+    public GoodsUpdateVo mallAftersaleRefund(AfterSaleRefundBo bo) throws ZhongcheException {
+        return tongJiPullController.mallAftersaleRefund(bo);
+    }
+
+    /**
+     * @param bo
+     * @return
+     * @throws ZhongcheException
+     */
+    @Override
+    public ZhongCheOrderDeliverVo mallOrderDeliverGoods(ZhongCheOrderDeliverBo bo) throws ZhongcheException {
+        return tongJiPullController.mallOrderDeliverGoods(bo);
+    }
+}

+ 33 - 3
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/dubbo/RemoteZhongChePullServiceImpl.java

@@ -7,12 +7,13 @@ import org.dromara.common.core.domain.zhongche.aftersale.bo.AfterSaleConfirmBo;
 import org.dromara.common.core.domain.zhongche.aftersale.bo.AfterSaleRefundBo;
 import org.dromara.common.core.domain.zhongche.aftersale.bo.AfterSaleRejectBo;
 import org.dromara.common.core.domain.zhongche.aftersale.bo.AfterSaleReturnReceivedBo;
+import org.dromara.common.core.domain.zhongche.vo.OrderDetailVo;
 import org.dromara.common.core.exception.api.ZhongcheException;
 import org.dromara.external.api.zhongche.RemoteZhongChePullService;
-import org.dromara.external.api.zhongche.domain.bo.OrderConfirmBo;
-import org.dromara.external.api.zhongche.domain.bo.OrderRejectBo;
-import org.dromara.external.api.zhongche.domain.bo.ZhongCheOrderDeliverBo;
+import org.dromara.external.api.zhongche.domain.bo.*;
+import org.dromara.external.api.zhongche.domain.vo.AreaVo;
 import org.dromara.external.api.zhongche.domain.vo.GoodsUpdateVo;
+import org.dromara.external.api.zhongche.domain.vo.PendingOrderListVo;
 import org.dromara.external.api.zhongche.domain.vo.ZhongCheOrderDeliverVo;
 import org.dromara.external.controller.zhongche.ZhongChePullController;
 import org.springframework.stereotype.Service;
@@ -29,6 +30,17 @@ import org.springframework.web.bind.annotation.RequestBody;
 public class RemoteZhongChePullServiceImpl implements RemoteZhongChePullService {
 
     private final ZhongChePullController zhongChePullController;
+
+    /**
+     * @param bo
+     * @return
+     */
+    @Override
+    public AreaVo areaQuery(AreaQueryBo bo) {
+        AreaVo areaVo = zhongChePullController.areaQuery(bo);
+        return areaVo;
+    }
+
     @Override
     public GoodsUpdateVo mallOrderConfirm(OrderConfirmBo bo) throws ZhongcheException {
         GoodsUpdateVo goodsUpdateVo = zhongChePullController.mallOrderConfirm(bo);
@@ -71,4 +83,22 @@ public class RemoteZhongChePullServiceImpl implements RemoteZhongChePullService
     public ZhongCheOrderDeliverVo mallOrderDeliverGoods(ZhongCheOrderDeliverBo bo) throws ZhongcheException {
         return zhongChePullController.mallOrderDeliverGoods(bo);
     }
+
+    /**
+     * @param bo
+     * @return
+     */
+    @Override
+    public PendingOrderListVo mallOrderPendingList(PendingOrderListBo bo) {
+        return zhongChePullController.mallOrderPendingList(bo);
+    }
+
+    /**
+     * @param bo
+     * @return
+     */
+    @Override
+    public OrderDetailVo mallOrderDetail(OrderDetailBo bo) {
+        return zhongChePullController.mallOrderDetail(bo);
+    }
 }

+ 171 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderMainCrrcExtController.java

@@ -1,11 +1,40 @@
 package org.dromara.order.controller;
 
+import java.math.BigDecimal;
+import java.util.Arrays;
 import java.util.List;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.dromara.external.api.zhongche.RemoteZhongChePullService;
+import org.dromara.external.api.zhongche.domain.OrderDeliverGoods;
+import org.dromara.external.api.zhongche.domain.PendingOrderRecord;
+import org.dromara.external.api.zhongche.domain.bo.PendingOrderListBo;
+import org.dromara.external.api.zhongche.domain.bo.ZhongCheOrderDeliverBo;
+import org.dromara.external.api.zhongche.domain.vo.PendingOrderListVo;
+import org.dromara.external.api.zhongche.domain.vo.ZhongCheOrderDeliverVo;
+import org.dromara.order.domain.OrderDeliverThird;
+import org.dromara.order.domain.OrderMain;
+import org.dromara.order.domain.OrderMainCrrcExt;
+import org.dromara.order.domain.OrderProduct;
+import org.dromara.order.domain.bo.OrderProductBo;
+import org.dromara.order.domain.vo.OrderItemDeliverVo;
+import org.dromara.order.domain.vo.OrderDeliverImportVo;
+import org.dromara.order.listener.OrderDeliverImportListener;
+import org.dromara.order.service.IOrderDeliverService;
+import org.dromara.order.service.IOrderDeliverThirdService;
+import org.dromara.order.service.IOrderMainService;
+import org.dromara.order.service.IOrderProductService;
+import org.dromara.order.mapper.OrderMainMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -17,10 +46,13 @@ import org.dromara.common.core.validate.AddGroup;
 import org.dromara.common.core.validate.EditGroup;
 import org.dromara.common.log.enums.BusinessType;
 import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.common.excel.core.ExcelResult;
 import org.dromara.order.domain.vo.OrderMainCrrcExtVo;
 import org.dromara.order.domain.bo.OrderMainCrrcExtBo;
 import org.dromara.order.service.IOrderMainCrrcExtService;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.springframework.http.MediaType;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * 中车电子商城订单扩展
@@ -37,6 +69,19 @@ public class OrderMainCrrcExtController extends BaseController {
 
     private final IOrderMainCrrcExtService orderMainCrrcExtService;
 
+    private final IOrderMainService orderMainService;
+
+    private final IOrderProductService orderProductService;
+
+    private final IOrderDeliverThirdService orderDeliverThirdService;
+
+    private final IOrderDeliverService orderDeliverService;
+
+    private final OrderMainMapper orderMainMapper;
+
+    @DubboReference
+    private final RemoteZhongChePullService remoteZhongChePullService;
+
     /**
      * 查询中车电子商城订单扩展列表
      */
@@ -103,4 +148,130 @@ public class OrderMainCrrcExtController extends BaseController {
                           @PathVariable("ids") Long[] ids) {
         return toAjax(orderMainCrrcExtService.deleteWithValidByIds(List.of(ids), true));
     }
+
+    /**
+    * 同步项目订单收货地址信息
+    * */
+    @PostMapping("/syncOrderConsigneeInfo")
+    public R<Void> syncOrderConsigneeInfo() {
+        orderMainCrrcExtService.syncOrderConsigneeInfo();
+        return R.ok();
+    }
+    /**
+    * 导出项目订单发货信息
+    * */
+    @PostMapping("/exportOrderDeliverInfo")
+    public void exportOrderDeliverInfo(HttpServletResponse response) {
+        List<OrderItemDeliverVo>  list= orderMainCrrcExtService.exportOrderDeliverInfo();
+        ExcelUtil.exportExcel(list, "项目订单发货信息", OrderItemDeliverVo.class, response);
+    }
+
+    /**
+    * 处理待处理的订单
+    * */
+    @PostMapping("/handlePendingOrder")
+    public R<Void> handlePendingOrder(PendingOrderListBo bo) {
+        orderMainCrrcExtService.handlePendingOrder(bo);
+        return R.ok();
+    }
+
+    /**
+    * 同步产品库存
+    * */
+    @PostMapping("/syncProductInventory")
+    public R<Void> syncProductInventory() {
+        orderMainCrrcExtService.syncProductInventory();
+        return R.ok();
+    }
+
+    /**
+    * 一键确定订单
+    * */
+    @PostMapping("/oneKeyConfirmOrder/{orderIds}")
+    public R<Void> oneKeyConfirmOrder(@PathVariable String orderIds) {
+        if (ObjectUtil.isEmpty(orderIds)){
+            return R.fail("订单编号不能为空");
+        }
+        List<String> orderIdList = Arrays.asList(orderIds.split(","));
+        List<OrderMainCrrcExt> list = orderMainCrrcExtService.list(Wrappers.lambdaQuery(OrderMainCrrcExt.class)
+            .in(OrderMainCrrcExt::getId,orderIdList)
+        );
+        for (OrderMainCrrcExt orderMainCrrcExt : list) {
+            List<OrderProduct> products = orderProductService.list(Wrappers.lambdaQuery(OrderProduct.class)
+                .eq(OrderProduct::getOrderId, orderMainCrrcExt.getId()));
+            List<OrderProductBo> updatedProducts = BeanUtil.copyToList(products, OrderProductBo.class);
+            orderMainService.confirmOrder(orderMainCrrcExt.getId(), updatedProducts);
+        }
+        return R.ok();
+    }
+
+
+
+    /**
+     * 导入订单发货数据
+     *
+     * @param file 导入文件
+     */
+    @Log(title = "订单发货导入", businessType = BusinessType.IMPORT)
+    @PostMapping(value = "/importDeliverData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+    public R<Void> importDeliverData(@RequestPart("file") MultipartFile file) throws Exception {
+        ExcelResult<OrderDeliverImportVo> result = ExcelUtil.importExcel(
+            file.getInputStream(),
+            OrderDeliverImportVo.class,
+            new OrderDeliverImportListener(orderMainCrrcExtService, orderProductService, orderMainService, orderDeliverService, orderMainMapper)
+        );
+        return R.ok(result.getAnalysis());
+    }
+
+    /**
+     * 获取订单发货导入模板
+     */
+    @Log(title = "订单发货导入", businessType = BusinessType.IMPORT)
+    @PostMapping("/importDeliverTemplate")
+    public void importDeliverTemplate(HttpServletResponse response) {
+        ExcelUtil.exportExcel(List.of(), "订单发货导入模板", OrderDeliverImportVo.class, response);
+    }
+
+    /**
+     * 发货
+     * */
+    @PostMapping("/oneKeyDeliverGoods")
+    public R<Void> oneKeyDeliverGoods(String purchaserOrderNo) {
+        OrderMainCrrcExt one = orderMainCrrcExtService.getOne(Wrappers.lambdaQuery(OrderMainCrrcExt.class)
+            .eq(OrderMainCrrcExt::getPurchaserOrderNo, purchaserOrderNo)
+            .last("limit 1")
+        );
+        // 获取获取订单商品
+        List<OrderProduct> products = orderProductService.list(Wrappers.lambdaQuery(OrderProduct.class)
+            .eq(OrderProduct::getOrderId, one.getId())
+        );
+        String orderNo = one.getCrrcOrderNo();
+        String deliveryType = "1";
+        String expressCode = "SF0221406129514";
+        String expressCompanyName = "顺丰";
+        List<OrderDeliverGoods> orderDeliverGoods = products.stream().map(product -> {
+            OrderDeliverGoods orderDeliverGood = new OrderDeliverGoods();
+            orderDeliverGood.setGoodsId(product.getProductNo());
+            orderDeliverGood.setNum(BigDecimal.valueOf(product.getOrderQuantity()));
+            return orderDeliverGood;
+        }).toList();
+        ZhongCheOrderDeliverBo zhongCheOrderDeliverBo = new ZhongCheOrderDeliverBo();
+        zhongCheOrderDeliverBo.setOrderNo(orderNo);
+        zhongCheOrderDeliverBo.setDeliveryType(deliveryType);
+        zhongCheOrderDeliverBo.setExpressCode(expressCode);
+        zhongCheOrderDeliverBo.setExpressCompanyName(expressCompanyName);
+        zhongCheOrderDeliverBo.setOrderDeliverGoods(orderDeliverGoods);
+        ZhongCheOrderDeliverVo zhongCheOrderDeliverVo = remoteZhongChePullService.mallOrderDeliverGoods(zhongCheOrderDeliverBo);
+        //保存第三方订单发货信息
+        OrderDeliverThird orderDeliverThird = new OrderDeliverThird();
+        orderDeliverThird.setOrderId(one.getId());
+        orderDeliverThird.setOutgoingCode(zhongCheOrderDeliverVo.getOutgoingCode());
+        orderDeliverThirdService.save(orderDeliverThird);
+        //将订单改为已发货
+        orderMainService.update(Wrappers.lambdaUpdate(OrderMain.class)
+            .eq(OrderMain::getId, one.getId()).set(OrderMain::getOrderStatus, 4)
+        );
+        return R.ok();
+    }
+
 }

+ 6 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderDeliverThird.java

@@ -32,6 +32,12 @@ public class OrderDeliverThird extends TenantEntity {
      */
     private Long deliverId;
 
+    /**
+    * 订单id
+    * */
+    private Long orderId;
+
+
     /**
      * 第三方发货单号
      */

+ 20 - 8
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderMainCrrcExt.java

@@ -62,25 +62,37 @@ public class OrderMainCrrcExt extends TenantEntity {
     private String receiverName;
 
     /**
-     * 收货地址省编码(provinceId),中车行政区编码
+     * 一级地址编码:收货人省份地址编码
      */
     private String provinceId;
-
     /**
-     * 收货地址市编码(cityId)
+     * 省名称
+     */
+    private String provinceName;
+    /**
+     * 二级地址编码:收货人市级地址编码
      */
     private String cityId;
-
     /**
-     * 收货地址区/县编码(countyId)
+     * 市名称
+     */
+    private String cityName;
+    /**
+     * 三级地址编码:收货人县(区)级地址编码
      */
     private String countyId;
-
     /**
-     * 收货地址乡镇编码(townId),无四级地址传0
+     * 区名称
+     */
+    private String countyName;
+    /**
+     * 四级地址编码:收货人乡镇地址编码(如果该地区有四级地址,则必须传递四级地址,没有四级地址则传 0)
      */
     private String townId;
-
+    /**
+     * 乡镇名称
+     */
+    private String townName;
     /**
      * 收货详细地址(address)
      */

+ 2 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderDeliverBo.java

@@ -86,6 +86,8 @@ public class OrderDeliverBo extends BaseEntity {
 
     private String logisticsCompanyCode;
 
+    private String logisticsCompanyName;
+
     /**
      * 物流单号
      */

+ 52 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderDeliverImportVo.java

@@ -0,0 +1,52 @@
+package org.dromara.order.domain.vo;
+
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 订单发货导入视图对象
+ *
+ * @author LionLi
+ * @date 2026-05-20
+ */
+@Data
+@ExcelIgnoreUnannotated
+public class OrderDeliverImportVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 商品编号
+     */
+    @ExcelProperty(value = "商品编号", index = 0)
+    private String productNo;
+
+    /**
+     * 订单号(采购平台订单号)
+     */
+    @ExcelProperty(value = "采购订单号", index = 1)
+    private String purchaserOrderNo;
+
+    /**
+     * 快递单号
+     */
+    @ExcelProperty(value = "快递单号", index = 2)
+    private String expressCode;
+
+    /**
+     * 快递公司
+     */
+    @ExcelProperty(value = "快递公司", index = 3)
+    private String expressCompanyName;
+    /**
+    * 收货人手机号
+     */
+    @ExcelProperty(value = "收货人手机号", index = 4)
+    private String mobile;
+
+}

+ 121 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderItemDeliverVo.java

@@ -0,0 +1,121 @@
+package org.dromara.order.domain.vo;
+
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import lombok.Data;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 项目订单发货信息
+ *
+ * @author
+ * @date 2026/5/19 下午4:28
+ */
+@Data
+@ExcelIgnoreUnannotated
+public class OrderItemDeliverVo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+    * 系统订单编号
+    * */
+    @ExcelProperty(value = "系统订单编号")
+    private String orderNo;
+    /**
+     * 第三方平台订单号
+     * */
+    @ExcelProperty(value = "第三方平台订单号")
+    private String crrcOrderNo;
+    /**
+    * 第三方采购单号
+    * */
+    @ExcelProperty(value = "第三方采购单号")
+    private String purchaserOrderNo;
+    /**
+    * 下单时间
+    * */
+    @ExcelProperty(value = "下单时间")
+    private Date createTime;
+    /**
+     * 商品编号
+     */
+    @ExcelProperty(value = "商品编号")
+    private String productNo;
+    /**
+     * 商品名称
+     */
+    @ExcelProperty(value = "商品名称")
+    private String productName;
+    /**
+     * 采购数量
+     * */
+    @ExcelProperty(value = "采购数量")
+    private Long orderQuantity;
+    /**
+     * 单位
+     */
+    @ExcelProperty(value = "单位")
+    private String productUnit;
+
+    /**
+    * 采购单价
+    * */
+    @ExcelProperty(value = "采购单价")
+    private BigDecimal orderPrice;
+    /**
+    * 小计金额
+    * */
+    @ExcelProperty(value = "小计金额")
+    private BigDecimal subtotal;
+
+    /**
+     * 收货人姓名(name)
+     */
+    @ExcelProperty(value = "收货人姓名")
+    private String receiverName;
+
+    /**
+     * 收货人手机号(mobile)
+     */
+    @ExcelProperty(value = "收货人手机号")
+    private String mobile;
+
+    /**
+     * 省名称
+     */
+    @ExcelProperty(value = "省名称")
+    private String provinceName;
+    /**
+     * 市名称
+     */
+    @ExcelProperty(value = "市名称")
+    private String cityName;
+    /**
+     * 区名称
+     */
+    @ExcelProperty(value = "区名称")
+    private String countyName;
+    /**
+     * 乡镇名称
+     */
+    @ExcelProperty(value = "乡镇名称")
+    private String townName;
+
+    /**
+     * 收货详细地址(address)
+     */
+    @ExcelProperty(value = "收货详细地址")
+    private String detailAddress;
+
+    /**
+    * 备注
+    * */
+    @ExcelProperty(value = "备注")
+    private String remark;
+}

+ 20 - 15
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderMainCrrcExtVo.java

@@ -80,32 +80,37 @@ public class OrderMainCrrcExtVo implements Serializable {
     private String receiverName;
 
     /**
-     * 收货地址省编码(provinceId),中车行政区编码
+     * 一级地址编码:收货人省份地址编码
      */
-    @ExcelProperty(value = "收货地址省编码", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(readConverterExp = "p=rovinceId")
     private String provinceId;
-
     /**
-     * 收货地址市编码(cityId)
+     * 省名称
+     */
+    private String provinceName;
+    /**
+     * 二级地址编码:收货人市级地址编码
      */
-    @ExcelProperty(value = "收货地址市编码", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(readConverterExp = "c=ityId")
     private String cityId;
-
     /**
-     * 收货地址区/县编码(countyId)
+     * 市名称
+     */
+    private String cityName;
+    /**
+     * 三级地址编码:收货人县(区)级地址编码
      */
-    @ExcelProperty(value = "收货地址区/县编码", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(readConverterExp = "c=ountyId")
     private String countyId;
-
     /**
-     * 收货地址乡镇编码(townId),无四级地址传0
+     * 区名称
+     */
+    private String countyName;
+    /**
+     * 四级地址编码:收货人乡镇地址编码(如果该地区有四级地址,则必须传递四级地址,没有四级地址则传 0)
      */
-    @ExcelProperty(value = "收货地址乡镇编码", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(readConverterExp = "t=ownId")
     private String townId;
+    /**
+     * 乡镇名称
+     */
+    private String townName;
 
     /**
      * 收货详细地址(address)

+ 6 - 1
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/dubbo/RemoteExternalOrderServiceImpl.java

@@ -391,7 +391,7 @@ public class RemoteExternalOrderServiceImpl implements RemoteExternalOrderServic
         }
         orderMain.setOrderTime(orderTime);
         //数据来源
-        orderMain.setDataSource("zhongche");
+        orderMain.setDataSource(orderDetailVo.getDataSource());
         //商品总数量
         long totalQuantity = orderDetailVo.getOrderGoods()
             .stream()
@@ -400,6 +400,7 @@ public class RemoteExternalOrderServiceImpl implements RemoteExternalOrderServic
             .mapToInt(BigDecimal::intValueExact)
             .sum();
         orderMain.setProductQuantity(totalQuantity);
+        orderMain.setOrderSource("4");
         boolean orderMainFlag = orderMainService.save(orderMain);
         Long id = orderMain.getId();
         //副表
@@ -415,13 +416,17 @@ public class RemoteExternalOrderServiceImpl implements RemoteExternalOrderServic
         orderMainCrrcExt.setReceiverName(orderDetailVo.getName());
         //10
         orderMainCrrcExt.setProvinceId(orderDetailVo.getProvinceId());
+        orderMainCrrcExt.setProvinceName(orderDetailVo.getProvinceName());
         //11
         orderMainCrrcExt.setCityId(orderDetailVo.getCityId());
+        orderMainCrrcExt.setCityName(orderDetailVo.getCityName());
         //12
         orderMainCrrcExt.setCountyId(orderDetailVo.getCountyId());
+        orderMainCrrcExt.setCountyName(orderDetailVo.getCountyName());
         //13
         if (ObjectUtil.isNotEmpty(orderDetailVo.getTownId())){
             orderMainCrrcExt.setTownId(orderDetailVo.getTownId());
+            orderMainCrrcExt.setTownName(orderDetailVo.getTownName());
         }
         //14、详细地址
         orderMainCrrcExt.setDetailAddress(orderDetailVo.getAddress());

+ 225 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/listener/OrderDeliverImportListener.java

@@ -0,0 +1,225 @@
+package org.dromara.order.listener;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.idev.excel.context.AnalysisContext;
+import cn.idev.excel.event.AnalysisEventListener;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.external.api.zhongche.RemoteZhongChePullService;
+import org.dromara.external.api.zhongche.domain.OrderDeliverGoods;
+import org.dromara.external.api.zhongche.domain.bo.ZhongCheOrderDeliverBo;
+import org.dromara.external.api.zhongche.domain.vo.ZhongCheOrderDeliverVo;
+import org.dromara.common.excel.core.ExcelListener;
+import org.dromara.common.excel.core.ExcelResult;
+import org.dromara.order.domain.*;
+import org.dromara.order.domain.bo.OrderDeliverBo;
+import org.dromara.order.domain.bo.OrderDeliverProductBo;
+import org.dromara.order.domain.vo.OrderDeliverImportVo;
+import org.dromara.order.mapper.OrderMainMapper;
+import org.dromara.order.service.IOrderDeliverService;
+import org.dromara.order.service.IOrderDeliverThirdService;
+import org.dromara.order.service.IOrderMainCrrcExtService;
+import org.dromara.order.service.IOrderMainService;
+import org.dromara.order.service.IOrderProductService;
+import org.dromara.system.api.RemoteComLogisticsCompanyService;
+import org.dromara.system.api.domain.vo.RemoteLogisticsCompanyVo;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 订单发货导入监听器
+ *
+ * @author LionLi
+ * @date 2026-05-20
+ */
+@Slf4j
+public class OrderDeliverImportListener extends AnalysisEventListener<OrderDeliverImportVo> implements ExcelListener<OrderDeliverImportVo> {
+
+    private final IOrderMainCrrcExtService orderMainCrrcExtService;
+    private final IOrderProductService orderProductService;
+    private final IOrderMainService orderMainService;
+    private final IOrderDeliverService orderDeliverService;
+    private final OrderMainMapper orderMainMapper;
+
+    @DubboReference
+    private RemoteZhongChePullService remoteZhongChePullService;
+    @DubboReference
+    private RemoteComLogisticsCompanyService remoteComLogisticsCompanyService;
+
+
+    private int successNum = 0;
+    private int failureNum = 0;
+    private final StringBuilder successMsg = new StringBuilder();
+    private final StringBuilder failureMsg = new StringBuilder();
+
+    public OrderDeliverImportListener(IOrderMainCrrcExtService orderMainCrrcExtService,
+                                      IOrderProductService orderProductService,
+                                      IOrderMainService orderMainService,
+                                      IOrderDeliverService orderDeliverService,
+                                      OrderMainMapper orderMainMapper) {
+        this.orderMainCrrcExtService = orderMainCrrcExtService;
+        this.orderProductService = orderProductService;
+        this.orderMainService = orderMainService;
+        this.orderDeliverService = orderDeliverService;
+        this.orderMainMapper = orderMainMapper;
+        this.remoteZhongChePullService = SpringUtils.getBean(RemoteZhongChePullService.class);
+        this.remoteComLogisticsCompanyService = SpringUtils.getBean(RemoteComLogisticsCompanyService.class);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void invoke(OrderDeliverImportVo importVo, AnalysisContext context) {
+        try {
+            // 校验必填字段
+            if (ObjectUtil.isEmpty(importVo.getProductNo())) {
+                failureNum++;
+                failureMsg.append("<br/>").append(failureNum).append("、第 ").append(context.readRowHolder().getRowIndex() + 1).append(" 行,商品编号不能为空");
+                return;
+            }
+
+            if (ObjectUtil.isEmpty(importVo.getPurchaserOrderNo())) {
+                failureNum++;
+                failureMsg.append("<br/>").append(failureNum).append("、第 ").append(context.readRowHolder().getRowIndex() + 1).append(" 行,订单号不能为空");
+                return;
+            }
+
+            if (ObjectUtil.isEmpty(importVo.getExpressCode())) {
+                failureNum++;
+                failureMsg.append("<br/>").append(failureNum).append("、第 ").append(context.readRowHolder().getRowIndex() + 1).append(" 行,快递单号不能为空");
+                return;
+            }
+
+            if (ObjectUtil.isEmpty(importVo.getExpressCompanyName())) {
+                failureNum++;
+                failureMsg.append("<br/>").append(failureNum).append("、第 ").append(context.readRowHolder().getRowIndex() + 1).append(" 行,快递公司不能为空");
+                return;
+            }
+            if (ObjectUtil.isEmpty(importVo.getMobile())) {
+                failureNum++;
+                failureMsg.append("<br/>").append(failureNum).append("、第 ").append(context.readRowHolder().getRowIndex() + 1).append(" 行,收货人手机号不能为空");
+                return;
+            }
+
+            // 根据采购平台订单号查询订单扩展信息
+            OrderMainCrrcExt orderMainCrrcExt = orderMainCrrcExtService.getOne(Wrappers.lambdaQuery(OrderMainCrrcExt.class)
+                .eq(OrderMainCrrcExt::getPurchaserOrderNo, importVo.getPurchaserOrderNo())
+                .last("limit 1")
+            );
+
+            if (ObjectUtil.isEmpty(orderMainCrrcExt)) {
+                failureNum++;
+                failureMsg.append("<br/>").append(failureNum).append("、第 ").append(context.readRowHolder().getRowIndex() + 1).append(" 行,订单号[").append(importVo.getPurchaserOrderNo()).append("]不存在");
+                return;
+            }
+
+            // 获取订单商品信息
+            List<OrderProduct> products = orderProductService.list(Wrappers.lambdaQuery(OrderProduct.class)
+                .eq(OrderProduct::getOrderId, orderMainCrrcExt.getId())
+                .eq(OrderProduct::getProductNo, importVo.getProductNo())
+            );
+
+            if (ObjectUtil.isEmpty(products)) {
+                failureNum++;
+                failureMsg.append("<br/>").append(failureNum).append("、第 ").append(context.readRowHolder().getRowIndex() + 1).append(" 行,商品编号[").append(importVo.getProductNo()).append("]在该订单中不存在");
+                return;
+            }
+
+
+            // 构建发货单BO对象
+            OrderDeliverBo deliverBo = new OrderDeliverBo();
+            deliverBo.setOrderId(orderMainCrrcExt.getId());
+
+            // 设置发货方式:0-自提,1-快递
+            deliverBo.setDeliverMethod("1");
+
+            // 设置物流信息
+            deliverBo.setLogisticsCompanyName(importVo.getExpressCompanyName());
+            deliverBo.setLogisticNo(importVo.getExpressCode());
+            RemoteLogisticsCompanyVo remoteLogisticsCompanyVo = remoteComLogisticsCompanyService.selectLogisticsCompanyByName(importVo.getExpressCompanyName());
+            if (ObjectUtil.isEmpty(remoteLogisticsCompanyVo)) {
+                failureNum++;
+                failureMsg.append("<br/>").append(failureNum).append("、第 ").append(context.readRowHolder().getRowIndex() + 1).append(" 行,物流公司[").append(importVo.getExpressCompanyName()).append("]不存在");
+                return;
+            }
+            deliverBo.setLogisticsCompanyId(remoteLogisticsCompanyVo.getId());
+            deliverBo.setLogisticsCompanyCode(remoteLogisticsCompanyVo.getLogisticsCode());
+            deliverBo.setConsigneePhone(importVo.getMobile());
+
+            // 获取订单数据源
+            OrderMain orderMain = orderMainMapper.selectById(orderMainCrrcExt.getId());
+            if (orderMain != null) {
+                deliverBo.setDataSource(orderMain.getDataSource());
+            }
+
+            // 构建发货商品明细
+            List<OrderDeliverProductBo> deliverProducts = new ArrayList<>();
+            for (OrderProduct p : products) {
+                OrderDeliverProductBo deliverProduct = new OrderDeliverProductBo();
+                deliverProduct.setProductId(p.getId());
+                deliverProduct.setProductNo(p.getProductNo());
+                deliverProduct.setProductName(p.getProductName());
+                deliverProduct.setProductUnit(p.getProductUnit());
+                deliverProduct.setDeliverNum(Long.valueOf(p.getOrderQuantity()));
+                deliverProduct.setOrderPrice(p.getOrderPrice());
+                deliverProduct.setSubtotal(p.getOrderPrice().multiply(BigDecimal.valueOf(p.getOrderQuantity())));
+                deliverProducts.add(deliverProduct);
+            }
+            deliverBo.setOrderDeliverProducts(deliverProducts);
+
+            // 调用标准的发货接口(包含完整的事务处理、状态更新、第三方通知等)
+            Boolean result = orderDeliverService.insertByBo(deliverBo);
+
+            if (result) {
+                successNum++;
+                successMsg.append("<br/>").append(successNum).append("、订单号[").append(importVo.getPurchaserOrderNo()).append("]商品[").append(importVo.getProductNo()).append("]发货成功");
+            } else {
+                failureNum++;
+                failureMsg.append("<br/>").append(failureNum).append("、订单号[").append(importVo.getPurchaserOrderNo()).append("]商品[").append(importVo.getProductNo()).append("]发货失败");
+            }
+        } catch (Exception e) {
+            failureNum++;
+            String msg = "<br/>" + failureNum + "、订单号[" + importVo.getPurchaserOrderNo() + "]商品[" + importVo.getProductNo() + "]发货失败:";
+            String message = e.getMessage();
+            failureMsg.append(msg).append(message);
+            log.error(msg, e);
+            throw e; // 抛出异常触发事务回滚
+        }
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext context) {
+        // 所有数据解析完成后调用
+    }
+
+    @Override
+    public ExcelResult<OrderDeliverImportVo> getExcelResult() {
+        return new ExcelResult<OrderDeliverImportVo>() {
+            @Override
+            public String getAnalysis() {
+                if (failureNum > 0) {
+                    failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
+                    throw new ServiceException(failureMsg.toString());
+                } else {
+                    successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
+                }
+                return successMsg.toString();
+            }
+
+            @Override
+            public List<OrderDeliverImportVo> getList() {
+                return null;
+            }
+
+            @Override
+            public List<String> getErrorList() {
+                return null;
+            }
+        };
+    }
+}

+ 28 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderMainCrrcExtService.java

@@ -1,7 +1,9 @@
 package org.dromara.order.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.external.api.zhongche.domain.bo.PendingOrderListBo;
 import org.dromara.order.domain.OrderMainCrrcExt;
+import org.dromara.order.domain.vo.OrderItemDeliverVo;
 import org.dromara.order.domain.vo.OrderMainCrrcExtVo;
 import org.dromara.order.domain.bo.OrderMainCrrcExtBo;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -67,4 +69,30 @@ public interface IOrderMainCrrcExtService extends IService<OrderMainCrrcExt>{
      * @return 是否删除成功
      */
     Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 同步订单收货人信息
+     */
+    void syncOrderConsigneeInfo();
+
+
+    /**
+     * 导出项目订单发货信息
+     */
+    List<OrderItemDeliverVo> exportOrderDeliverInfo();
+
+    /**
+    * 处理待处理的订单
+    * */
+    void handlePendingOrder(PendingOrderListBo bo);
+
+    /**
+    * 同步项目订单库存信息
+    * */
+    void syncProductInventory();
+
+    /**
+    * 一键确认订单
+    * */
+    void oneKeyConfirmOrder(Integer limit);
 }

+ 38 - 5
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderDeliverServiceImpl.java

@@ -1,6 +1,7 @@
 package org.dromara.order.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@@ -19,6 +20,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.redis.utils.SequenceUtils;
 import org.dromara.customer.api.RemoteCustomerService;
 import org.dromara.external.api.zhongche.RemoteZhongChePullService;
+import org.dromara.external.api.zhongche.domain.OrderDeliverGoods;
 import org.dromara.external.api.zhongche.domain.bo.ZhongCheOrderDeliverBo;
 import org.dromara.external.api.zhongche.domain.vo.ZhongCheOrderDeliverVo;
 import org.dromara.order.domain.*;
@@ -35,6 +37,7 @@ import org.dromara.order.service.IZhongCheOrderMainService;
 import org.dromara.order.utils.kd100.Kd100Util;
 import org.dromara.order.utils.kd100.domain.QueryTrackDTO;
 import org.dromara.order.utils.kd100.domain.TrackVO;
+import org.dromara.system.api.RemoteComLogisticsCompanyService;
 import org.dromara.system.api.RemoteDeptService;
 import org.dromara.system.api.RemoteUserService;
 import org.springframework.stereotype.Service;
@@ -66,6 +69,8 @@ public class OrderDeliverServiceImpl extends ServiceImpl<OrderDeliverMapper, Ord
 
     @DubboReference
     private RemoteZhongChePullService remoteZhongChePullService;
+    @DubboReference
+    private RemoteComLogisticsCompanyService remoteComLogisticsCompanyService;
 
 
     private final OrderDeliverMapper baseMapper;
@@ -150,7 +155,7 @@ public class OrderDeliverServiceImpl extends ServiceImpl<OrderDeliverMapper, Ord
             QueryTrackDTO dto = QueryTrackDTO.builder()
                 .com(bo.getLogisticsCompanyCode())
                 .num(bo.getLogisticNo())
-                .phone(bo.getPhone())
+                .phone(bo.getConsigneePhone())
                 .build();
 
             // 3. 调用物流查询
@@ -298,13 +303,27 @@ public class OrderDeliverServiceImpl extends ServiceImpl<OrderDeliverMapper, Ord
                     zhongCheOrderDeliverBo.setDeliveryType("2");
                 }else if (Objects.equals(bo.getDeliverMethod(),"1")){
                     zhongCheOrderDeliverBo.setDeliveryType("1");
-                    zhongCheOrderDeliverBo.setExpressCode(bo.getLogisticNo());
-                    zhongCheOrderDeliverBo.setExpressCompanyName(bo.getLogisticsCompanyCode());
+                    if(ObjectUtil.isNotEmpty(bo.getLogisticsCompanyName())){
+                        zhongCheOrderDeliverBo.setExpressCode(bo.getLogisticNo());
+                        zhongCheOrderDeliverBo.setExpressCompanyName(bo.getLogisticsCompanyName());
+                    }else{
+                        String companyName = remoteComLogisticsCompanyService.selectLogisticsCompanyNameById(bo.getLogisticsCompanyId());
+                        zhongCheOrderDeliverBo.setExpressCode(bo.getLogisticNo());
+                        zhongCheOrderDeliverBo.setExpressCompanyName(companyName);
+                    }
                 }
+                List<OrderDeliverGoods> orderDeliverGoods = bo.getOrderDeliverProducts().stream().map(orderDeliverProductBo -> {
+                    OrderDeliverGoods zhongCheOrderDeliverGoods = new OrderDeliverGoods();
+                    zhongCheOrderDeliverGoods.setGoodsId(orderDeliverProductBo.getProductNo());
+                    zhongCheOrderDeliverGoods.setNum(BigDecimal.valueOf(orderDeliverProductBo.getDeliverNum()));
+                    return zhongCheOrderDeliverGoods;
+                }).toList();
+                zhongCheOrderDeliverBo.setOrderDeliverGoods(orderDeliverGoods);
                 ZhongCheOrderDeliverVo zhongCheOrderDeliverVo = remoteZhongChePullService.mallOrderDeliverGoods(zhongCheOrderDeliverBo);
                 //保存第三方订单发货信息
                 OrderDeliverThird orderDeliverThird = new OrderDeliverThird();
                 orderDeliverThird.setDeliverId(deliver.getId());
+                orderDeliverThird.setOrderId(orderId);
                 orderDeliverThird.setOutgoingCode(zhongCheOrderDeliverVo.getOutgoingCode());
                 orderDeliverThirdService.save(orderDeliverThird);
             }
@@ -317,13 +336,27 @@ public class OrderDeliverServiceImpl extends ServiceImpl<OrderDeliverMapper, Ord
                     zhongCheOrderDeliverBo.setDeliveryType("2");
                 }else if (Objects.equals(bo.getDeliverMethod(),"1")){
                     zhongCheOrderDeliverBo.setDeliveryType("1");
-                    zhongCheOrderDeliverBo.setExpressCode(bo.getLogisticNo());
-                    zhongCheOrderDeliverBo.setExpressCompanyName(bo.getLogisticsCompanyCode());
+                    if(ObjectUtil.isNotEmpty(bo.getLogisticsCompanyName())){
+                        zhongCheOrderDeliverBo.setExpressCode(bo.getLogisticNo());
+                        zhongCheOrderDeliverBo.setExpressCompanyName(bo.getLogisticsCompanyName());
+                    }else{
+                        String companyName = remoteComLogisticsCompanyService.selectLogisticsCompanyNameById(bo.getLogisticsCompanyId());
+                        zhongCheOrderDeliverBo.setExpressCode(bo.getLogisticNo());
+                        zhongCheOrderDeliverBo.setExpressCompanyName(companyName);
+                    }
                 }
+                List<OrderDeliverGoods> orderDeliverGoods = bo.getOrderDeliverProducts().stream().map(orderDeliverProductBo -> {
+                    OrderDeliverGoods zhongCheOrderDeliverGoods = new OrderDeliverGoods();
+                    zhongCheOrderDeliverGoods.setGoodsId(orderDeliverProductBo.getProductNo());
+                    zhongCheOrderDeliverGoods.setNum(BigDecimal.valueOf(orderDeliverProductBo.getDeliverNum()));
+                    return zhongCheOrderDeliverGoods;
+                }).toList();
+                zhongCheOrderDeliverBo.setOrderDeliverGoods(orderDeliverGoods);
                 ZhongCheOrderDeliverVo zhongCheOrderDeliverVo = remoteZhongChePullService.mallOrderDeliverGoods(zhongCheOrderDeliverBo);
                 //保存第三方订单发货信息
                 OrderDeliverThird orderDeliverThird = new OrderDeliverThird();
                 orderDeliverThird.setDeliverId(deliver.getId());
+                orderDeliverThird.setOrderId(orderId);
                 orderDeliverThird.setOutgoingCode(zhongCheOrderDeliverVo.getOutgoingCode());
                 orderDeliverThirdService.save(orderDeliverThird);
             }

+ 198 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderMainCrrcExtServiceImpl.java

@@ -1,6 +1,11 @@
 package org.dromara.order.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.dromara.common.core.domain.zhongche.vo.OrderDetailVo;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -10,6 +15,24 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.external.api.domain.ExternalProductDto;
+import org.dromara.external.api.service.RemoteExternalProductService;
+import org.dromara.external.api.zhongche.RemoteZhongChePullService;
+import org.dromara.external.api.zhongche.domain.Area;
+import org.dromara.external.api.zhongche.domain.PendingOrderRecord;
+import org.dromara.external.api.zhongche.domain.bo.AreaQueryBo;
+import org.dromara.external.api.zhongche.domain.bo.OrderDetailBo;
+import org.dromara.external.api.zhongche.domain.bo.PendingOrderListBo;
+import org.dromara.external.api.zhongche.domain.vo.AreaVo;
+import org.dromara.external.api.zhongche.domain.vo.PendingOrderListVo;
+import org.dromara.order.domain.OrderMain;
+import org.dromara.order.domain.OrderProduct;
+import org.dromara.order.domain.vo.OrderItemDeliverVo;
+import org.dromara.order.mapper.OrderMainMapper;
+import org.dromara.order.service.IOrderMainService;
+import org.dromara.order.service.IOrderProductService;
+import org.dromara.product.api.RemoteExternalOrderService;
+import org.dromara.product.api.domain.dto.OrderNoDto;
 import org.springframework.stereotype.Service;
 import org.dromara.order.domain.bo.OrderMainCrrcExtBo;
 import org.dromara.order.domain.vo.OrderMainCrrcExtVo;
@@ -17,9 +40,11 @@ import org.dromara.order.domain.OrderMainCrrcExt;
 import org.dromara.order.mapper.OrderMainCrrcExtMapper;
 import org.dromara.order.service.IOrderMainCrrcExtService;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Collection;
+import java.util.stream.Collectors;
 
 /**
  * 中车电子商城订单扩展Service业务层处理
@@ -34,6 +59,18 @@ public class OrderMainCrrcExtServiceImpl  extends ServiceImpl<OrderMainCrrcExtMa
 
     private final OrderMainCrrcExtMapper baseMapper;
 
+    private final OrderMainMapper orderMainMapper;
+
+    private final IOrderProductService orderProductService;
+    @DubboReference
+    private final RemoteZhongChePullService remoteZhongChePullService;
+    @DubboReference
+    private final RemoteExternalOrderService remoteExternalOrderService;
+    @DubboReference
+    private final RemoteExternalProductService remoteExternalProductService;
+
+
+
     /**
      * 查询中车电子商城订单扩展
      *
@@ -158,4 +195,165 @@ public class OrderMainCrrcExtServiceImpl  extends ServiceImpl<OrderMainCrrcExtMa
         }
         return baseMapper.deleteByIds(ids) > 0;
     }
+
+    /**
+     * 同步订单收货人信息
+     */
+    @Override
+    public void syncOrderConsigneeInfo() {
+        List<OrderMainCrrcExt> list = baseMapper.selectList(
+            Wrappers.lambdaQuery(OrderMainCrrcExt.class)
+            .isNull(OrderMainCrrcExt::getProvinceName).last("limit 30")
+        );
+        //获取省市区乡的名称
+        //省
+        AreaQueryBo provinceNameAreaQueryBo = new AreaQueryBo();
+        provinceNameAreaQueryBo.setLevel(1);
+        provinceNameAreaQueryBo.setPid("0");
+        AreaVo provinceNameAreaVo = remoteZhongChePullService.areaQuery(provinceNameAreaQueryBo);
+        Map<String, String> provinceNameMap = provinceNameAreaVo.getAreas().stream().collect(Collectors.toMap(Area::getId, Area::getName));
+
+        List<OrderMainCrrcExt> updateOrderMainCrrcExts = new ArrayList<>();
+        for (OrderMainCrrcExt orderMainCrrcExt : list) {
+            //市
+            AreaQueryBo cityNameAreaQueryBo = new AreaQueryBo();
+            cityNameAreaQueryBo.setLevel(2);
+            cityNameAreaQueryBo.setPid(orderMainCrrcExt.getProvinceId());
+            AreaVo cityNameAreaVo = remoteZhongChePullService.areaQuery(cityNameAreaQueryBo);
+            Map<String, String> cityNameMap = cityNameAreaVo.getAreas().stream().collect(Collectors.toMap(Area::getId, Area::getName));
+            //区
+            AreaQueryBo countyNameAreaQueryBo = new AreaQueryBo();
+            countyNameAreaQueryBo.setLevel(3);
+            countyNameAreaQueryBo.setPid(orderMainCrrcExt.getCityId());
+            AreaVo countyNameAreaVo = remoteZhongChePullService.areaQuery(countyNameAreaQueryBo);
+            Map<String, String> countyNameMap = countyNameAreaVo.getAreas().stream().collect(Collectors.toMap(Area::getId, Area::getName));
+            //乡
+            AreaQueryBo townNameAreaQueryBo = new AreaQueryBo();
+            townNameAreaQueryBo.setLevel(4);
+            townNameAreaQueryBo.setPid(orderMainCrrcExt.getCountyId());
+            AreaVo townNameAreaVo = remoteZhongChePullService.areaQuery(townNameAreaQueryBo);
+            Map<String, String> townNameMap = townNameAreaVo.getAreas().stream().collect(Collectors.toMap(Area::getId, Area::getName));
+
+            OrderMainCrrcExt updateOrderMainCrrcExt = new OrderMainCrrcExt();
+            updateOrderMainCrrcExt.setId(orderMainCrrcExt.getId());
+            updateOrderMainCrrcExt.setProvinceName(provinceNameMap.get(orderMainCrrcExt.getProvinceId()));
+            updateOrderMainCrrcExt.setCityName(cityNameMap.get(orderMainCrrcExt.getCityId()));
+            updateOrderMainCrrcExt.setCountyName(countyNameMap.get(orderMainCrrcExt.getCountyId()));
+            updateOrderMainCrrcExt.setTownName(townNameMap.get(orderMainCrrcExt.getTownId()));
+            updateOrderMainCrrcExts.add(updateOrderMainCrrcExt);
+        }
+        baseMapper.updateBatchById(updateOrderMainCrrcExts);
+    }
+
+    /**
+     * 导出项目订单发货信息
+     */
+    @Override
+    public List<OrderItemDeliverVo> exportOrderDeliverInfo() {
+        //获取项目订单
+        List<OrderMainCrrcExt> list = baseMapper.selectList();
+        List<OrderItemDeliverVo> orderItemDeliverVos = list.stream().map(orderMainCrrcExt -> {
+            OrderItemDeliverVo bean = BeanUtil.toBean(orderMainCrrcExt, OrderItemDeliverVo.class);
+            OrderProduct product = orderProductService.getOne(Wrappers.lambdaQuery(OrderProduct.class)
+                .eq(OrderProduct::getOrderId, orderMainCrrcExt.getId())
+            );
+            OrderMain orderMain = orderMainMapper.selectOne(Wrappers.lambdaQuery(OrderMain.class)
+                .eq(OrderMain::getId, orderMainCrrcExt.getId())
+            );
+
+            if(ObjectUtil.isNotEmpty(product)){
+                bean.setProductName(product.getProductName());
+                bean.setProductNo(product.getProductNo());
+                bean.setProductUnit(product.getProductUnit());
+                bean.setOrderQuantity(product.getOrderQuantity());
+                bean.setOrderPrice(product.getOrderPrice());
+                bean.setSubtotal(product.getSubtotal());
+                bean.setOrderNo(product.getOrderNo());
+                bean.setRemark(orderMain.getRemark());
+            }
+            return bean;
+        }).toList();
+        return orderItemDeliverVos;
+    }
+
+    /**
+     * 处理待处理的订单
+     */
+    @Override
+    public void handlePendingOrder(PendingOrderListBo pendingOrderListBo) {
+        PendingOrderListVo pendingOrderListVo = remoteZhongChePullService.mallOrderPendingList(pendingOrderListBo);
+        List<PendingOrderRecord> records = pendingOrderListVo.getRecords();
+        List<String> orderNos = records.stream().map(PendingOrderRecord::getOrderNo).toList();
+        orderNos.forEach(orderNo -> {
+            boolean exists = baseMapper.exists(
+                Wrappers.lambdaQuery(OrderMainCrrcExt.class)
+                    .eq(OrderMainCrrcExt::getCrrcOrderNo, orderNo)
+            );
+            if(!exists){
+                OrderDetailBo orderDetailBo = new OrderDetailBo();
+                orderDetailBo.setOrderNo(orderNo);
+                OrderDetailVo orderDetailVo = remoteZhongChePullService.mallOrderDetail(orderDetailBo);
+                //获取省市区乡的名称
+                //省
+                AreaQueryBo provinceNameAreaQueryBo = new AreaQueryBo();
+                provinceNameAreaQueryBo.setLevel(1);
+                provinceNameAreaQueryBo.setPid("0");
+                AreaVo provinceNameAreaVo = remoteZhongChePullService.areaQuery(provinceNameAreaQueryBo);
+                Map<String, String> provinceNameMap = provinceNameAreaVo.getAreas().stream().collect(Collectors.toMap(Area::getId, Area::getName));
+                //市
+                AreaQueryBo cityNameAreaQueryBo = new AreaQueryBo();
+                cityNameAreaQueryBo.setLevel(2);
+                cityNameAreaQueryBo.setPid(orderDetailVo.getProvinceId());
+                AreaVo cityNameAreaVo = remoteZhongChePullService.areaQuery(cityNameAreaQueryBo);
+                Map<String, String> cityNameMap = cityNameAreaVo.getAreas().stream().collect(Collectors.toMap(Area::getId, Area::getName));
+                //区
+                AreaQueryBo countyNameAreaQueryBo = new AreaQueryBo();
+                countyNameAreaQueryBo.setLevel(3);
+                countyNameAreaQueryBo.setPid(orderDetailVo.getCityId());
+                AreaVo countyNameAreaVo = remoteZhongChePullService.areaQuery(countyNameAreaQueryBo);
+                Map<String, String> countyNameMap = countyNameAreaVo.getAreas().stream().collect(Collectors.toMap(Area::getId, Area::getName));
+                //乡
+                AreaQueryBo townNameAreaQueryBo = new AreaQueryBo();
+                townNameAreaQueryBo.setLevel(4);
+                townNameAreaQueryBo.setPid(orderDetailVo.getCountyId());
+                AreaVo townNameAreaVo = remoteZhongChePullService.areaQuery(townNameAreaQueryBo);
+                Map<String, String> townNameMap = townNameAreaVo.getAreas().stream().collect(Collectors.toMap(Area::getId, Area::getName));
+
+                orderDetailVo.setProvinceName(provinceNameMap.get(orderDetailVo.getProvinceId()));
+                orderDetailVo.setCityName(cityNameMap.get(orderDetailVo.getCityId()));
+                orderDetailVo.setCountyName(countyNameMap.get(orderDetailVo.getCountyId()));
+                orderDetailVo.setTownName(townNameMap.get(orderDetailVo.getTownId()));
+                OrderNoDto orderNoDto = remoteExternalOrderService.createZhongCheOrder(orderDetailVo);
+                log.info("新订单执行结果,orderNoDto={}", JSONUtil.toJsonStr(orderNoDto));
+            }
+        });
+
+    }
+
+    /**
+     * 同步项目订单库存信息
+     */
+    @Override
+    public void syncProductInventory() {
+        List<OrderMainCrrcExt> orderMainCrrcExts = baseMapper.selectList();
+        List<Long> orderId = orderMainCrrcExts.stream().map(OrderMainCrrcExt::getId).toList();
+        List<OrderProduct> products = orderProductService.list(Wrappers.lambdaQuery(OrderProduct.class).in(OrderProduct::getOrderId, orderId));
+        //将订单商品按照商品id分组,key为商品id,value为商品订购数量之和
+        Map<Long, Long> productIdToOrderQuantitySum = products.stream().collect(Collectors.groupingBy(OrderProduct::getProductId, Collectors.summingLong(OrderProduct::getOrderQuantity)));
+        remoteExternalProductService.syncExternalProductInventory(productIdToOrderQuantitySum.entrySet().stream().map(entry -> {
+            ExternalProductDto externalProductDto = new ExternalProductDto();
+            externalProductDto.setProductId(entry.getKey());
+            externalProductDto.setItemId(2028409445955592193L);
+            externalProductDto.setAvailableInventory(Math.toIntExact(entry.getValue()));
+            return externalProductDto;
+        }).toList());
+    }
+
+    /**
+     * 一键确认订单
+     */
+    @Override
+    public void oneKeyConfirmOrder(Integer limit) {
+
+    }
 }

+ 87 - 74
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderMainServiceImpl.java

@@ -712,68 +712,76 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
         if (existingOrder == null) {
             throw new ServiceException("订单不存在");
         }
-        String platformCode = PlatformContext.getPlatform();
-        // 判断是否为 market 平台,且是未拆分的子订单
-        if (ObjectUtils.isNotEmpty(platformCode)
-            && "market".equals(platformCode)
-            && SysPlatformYesNo.NO.getCode().equals(existingOrder.getIsSplitChild())
-            // 确保订单还未被拆分过,防止重复拆分
-        ) {
-
-            log.info("Market平台订单确认,开始处理自营商品拆分,订单ID: {}", orderId);
-            // 1. 提取所有订单商品ID
-            List<Long> orderProductIds = updatedProducts.stream()
-                .map(OrderProductBo::getId)
-                .filter(Objects::nonNull)
-                .collect(Collectors.toList());
-
-            List<OrderProductVo> orderProductVoList = orderProductMapper.selectVoByIds(orderProductIds);
-            // 1. 提取所有商品ID
-            List<Long> productIds = orderProductVoList.stream()
-                .map(OrderProductVo::getProductId)
-                .filter(Objects::nonNull)
-                .collect(Collectors.toList());
-
-            if (CollUtil.isNotEmpty(productIds)) {
-                // 2. 一次性获取所有商品详情 (避免循环查库)
-                List<ProductVo> productDetails = remoteProductService.getProductDetails(productIds);
-
-                // 3. 构建 自营商品ID -> ProductVo 的映射
-                // 假设 getIsSelf() 返回 Integer, 1 代表自营
-                Map<Long, ProductVo> selfProductMap = productDetails.stream()
-                    .filter(p -> Integer.valueOf(1).equals(p.getIsSelf()))
-                    .collect(Collectors.toMap(ProductVo::getId, Function.identity()));
-
-                // 4. 如果存在自营商品,则构建分配规则
-                if (!selfProductMap.isEmpty()) {
-                    OrderSplitAssignBo assignBo = new OrderSplitAssignBo();
-                    assignBo.setOrderId(orderId);
-                    assignBo.setRemark("Market平台自动拆分自营订单");
-
-                    List<OrderProductAssignRule> rules = new ArrayList<>();
-
-                    for (OrderProductVo bo : orderProductVoList) {
-                        Long productId = bo.getProductId();
-                        // 如果该商品是自营商品
-                        if (selfProductMap.containsKey(productId)) {
-                            OrderProductAssignRule rule = new OrderProductAssignRule();
-                            rule.setItemId(bo.getId()); // 设置订单商品行ID
-                            // 假设自营商品分配给特定的供应商ID,或者设置为 CUSTOMER 类型
-                            rule.setAssigneeId(null);
-                            rule.setAssigneeType(AssigneeTypeConstants.CUSTOMER.getCode());
-                            rules.add(rule);
-                        }
-                    }
-
-                    if (!rules.isEmpty()) {
-                        assignBo.setItemRules(rules);
-                        // 调用分配服务进行拆单
-                        orderAssignmentService.splitAssign(assignBo);
-                        log.info("订单 {} 的自营商品已成功拆分为新子单", orderId);
-                    }
-                }
-            }
-        }
+        // 判断是否为 zhongche 平台
+        if(Objects.equals(existingOrder.getDataSource(),"zhongche")){
+            this.accept(orderId);
+        }
+        // 判断是否为 tongji 平台
+        if(Objects.equals(existingOrder.getDataSource(),"tongji")){
+            this.accept(orderId);
+        }
+//        String platformCode = PlatformContext.getPlatform();
+//        // 判断是否为 market 平台,且是未拆分的子订单
+//        if (ObjectUtils.isNotEmpty(platformCode)
+//            && "market".equals(platformCode)
+//            && SysPlatformYesNo.NO.getCode().equals(existingOrder.getIsSplitChild())
+//            // 确保订单还未被拆分过,防止重复拆分
+//        ) {
+//
+//            log.info("Market平台订单确认,开始处理自营商品拆分,订单ID: {}", orderId);
+//            // 1. 提取所有订单商品ID
+//            List<Long> orderProductIds = updatedProducts.stream()
+//                .map(OrderProductBo::getId)
+//                .filter(Objects::nonNull)
+//                .collect(Collectors.toList());
+//
+//            List<OrderProductVo> orderProductVoList = orderProductMapper.selectVoByIds(orderProductIds);
+//            // 1. 提取所有商品ID
+//            List<Long> productIds = orderProductVoList.stream()
+//                .map(OrderProductVo::getProductId)
+//                .filter(Objects::nonNull)
+//                .collect(Collectors.toList());
+//
+//            if (CollUtil.isNotEmpty(productIds)) {
+//                // 2. 一次性获取所有商品详情 (避免循环查库)
+//                List<ProductVo> productDetails = remoteProductService.getProductDetails(productIds);
+//
+//                // 3. 构建 自营商品ID -> ProductVo 的映射
+//                // 假设 getIsSelf() 返回 Integer, 1 代表自营
+//                Map<Long, ProductVo> selfProductMap = productDetails.stream()
+//                    .filter(p -> Integer.valueOf(1).equals(p.getIsSelf()))
+//                    .collect(Collectors.toMap(ProductVo::getId, Function.identity()));
+//
+//                // 4. 如果存在自营商品,则构建分配规则
+//                if (!selfProductMap.isEmpty()) {
+//                    OrderSplitAssignBo assignBo = new OrderSplitAssignBo();
+//                    assignBo.setOrderId(orderId);
+//                    assignBo.setRemark("Market平台自动拆分自营订单");
+//
+//                    List<OrderProductAssignRule> rules = new ArrayList<>();
+//
+//                    for (OrderProductVo bo : orderProductVoList) {
+//                        Long productId = bo.getProductId();
+//                        // 如果该商品是自营商品
+//                        if (selfProductMap.containsKey(productId)) {
+//                            OrderProductAssignRule rule = new OrderProductAssignRule();
+//                            rule.setItemId(bo.getId()); // 设置订单商品行ID
+//                            // 假设自营商品分配给特定的供应商ID,或者设置为 CUSTOMER 类型
+//                            rule.setAssigneeId(null);
+//                            rule.setAssigneeType(AssigneeTypeConstants.CUSTOMER.getCode());
+//                            rules.add(rule);
+//                        }
+//                    }
+//
+//                    if (!rules.isEmpty()) {
+//                        assignBo.setItemRules(rules);
+//                        // 调用分配服务进行拆单
+//                        orderAssignmentService.splitAssign(assignBo);
+//                        log.info("订单 {} 的自营商品已成功拆分为新子单", orderId);
+//                    }
+//                }
+//            }
+//        }
 
         // 2. 检查当前状态:只允许从“待确认”(比如状态0或1)变为“待发货”(2)
         if (!OrderStatus.PENDING_PAYMENT.getCode().equals(existingOrder.getOrderStatus()) && !OrderStatus.PENDING_CONFIRMATION.getCode().equals(existingOrder.getOrderStatus())) {
@@ -982,6 +990,10 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
         OrderMain order = new OrderMain();
         order.setId(bo.getId());
         order.setOrderStatus(bo.getOrderStatus());
+        //如果是项目订单取消则要调用拒单
+        if (Objects.equals("7", bo.getOrderStatus())) {
+            this.reject(bo.getId(), "取消订单");
+        }
         return baseMapper.updateById(order);
     }
 
@@ -1163,12 +1175,14 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
         if (goodsUpdateVo.getResult() != 1) {
             throw new ZhongcheException("中车订单扩展信息不存在");
         }
-        OrderMain update = new OrderMain();
-        update.setId(id);
-        update.setOrderStatus(OrderStatus.PENDING_SHIPMENT.getCode());   // ← 待发货
-
-        int rows = baseMapper.updateById(update);
-        return rows > 0;
+        log.info("接单成功{}",orderNo);
+        //更新扩展表
+        orderMainCrrcExtService.update(
+            Wrappers.lambdaUpdate(OrderMainCrrcExt.class)
+                .eq(OrderMainCrrcExt::getId, ext.getId())
+                .set(OrderMainCrrcExt::getMallOrderNo, orderNo)
+        );
+        return true;
 
 
     }
@@ -1180,6 +1194,10 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
         if (orderMain == null) {
             throw new ZhongcheException("订单不存在");
         }
+        List<String> dataSources = List.of("zhongche", "tongji");
+        if(!dataSources.contains(orderMain.getDataSource())){
+            return false;
+        }
         String orderNo = orderMain.getOrderNo();
         // 查扩展表拿中车订单号(ID一致!)
         OrderMainCrrcExt ext = orderMainCrrcExtService.getById(id);
@@ -1192,12 +1210,7 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
         if (goodsUpdateVo.getResult() != 1) {
             throw new ZhongcheException("拒绝失败");
         }
-        OrderMain update = new OrderMain();
-        update.setId(id);
-        update.setOrderStatus("7");
-        update.setRemark(reason);
-        int rows = baseMapper.updateById(update);
-        return rows > 0;
+        return true;
     }
 
     @Override

+ 2 - 2
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/utils/kd100/Kd100Util.java

@@ -55,8 +55,8 @@ public class Kd100Util {
     public static void main(String[] args) {
         QueryTrackDTO param = QueryTrackDTO.builder()
                 .com("shunfeng")
-                .num("SF0224870584349")
-                .phone("18062697722")
+                .num("SF5196958100022")
+                .phone("13708974693")
                 .build();
         TrackVO orderTracesByJson = queryTrack(param);
         System.out.println(JSONUtil.toJsonStr(orderTracesByJson));

+ 2 - 1
ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderProductMapper.xml

@@ -32,7 +32,8 @@
                op.assigned_child_order_id                            AS assignedChildOrderId,
                op.status                                             AS status,
                op.del_flag                                           AS delFlag,
-               op.remark                                             AS remark
+               op.remark                                             AS remark,
+               op.tax_rate                                          AS taxRate
         FROM order_product op
                  LEFT JOIN order_deliver od ON od.order_id = op.order_id
                  LEFT JOIN order_deliver_product odp ON odp.deliver_id = od.id

+ 17 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteComLogisticsCompanyServiceImpl.java

@@ -1,8 +1,12 @@
 package org.dromara.system.dubbo;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.dromara.system.api.RemoteComLogisticsCompanyService;
+import org.dromara.system.api.domain.vo.RemoteLogisticsCompanyVo;
 import org.dromara.system.domain.ComLogisticsCompany;
 import org.dromara.system.service.IComLogisticsCompanyService;
 import org.springframework.stereotype.Service;
@@ -51,4 +55,17 @@ public class RemoteComLogisticsCompanyServiceImpl implements RemoteComLogisticsC
             ));
 
     }
+
+    /**
+     * 通过名称获取id
+     *
+     * @param name
+     */
+    @Override
+    public RemoteLogisticsCompanyVo selectLogisticsCompanyByName(String name) {
+        ComLogisticsCompany one = comLogisticsCompanyService.getOne(Wrappers.lambdaQuery(ComLogisticsCompany.class)
+            .eq(ComLogisticsCompany::getLogisticsName, name)
+        );
+        return ObjectUtil.isEmpty(one) ? null : BeanUtil.toBean(one, RemoteLogisticsCompanyVo.class);
+    }
 }