Browse Source

Merge branch 'master' into tys

沐梦. 4 ngày trước cách đây
mục cha
commit
d76b3214cc
100 tập tin đã thay đổi với 3390 bổ sung476 xóa
  1. 3 0
      ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/RemotePartnerPreparedService.java
  2. 104 0
      ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/domain/dto/PartnerPreparedDTO.java
  3. 122 0
      ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/domain/dto/PartnerPreparedProductDTO.java
  4. 10 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/domain/ExternalProductDto.java
  5. 24 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTAddressBo.java
  6. 22 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTAfterSaleBo.java
  7. 90 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTApplyAfterSaleBo.java
  8. 24 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTChangeConsigneeInfoBo.java
  9. 81 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTCreateOrderBo.java
  10. 27 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTDeliveredBo.java
  11. 27 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTGetAreaAvailableBo.java
  12. 18 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTGetSkuImageBo.java
  13. 30 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTGetStorageBo.java
  14. 40 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTGetTokenBo.java
  15. 18 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTGoodsSkuBo.java
  16. 22 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTOrderBo.java
  17. 28 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTRefreshTokenBo.java
  18. 124 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTSaveGoodsInfoBo.java
  19. 49 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTSaveGoodsStorageBo.java
  20. 27 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTShipBo.java
  21. 34 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTUpdateGoodsSaleStatusBo.java
  22. 27 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTAddressVo.java
  23. 18 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTAfterSaleStatusVo.java
  24. 21 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTApplyAfterSaleVo.java
  25. 18 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTCancelAfterSaleVo.java
  26. 24 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTCategoryVo.java
  27. 21 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTCreateOrderVo.java
  28. 57 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTDeliveryInfoVo.java
  29. 18 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTGoodsAreaAvailableVo.java
  30. 110 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTGoodsInfoVo.java
  31. 21 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTGoodsPriceVo.java
  32. 18 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTGoodsSaleStatusVo.java
  33. 21 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTGoodsStorageVo.java
  34. 19 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTOrderResultVo.java
  35. 21 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTSaveGoodsResultVo.java
  36. 21 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTSaveStorageResultVo.java
  37. 34 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTSkuImageVo.java
  38. 27 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTTokenVo.java
  39. 21 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTUpdateSaleStatusResultVo.java
  40. 4 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/service/RemoteExternalProductService.java
  41. 33 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/tongji/RemoteTongJiPullService.java
  42. 13 2
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/RemoteZhongChePullService.java
  43. 4 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/Area.java
  44. 4 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/OrderDeliverGoods.java
  45. 3 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/PendingOrderRecord.java
  46. 4 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/AreaQueryBo.java
  47. 5 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/MessageBo.java
  48. 1 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/OrderConfirmBo.java
  49. 4 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/OrderDetailBo.java
  50. 4 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/PendingOrderListBo.java
  51. 3 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/bo/ZhongCheOrderDeliverBo.java
  52. 2 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/vo/AreaVo.java
  53. 3 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/vo/PendingOrderListVo.java
  54. 4 1
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/domain/vo/ZhongCheOrderDeliverVo.java
  55. 82 0
      ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/RemoteApiOrderService.java
  56. 5 0
      ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/RemoteExternalOrderService.java
  57. 166 0
      ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/domain/bo/ApiApplyReturnBo.java
  58. 90 0
      ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/domain/bo/ApiOrderDeliverBo.java
  59. 35 0
      ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/domain/bo/ApiWithdrawReturnBo.java
  60. 83 0
      ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/domain/bo/RemoteOrderBo.java
  61. 181 0
      ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/domain/dto/ApiOrderDeliverDto.java
  62. 69 0
      ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/domain/dto/ApiTrackDto.java
  63. 265 0
      ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/domain/dto/OrderDto.java
  64. 24 2
      ruoyi-api/ruoyi-api-product/src/main/java/org/dromara/product/api/RemoteCategoryService.java
  65. 2 2
      ruoyi-api/ruoyi-api-product/src/main/java/org/dromara/product/api/RemoteProductService.java
  66. 141 0
      ruoyi-api/ruoyi-api-product/src/main/java/org/dromara/product/api/domain/CategoryDto.java
  67. 7 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteComLogisticsCompanyService.java
  68. 2 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteComStaffService.java
  69. 7 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDeptService.java
  70. 7 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteUserService.java
  71. 51 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteUserWechatService.java
  72. 4 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/bo/RemoteUserBo.java
  73. 2 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/vo/RemoteComStaffVo.java
  74. 33 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/vo/RemoteLogisticsCompanyVo.java
  75. 95 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/vo/RemoteUserWechatVo.java
  76. 3 3
      ruoyi-auth/src/main/java/org/dromara/auth/controller/Auth2Controller.java
  77. 278 59
      ruoyi-auth/src/main/java/org/dromara/auth/controller/MiniTokenController.java
  78. 2 2
      ruoyi-auth/src/main/java/org/dromara/auth/controller/TokenController.java
  79. 6 73
      ruoyi-auth/src/main/java/org/dromara/auth/domain/bo/SysUserWechatBo.java
  80. 0 17
      ruoyi-auth/src/main/java/org/dromara/auth/service/MiniAuthService.java
  81. 0 299
      ruoyi-auth/src/main/java/org/dromara/auth/service/impl/MiniAuthServiceImpl.java
  82. 1 1
      ruoyi-auth/src/main/java/org/dromara/auth/service/impl/PasswordAuthStrategy.java
  83. 3 1
      ruoyi-auth/src/main/resources/application.yml
  84. 106 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/jiaotou/JiaoTouResult.java
  85. 1 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/zhongche/aftersale/bo/AfterSaleConfirmBo.java
  86. 1 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/zhongche/aftersale/bo/AfterSaleRefundBo.java
  87. 1 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/zhongche/aftersale/bo/AfterSaleRejectBo.java
  88. 1 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/zhongche/aftersale/bo/AfterSaleReturnReceivedBo.java
  89. 21 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/zhongche/vo/OrderDetailVo.java
  90. 5 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/AssigneeTypeConstants.java
  91. 19 1
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/OrderSourceEnum.java
  92. 7 1
      ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java
  93. 2 1
      ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/SequenceUtils.java
  94. 6 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/pc/PcStatementOrderController.java
  95. 4 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/impl/StatementInvoiceServiceImpl.java
  96. 14 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/CustomerInfoController.java
  97. 11 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierInfoController.java
  98. 9 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/pc/CustomerRegisterController.java
  99. 1 2
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/pc/PcComplaintsSuggestionsController.java
  100. 5 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/pc/PcContactController.java

+ 3 - 0
ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/RemotePartnerPreparedService.java

@@ -12,6 +12,9 @@ import java.util.Set;
  */
 public interface RemotePartnerPreparedService {
 
+    /*查询备货单详情*/
+    PartnerPreparedDTO getPrepareOrderDetail(String prepareOrderNo);
+
     PartnerPreparedDTO updatePartnerPreparedById(String id);
 
     PartnerPreparedDTO cancelPartnerPreparedById(String prepareOrderNo, String cancelReason);

+ 104 - 0
ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/domain/dto/PartnerPreparedDTO.java

@@ -3,6 +3,7 @@ package org.dromara.customer.api.domain.dto;
 import lombok.Data;
 
 import java.io.Serializable;
+import java.util.Date;
 
 /**
  * author
@@ -12,7 +13,110 @@ import java.io.Serializable;
 public class PartnerPreparedDTO implements Serializable {
     private static final long serialVersionUID = 1L;
 
+    /**
+     * ID
+     */
+    private Long id;
+
+    /**
+     * 伙伴商ID(关联partner_info.id)
+     */
+    private Long partnerId;
+
+    /**
+     * 备货单编号
+     */
+    private String preparedNo;
+
+    /**
+     * 合作项目代码(关联字典 cooperation_code)
+     */
+    private String cooperationCode;
+
+    /**
+     * 客户名称
+     */
+    private String customerName;
+
+    /**
+     * 采购单位名称
+     */
+    private String purchasingUnitName;
+
+    /**
+     * 备货金额
+     */
+    private Long amount;
+
+    /**
+     * 区域
+     */
+    private String area;
+
+    /**
+     * 预计时间
+     */
+    private Date estimatedTime;
+
+    /**
+     * 到期日期
+     */
+    private Date dueDate;
+
+    /**
+     * 发票附件
+     */
+    private String invoiceAttachment;
+
+    /**
+     * 采购单位
+     */
+    private String purchasingUnit;
+
+    /**
+     * 联系人
+     */
+    private String person;
+
+    /**
+     * 部门
+     */
+    private String deptName;
+
+    /**
+     * 联系电话
+     */
+    private String phone;
+
+    /**
+     * 备货状态(0=待审核 1=已通过 2=已驳回)
+     */
+    private Long preparedStatus;
+
+    /**
+     * 处理状态(0=未处理 1=处理中 2=已完成)
+     */
+    private Long dealStatus;
+
+    /**
+     * 驳回原因
+     */
+    private String reject;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    private Date createTime;
+
     private boolean flag;
 
     private String message;
+
 }

+ 122 - 0
ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/domain/dto/PartnerPreparedProductDTO.java

@@ -0,0 +1,122 @@
+package org.dromara.customer.api.domain.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * author
+ * 时间:2026/2/3,17:51
+ */
+@Data
+public class PartnerPreparedProductDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    private Long id;
+
+    /**
+     * 伙伴商ID(关联partner_info.id)
+     */
+    private Long partnerId;
+
+    /**
+     * 备货单编号
+     */
+    private String preparedNo;
+
+    /**
+     * 合作项目代码(关联字典 cooperation_code)
+     */
+    private String cooperationCode;
+
+    /**
+     * 客户名称
+     */
+    private String customerName;
+
+    /**
+     * 采购单位名称
+     */
+    private String purchasingUnitName;
+
+    /**
+     * 备货金额
+     */
+    private Long amount;
+
+    /**
+     * 区域
+     */
+    private String area;
+
+    /**
+     * 预计时间
+     */
+    private Date estimatedTime;
+
+    /**
+     * 到期日期
+     */
+    private Date dueDate;
+
+    /**
+     * 发票附件
+     */
+    private String invoiceAttachment;
+
+    /**
+     * 采购单位
+     */
+    private String purchasingUnit;
+
+    /**
+     * 联系人
+     */
+    private String person;
+
+    /**
+     * 部门
+     */
+    private String deptName;
+
+    /**
+     * 联系电话
+     */
+    private String phone;
+
+    /**
+     * 备货状态(0=待审核 1=已通过 2=已驳回)
+     */
+    private Long preparedStatus;
+
+    /**
+     * 处理状态(0=未处理 1=处理中 2=已完成)
+     */
+    private Long dealStatus;
+
+    /**
+     * 驳回原因
+     */
+    private String reject;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    private Date createTime;
+
+    private boolean flag;
+
+    private String message;
+
+}

+ 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;
+
 }

+ 24 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTAddressBo.java

@@ -0,0 +1,24 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.2.2 根据上级编码获取下一级地址 请求参数
+ */
+@Data
+@Schema(description = "根据上级编码获取下一级地址请求参数")
+public class JTAddressBo {
+
+    /** 授权时获取的token */
+    @Schema(description = "授权时获取的token")
+    private String access_token;
+
+    /** 时间戳 */
+    @Schema(description = "时间戳")
+    private String timestamp;
+
+    /** 上级(父级)编号 */
+    @Schema(description = "上级(父级)编号")
+    private String parentCode;
+}

+ 22 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTAfterSaleBo.java

@@ -0,0 +1,22 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 通用售后BO(取消申请售后/查询售后进度)
+ * 2.5.2 / 2.5.3
+ */
+@Data
+@Schema(description = "通用售后请求参数")
+public class JTAfterSaleBo {
+
+    @Schema(description = "电商的认证token")
+    private String access_token;
+
+    @Schema(description = "(i交投)售后单编号")
+    private String afterSaleSn;
+
+    @Schema(description = "(电商)售后单编号")
+    private String thirdAfterSaleSn;
+}

+ 90 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTApplyAfterSaleBo.java

@@ -0,0 +1,90 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.5.1 申请售后 请求参数
+ */
+@Data
+@Schema(description = "申请售后请求参数")
+public class JTApplyAfterSaleBo {
+
+    @Schema(description = "电商的认证token")
+    private String access_token;
+
+    @Schema(description = "(i交投)售后单编号")
+    private String afterSaleSn;
+
+    @Schema(description = "(i交投)订单编号")
+    private String orderSn;
+
+    @Schema(description = "(电商)订单编号")
+    private String thirdOrderSn;
+
+    @Schema(description = "售后类型 1 退货 2 换货")
+    private String afterSaleType;
+
+    @Schema(description = "售后描述信息")
+    private AfterSaleDescInfo afterSaleDescInfo;
+
+    @Schema(description = "申请售后的商品信息")
+    private AfterSaleGoodsInfo afterSaleGoodsInfo;
+
+    @Schema(description = "申请售后的取件信息")
+    private PickupWareInfo pickupWareInfo;
+
+    @Data
+    @Schema(description = "售后描述信息")
+    public static class AfterSaleDescInfo {
+
+        @Schema(description = "问题描述文字,最大100字符")
+        private String questionDesc;
+
+        @Schema(description = "问题描述图片,多张图片用逗号隔开,最多5张,最大512字符")
+        private String questionPic;
+    }
+
+    @Data
+    @Schema(description = "申请售后的商品信息")
+    public static class AfterSaleGoodsInfo {
+
+        @Schema(description = "申请售后的商品sku")
+        private String skuId;
+
+        @Schema(description = "申请售后的商品数量")
+        private Double skuNum;
+
+        @Schema(description = "申请售后的商品采购单价(元)")
+        private Double skuUnitPrice;
+
+        @Schema(description = "申请售后的商品采购总金额(元)")
+        private Double skuTotalPrice;
+    }
+
+    @Data
+    @Schema(description = "申请售后的取件信息")
+    public static class PickupWareInfo {
+
+        @Schema(description = "取件联系人")
+        private String customerName;
+
+        @Schema(description = "取件联系人联系方式")
+        private String customerMobile;
+
+        @Schema(description = "取件联系人一级地址编码")
+        private String provinceCode;
+
+        @Schema(description = "取件联系人二级地址编码")
+        private String cityCode;
+
+        @Schema(description = "取件联系人三级地址编码")
+        private String countyCode;
+
+        @Schema(description = "取件联系四级地址编码")
+        private String townCode;
+
+        @Schema(description = "取件联系人详细地址")
+        private String address;
+    }
+}

+ 24 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTChangeConsigneeInfoBo.java

@@ -0,0 +1,24 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.4.8 修改订单地址 请求参数
+ */
+@Data
+@Schema(description = "修改订单地址请求参数")
+public class JTChangeConsigneeInfoBo {
+
+    @Schema(description = "电商的认证token")
+    private String access_token;
+
+    @Schema(description = "(i交投)订单编号")
+    private String orderSn;
+
+    @Schema(description = "(电商)订单编号")
+    private String thirdOrderSn;
+
+    @Schema(description = "订单收货地址信息")
+    private JTCreateOrderBo.ConsigneeInfo consigneeInfo;
+}

+ 81 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTCreateOrderBo.java

@@ -0,0 +1,81 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 2.4.1 创建(预占库存)订单 请求参数
+ */
+@Data
+@Schema(description = "创建(预占库存)订单请求参数")
+public class JTCreateOrderBo {
+
+    @Schema(description = "电商的认证token")
+    private String access_token;
+
+    @Schema(description = "客户名称")
+    private String customerName;
+
+    @Schema(description = "(i交投)订单编号")
+    private String orderSn;
+
+    @Schema(description = "订单备注,最长200字符")
+    private String remark;
+
+    @Schema(description = "订单商品总金额(元)")
+    private Double orderGoodsTotalPrice;
+
+    @Schema(description = "订单运费(元)")
+    private Double orderFreightPrice;
+
+    @Schema(description = "订单总金额(商品总金额+运费)(元)")
+    private Double orderTotalPrice;
+
+    @Schema(description = "订单商品集合")
+    private List<OrderGoods> goodsInfoList;
+
+    @Schema(description = "订单收货地址信息")
+    private ConsigneeInfo consigneeInfo;
+
+    @Data
+    @Schema(description = "订单商品")
+    public static class OrderGoods {
+
+        @Schema(description = "订单商品sku")
+        private String sku;
+
+        @Schema(description = "订单商品购买数量")
+        private Double num;
+
+        @Schema(description = "订单商品购买单价(元)")
+        private Double unitPrice;
+    }
+
+    @Data
+    @Schema(description = "订单收货地址信息")
+    public static class ConsigneeInfo {
+
+        @Schema(description = "收货人姓名")
+        private String consigneeName;
+
+        @Schema(description = "收货人一级地址编码")
+        private String consigneeProvinceCode;
+
+        @Schema(description = "收货人二级地址编码")
+        private String consigneeCityCode;
+
+        @Schema(description = "收货人三级地址编码")
+        private String consigneeCountyCode;
+
+        @Schema(description = "收货人四级地址编码")
+        private String consigneeTownCode;
+
+        @Schema(description = "收货人详细地址,最多200字符")
+        private String consigneeAddress;
+
+        @Schema(description = "收货人联系电话")
+        private String consigneeMobile;
+    }
+}

+ 27 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTDeliveredBo.java

@@ -0,0 +1,27 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.4.6 妥投 请求参数
+ */
+@Data
+@Schema(description = "妥投请求参数")
+public class JTDeliveredBo {
+
+    @Schema(description = "(i交投)订单编号")
+    private String orderSn;
+
+    @Schema(description = "(电商)订单编号")
+    private String thirdOrderSn;
+
+    @Schema(description = "包裹编号")
+    private String packageSn;
+
+    @Schema(description = "物流单编号")
+    private String logisticSn;
+
+    @Schema(description = "妥投时间")
+    private String deliveredTime;
+}

+ 27 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTGetAreaAvailableBo.java

@@ -0,0 +1,27 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.3.8 获取商品区划可售信息 请求参数
+ */
+@Data
+@Schema(description = "获取商品区划可售信息请求参数")
+public class JTGetAreaAvailableBo {
+
+    @Schema(description = "电商的认证token")
+    private String access_token;
+
+    @Schema(description = "(规格)商品编号")
+    private String goodsSku;
+
+    @Schema(description = "一级(省级)地址编码")
+    private String provinceCode;
+
+    @Schema(description = "二级(市级)地址编码")
+    private String cityCode;
+
+    @Schema(description = "三级(区县)地址编码")
+    private String countyCode;
+}

+ 18 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTGetSkuImageBo.java

@@ -0,0 +1,18 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.3.9 获取商品的图片信息 请求参数
+ */
+@Data
+@Schema(description = "获取商品的图片信息请求参数")
+public class JTGetSkuImageBo {
+
+    @Schema(description = "电商的认证token")
+    private String access_token;
+
+    @Schema(description = "商品sku,多个sku之间用,隔开,最多支持100个sku")
+    private String skus;
+}

+ 30 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTGetStorageBo.java

@@ -0,0 +1,30 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.3.7 获取商品区划库存信息 请求参数
+ */
+@Data
+@Schema(description = "获取商品区划库存信息请求参数")
+public class JTGetStorageBo {
+
+    @Schema(description = "电商的认证token")
+    private String access_token;
+
+    @Schema(description = "(规格)商品编号")
+    private String goodsSku;
+
+    @Schema(description = "一级(省级)地址编码")
+    private String provinceCode;
+
+    @Schema(description = "二级(市级)地址编码")
+    private String cityCode;
+
+    @Schema(description = "三级(区县)地址编码")
+    private String countyCode;
+
+    @Schema(description = "已选数量")
+    private Integer goodsSkuNum;
+}

+ 40 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTGetTokenBo.java

@@ -0,0 +1,40 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.1.1 获取token 请求参数
+ */
+@Data
+@Schema(description = "i交投获取token请求参数")
+public class JTGetTokenBo {
+
+    /** i交投提供的用户名 */
+    @Schema(description = "i交投提供的用户名")
+    private String username;
+
+    /** i交投提供的密码(RSA公钥加密) */
+    @Schema(description = "i交投提供的密码(RSA公钥加密)")
+    private String password;
+
+    /** 认证类型,默认sign */
+    @Schema(description = "认证类型,默认sign")
+    private String grant_type;
+
+    /** 当日开始时间日期时间戳(ms) */
+    @Schema(description = "当日开始时间日期时间戳(ms)")
+    private String deviceId;
+
+    /** 签名(username+password+deviceId的低位无盐值32位md5值) */
+    @Schema(description = "签名")
+    private String sign;
+
+    /** i交投提供 */
+    @Schema(description = "client_id")
+    private String client_id;
+
+    /** i交投提供 */
+    @Schema(description = "client_secret")
+    private String client_secret;
+}

+ 18 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTGoodsSkuBo.java

@@ -0,0 +1,18 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.3.4 / 2.3.5 / 2.3.6 通用商品SKU查询请求参数
+ */
+@Data
+@Schema(description = "商品SKU查询请求参数")
+public class JTGoodsSkuBo {
+
+    @Schema(description = "电商的认证token")
+    private String access_token;
+
+    @Schema(description = "(规格)商品编号")
+    private String goodsSku;
+}

+ 22 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTOrderBo.java

@@ -0,0 +1,22 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 通用订单BO(确认订单/取消订单/获取订单物流/订单确认收货)
+ * 2.4.2 / 2.4.3 / 2.4.5 / 2.4.7
+ */
+@Data
+@Schema(description = "通用订单请求参数")
+public class JTOrderBo {
+
+    @Schema(description = "电商的认证token")
+    private String access_token;
+
+    @Schema(description = "(i交投)订单编号")
+    private String orderSn;
+
+    @Schema(description = "(电商)订单编号")
+    private String thirdOrderSn;
+}

+ 28 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTRefreshTokenBo.java

@@ -0,0 +1,28 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.1.2 刷新token 请求参数
+ */
+@Data
+@Schema(description = "i交投刷新token请求参数")
+public class JTRefreshTokenBo {
+
+    /** 认证类型,默认refresh_token */
+    @Schema(description = "认证类型,默认refresh_token")
+    private String grant_type;
+
+    /** 刷新token必要条件 */
+    @Schema(description = "refresh_token")
+    private String refresh_token;
+
+    /** i交投提供 */
+    @Schema(description = "client_id")
+    private String client_id;
+
+    /** i交投提供 */
+    @Schema(description = "client_secret")
+    private String client_secret;
+}

+ 124 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTSaveGoodsInfoBo.java

@@ -0,0 +1,124 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 2.3.1 保存(更新)商品信息 请求参数
+ */
+@Data
+@Schema(description = "保存(更新)商品信息请求参数")
+public class JTSaveGoodsInfoBo {
+
+    @Schema(description = "授权时获取的token")
+    private String access_token;
+
+    @Schema(description = "时间戳")
+    private String timestamp;
+
+    @Schema(description = "商品信息列表")
+    private List<GoodsInfo> goodsInfo;
+
+    @Data
+    @Schema(description = "商品信息")
+    public static class GoodsInfo {
+
+        @Schema(description = "商品名称")
+        private String goodsName;
+
+        @Schema(description = "主商品编号")
+        private String goodsMainSku;
+
+        @Schema(description = "商品品牌名称")
+        private String goodsBrandName;
+
+        @Schema(description = "商品三级品目编号")
+        private String goodsCategoryCode;
+
+        @Schema(description = "商品主图")
+        private String goodsImage;
+
+        @Schema(description = "商品详情")
+        private String goodsContent;
+
+        @Schema(description = "商品重量(克)")
+        private Double goodsWeight;
+
+        @Schema(description = "商品市场价(元)")
+        private Double goodsMarketPrice;
+
+        @Schema(description = "商品销售价(元)")
+        private Double goodsShopPrice;
+
+        @Schema(description = "上下架状态(1上架,0下架)")
+        private Integer goodsSaleStatus;
+
+        @Schema(description = "销售单位")
+        private String goodsSaleUnit;
+
+        @Schema(description = "售后服务")
+        private String goodsSaleService;
+
+        @Schema(description = "包装清单")
+        private String goodsSalePackage;
+
+        @Schema(description = "商品宣传组图")
+        private List<String> goodsImageList;
+
+        @Schema(description = "商品规格参数集合")
+        private List<GoodsAttr> goodsAttrList;
+
+        @Schema(description = "同类(不同规格)商品集合")
+        private List<SubGoods> subGoodsList;
+    }
+
+    @Data
+    @Schema(description = "商品规格参数")
+    public static class GoodsAttr {
+
+        @Schema(description = "规格名称")
+        private String attrName;
+
+        @Schema(description = "规格值")
+        private String attrValue;
+    }
+
+    @Data
+    @Schema(description = "规格商品")
+    public static class SubGoods {
+
+        @Schema(description = "(规格)商品编号")
+        private String subSku;
+
+        @Schema(description = "商品市场价格(元)")
+        private Double subMarketPrice;
+
+        @Schema(description = "商品销售价(元)")
+        private Double subShopPrice;
+
+        @Schema(description = "商品主图")
+        private String subGoodsImage;
+
+        @Schema(description = "商品上下架状态(1上架,0下架)")
+        private Integer subSaleStatus;
+
+        @Schema(description = "是否厂直直销商品(1是,0否)")
+        private Integer isDirectly;
+
+        @Schema(description = "销售维度(规格)")
+        private List<SubGoodsDim> subGoodsDimList;
+    }
+
+    @Data
+    @Schema(description = "销售维度")
+    public static class SubGoodsDim {
+
+        @Schema(description = "维度名称")
+        private String dimName;
+
+        @Schema(description = "维度值")
+        private String dimValue;
+    }
+}

+ 49 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTSaveGoodsStorageBo.java

@@ -0,0 +1,49 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 2.3.2 保存(更新)商品库存 请求参数
+ */
+@Data
+@Schema(description = "保存(更新)商品库存请求参数")
+public class JTSaveGoodsStorageBo {
+
+    @Schema(description = "授权时获取的token")
+    private String access_token;
+
+    @Schema(description = "时间戳")
+    private String timestamp;
+
+    @Schema(description = "商品库存信息列表")
+    private List<GoodsStorage> goodsInfo;
+
+    @Data
+    @Schema(description = "商品库存信息")
+    public static class GoodsStorage {
+
+        @Schema(description = "商品sku")
+        private String goodsSku;
+
+        @Schema(description = "一级(省级)地址编码")
+        private String provinceCode;
+
+        @Schema(description = "二级(市级)地址编码")
+        private String cityCode;
+
+        @Schema(description = "三级(区县)地址编码")
+        private String countyCode;
+
+        @Schema(description = "四级(乡镇)地址编码")
+        private String townCode;
+
+        @Schema(description = "“有货”或“无货”")
+        private String storageRemark;
+
+        @Schema(description = "区域库存")
+        private Integer storage;
+    }
+}

+ 27 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTShipBo.java

@@ -0,0 +1,27 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.4.4 发货 请求参数
+ */
+@Data
+@Schema(description = "发货请求参数")
+public class JTShipBo {
+
+    @Schema(description = "(i交投)订单编号")
+    private String orderSn;
+
+    @Schema(description = "(电商)订单编号")
+    private String thirdOrderSn;
+
+    @Schema(description = "包裹编号")
+    private String packageSn;
+
+    @Schema(description = "物流单编号")
+    private String logisticSn;
+
+    @Schema(description = "发货时间")
+    private String shipTime;
+}

+ 34 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/bo/JTUpdateGoodsSaleStatusBo.java

@@ -0,0 +1,34 @@
+package org.dromara.external.api.jiaotou.domian.bo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 2.3.3 更新商品上下架状态 请求参数
+ */
+@Data
+@Schema(description = "更新商品上下架状态请求参数")
+public class JTUpdateGoodsSaleStatusBo {
+
+    @Schema(description = "授权时获取的token")
+    private String access_token;
+
+    @Schema(description = "时间戳")
+    private String timestamp;
+
+    @Schema(description = "商品上下架信息")
+    private List<GoodsSaleStatus> goodsInfo;
+
+    @Data
+    @Schema(description = "商品上下架信息")
+    public static class GoodsSaleStatus {
+
+        @Schema(description = "商品sku")
+        private String goodsSku;
+
+        @Schema(description = "上下架状态(1上架,0下架)")
+        private Integer saleStatus;
+    }
+}

+ 27 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTAddressVo.java

@@ -0,0 +1,27 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.2.1 / 2.2.2 地址响应
+ */
+@Data
+@Schema(description = "地址信息响应")
+public class JTAddressVo {
+
+    @Schema(description = "地址编码")
+    private String regionCode;
+
+    @Schema(description = "地址简称")
+    private String regionName;
+
+    @Schema(description = "地址全称")
+    private String regionFullName;
+
+    @Schema(description = "上级(父级)地址编号")
+    private String parentCode;
+
+    @Schema(description = "等级(一级,二级,三级,四级)")
+    private Integer regionLevel;
+}

+ 18 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTAfterSaleStatusVo.java

@@ -0,0 +1,18 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.5.3 查询售后进度 响应
+ */
+@Data
+@Schema(description = "售后进度响应")
+public class JTAfterSaleStatusVo {
+
+    @Schema(description = "(i交投)售后单编号")
+    private String afterSaleSn;
+
+    @Schema(description = "当前售后状态(1提交申请,2商家处理,3商家拒绝,4商家取回商品,5退货完成)")
+    private String afterSaleStatus;
+}

+ 21 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTApplyAfterSaleVo.java

@@ -0,0 +1,21 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.5.1 申请售后 响应
+ */
+@Data
+@Schema(description = "申请售后响应")
+public class JTApplyAfterSaleVo {
+
+    @Schema(description = "(电商)售后单编号,最长32字符")
+    private String thirdAfterSaleSn;
+
+    @Schema(description = "(i交投)售后单编号")
+    private String afterSaleSn;
+
+    @Schema(description = "申请结果(1成功,0失败)")
+    private Integer result;
+}

+ 18 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTCancelAfterSaleVo.java

@@ -0,0 +1,18 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.5.2 取消申请售后 响应
+ */
+@Data
+@Schema(description = "取消申请售后响应")
+public class JTCancelAfterSaleVo {
+
+    @Schema(description = "(i交投)售后单编号")
+    private String afterSaleSn;
+
+    @Schema(description = "申请结果(1成功,0失败)")
+    private Integer result;
+}

+ 24 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTCategoryVo.java

@@ -0,0 +1,24 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.2.3 品目分类响应
+ */
+@Data
+@Schema(description = "品目分类响应")
+public class JTCategoryVo {
+
+    @Schema(description = "品目编码")
+    private String categoryCode;
+
+    @Schema(description = "品目名称")
+    private String categoryName;
+
+    @Schema(description = "等级(一级,二级,三级,四级)")
+    private Integer categoryLevel;
+
+    @Schema(description = "上级(父级)品目编号")
+    private String parentCode;
+}

+ 21 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTCreateOrderVo.java

@@ -0,0 +1,21 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.4.1 创建(预占库存)订单 响应
+ */
+@Data
+@Schema(description = "创建订单响应")
+public class JTCreateOrderVo {
+
+    @Schema(description = "(电商)订单编号,最长32字符")
+    private String thirdOrderSn;
+
+    @Schema(description = "(i交投)订单编号")
+    private String orderSn;
+
+    @Schema(description = "订单创建时间")
+    private String orderCreateTime;
+}

+ 57 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTDeliveryInfoVo.java

@@ -0,0 +1,57 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 2.4.5 获取订单物流信息 响应
+ */
+@Data
+@Schema(description = "订单物流信息响应")
+public class JTDeliveryInfoVo {
+
+    @Schema(description = "(i交投)订单编号")
+    private String orderSn;
+
+    @Schema(description = "有无物流包裹信息(1有,0无)")
+    private Integer isPackage;
+
+    @Schema(description = "物流包裹集合")
+    private List<PackageInfo> packageInfoList;
+
+    @Data
+    @Schema(description = "物流包裹信息")
+    public static class PackageInfo {
+
+        @Schema(description = "包裹号")
+        private String packageSn;
+
+        @Schema(description = "快递单号")
+        private String logisticSn;
+
+        @Schema(description = "快递公司名称")
+        private String expressCompany;
+
+        @Schema(description = "包裹订单商品list")
+        private List<String> skuList;
+
+        @Schema(description = "包裹物流信息集合")
+        private List<LogisticInfo> logisticList;
+    }
+
+    @Data
+    @Schema(description = "物流轨迹信息")
+    public static class LogisticInfo {
+
+        @Schema(description = "物流内容")
+        private String trackContent;
+
+        @Schema(description = "物流操作人")
+        private String trackOperator;
+
+        @Schema(description = "物流操作时间")
+        private String trackMsgTime;
+    }
+}

+ 18 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTGoodsAreaAvailableVo.java

@@ -0,0 +1,18 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.3.8 获取商品区划可售信息 响应
+ */
+@Data
+@Schema(description = "商品区划可售信息响应")
+public class JTGoodsAreaAvailableVo {
+
+    @Schema(description = "(规格)商品编号")
+    private String goodsSku;
+
+    @Schema(description = "是否可售(1可售,0不可售)")
+    private Integer result;
+}

+ 110 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTGoodsInfoVo.java

@@ -0,0 +1,110 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 2.3.4 更新单个商品信息 响应
+ */
+@Data
+@Schema(description = "单个商品信息响应")
+public class JTGoodsInfoVo {
+
+    @Schema(description = "商品名称")
+    private String goodsName;
+
+    @Schema(description = "主商品编号")
+    private String goodsMainSku;
+
+    @Schema(description = "商品品牌名称")
+    private String goodsBrandName;
+
+    @Schema(description = "商品三级品目编号")
+    private String goodsCategoryCode;
+
+    @Schema(description = "商品主图")
+    private String goodsImage;
+
+    @Schema(description = "商品详情")
+    private String goodsContent;
+
+    @Schema(description = "商品重量(克)")
+    private Double goodsWeight;
+
+    @Schema(description = "商品市场价(元)")
+    private Double goodsMarketPrice;
+
+    @Schema(description = "商品销售价(元)")
+    private Double goodsShopPrice;
+
+    @Schema(description = "上下架状态(1上架,0下架)")
+    private Integer goodsSaleStatus;
+
+    @Schema(description = "销售单位")
+    private String goodsSaleUnit;
+
+    @Schema(description = "售后服务")
+    private String goodsSaleService;
+
+    @Schema(description = "包装清单")
+    private String goodsSalePackage;
+
+    @Schema(description = "商品宣传组图")
+    private List<String> goodsImageList;
+
+    @Schema(description = "商品规格参数集合")
+    private List<GoodsAttr> goodsAttrList;
+
+    @Schema(description = "(规格)商品信息")
+    private SubGoodsObj subGoodsObj;
+
+    @Data
+    @Schema(description = "商品规格参数")
+    public static class GoodsAttr {
+
+        @Schema(description = "规格名称")
+        private String attrName;
+
+        @Schema(description = "规格值")
+        private String attrValue;
+    }
+
+    @Data
+    @Schema(description = "(规格)商品信息")
+    public static class SubGoodsObj {
+
+        @Schema(description = "(规格)商品编号")
+        private String subSku;
+
+        @Schema(description = "商品市场价格(元)")
+        private Double subMarketPrice;
+
+        @Schema(description = "商品销售价(元)")
+        private Double subShopPrice;
+
+        @Schema(description = "商品主图")
+        private String subGoodsImage;
+
+        @Schema(description = "规格商品上下架状态(1上架,0下架)")
+        private Integer subSaleStatus;
+
+        @Schema(description = "是否厂直直销商品(1是,0否)")
+        private Integer isDirectly;
+
+        @Schema(description = "销售维度(规格)")
+        private List<SubGoodsDim> subGoodsDimList;
+    }
+
+    @Data
+    @Schema(description = "销售维度")
+    public static class SubGoodsDim {
+
+        @Schema(description = "维度名称")
+        private String dimName;
+
+        @Schema(description = "维度值")
+        private String dimValue;
+    }
+}

+ 21 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTGoodsPriceVo.java

@@ -0,0 +1,21 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.3.6 获取商品价格信息 响应
+ */
+@Data
+@Schema(description = "商品价格信息响应")
+public class JTGoodsPriceVo {
+
+    @Schema(description = "(规格)商品编号")
+    private String goodsSku;
+
+    @Schema(description = "商品市场价格(元)")
+    private Double goodsMarketPrice;
+
+    @Schema(description = "商品销售价格(元)")
+    private Double goodsShopPrice;
+}

+ 18 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTGoodsSaleStatusVo.java

@@ -0,0 +1,18 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.3.5 获取商品上下架状态 响应
+ */
+@Data
+@Schema(description = "商品上下架状态响应")
+public class JTGoodsSaleStatusVo {
+
+    @Schema(description = "(规格)商品编号")
+    private String goodsSku;
+
+    @Schema(description = "商品上下架状态(1上架,0下架)")
+    private Integer goodsSaleStatus;
+}

+ 21 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTGoodsStorageVo.java

@@ -0,0 +1,21 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.3.7 获取商品区划库存信息 响应
+ */
+@Data
+@Schema(description = "商品区划库存信息响应")
+public class JTGoodsStorageVo {
+
+    @Schema(description = "(规格)商品编号")
+    private String goodsSku;
+
+    @Schema(description = "“有货”或者“无货”")
+    private String goodsStorageRemark;
+
+    @Schema(description = "区划库存(没有具体数据时返回0)")
+    private Integer goodsStorage;
+}

+ 19 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTOrderResultVo.java

@@ -0,0 +1,19 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 通用订单结果VO(确认订单/取消订单/发货/妥投/订单确认收货/修改订单地址)
+ * 2.4.2 / 2.4.3 / 2.4.4 / 2.4.6 / 2.4.7 / 2.4.8
+ */
+@Data
+@Schema(description = "通用订单操作结果")
+public class JTOrderResultVo {
+
+    @Schema(description = "(i交投)订单编号")
+    private String orderSn;
+
+    @Schema(description = "操作结果(1成功,0失败)")
+    private Integer result;
+}

+ 21 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTSaveGoodsResultVo.java

@@ -0,0 +1,21 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.3.1 保存(更新)商品信息 响应
+ */
+@Data
+@Schema(description = "保存(更新)商品信息响应")
+public class JTSaveGoodsResultVo {
+
+    @Schema(description = "规格商品编号")
+    private String subSku;
+
+    @Schema(description = "商品保存(更新)结果,成功还是失败")
+    private String result;
+
+    @Schema(description = "结果备注,新增成功为newRecord,更新成功为updateRecord,失败为失败原因")
+    private String msg;
+}

+ 21 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTSaveStorageResultVo.java

@@ -0,0 +1,21 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.3.2 保存(更新)商品库存 响应
+ */
+@Data
+@Schema(description = "保存(更新)商品库存响应")
+public class JTSaveStorageResultVo {
+
+    @Schema(description = "规格商品编号")
+    private String goodsSku;
+
+    @Schema(description = "操作结果(1成功,0失败)")
+    private String result;
+
+    @Schema(description = "结果备注")
+    private String msg;
+}

+ 34 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTSkuImageVo.java

@@ -0,0 +1,34 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 2.3.9 获取商品的图片信息 响应
+ */
+@Data
+@Schema(description = "商品图片信息响应")
+public class JTSkuImageVo {
+
+    @Schema(description = "商品sku")
+    private String skuId;
+
+    @Schema(description = "当前sku的图片集合")
+    private List<UrlInfo> urls;
+
+    @Data
+    @Schema(description = "图片信息")
+    public static class UrlInfo {
+
+        @Schema(description = "图片地址")
+        private String path;
+
+        @Schema(description = "是否是主图(1主图,0轮播图)")
+        private String primary;
+
+        @Schema(description = "图片位置")
+        private String pictureLocation;
+    }
+}

+ 27 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTTokenVo.java

@@ -0,0 +1,27 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.1.1 / 2.1.2 token 响应
+ */
+@Data
+@Schema(description = "i交投token响应")
+public class JTTokenVo {
+
+    @Schema(description = "访问令牌token")
+    private String access_token;
+
+    @Schema(description = "token类型")
+    private String token_type;
+
+    @Schema(description = "刷新token")
+    private String refresh_token;
+
+    @Schema(description = "有效时间")
+    private String expires_in;
+
+    @Schema(description = "scope")
+    private String scope;
+}

+ 21 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/jiaotou/domian/vo/JTUpdateSaleStatusResultVo.java

@@ -0,0 +1,21 @@
+package org.dromara.external.api.jiaotou.domian.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 2.3.3 更新商品上下架状态 响应
+ */
+@Data
+@Schema(description = "更新商品上下架状态响应")
+public class JTUpdateSaleStatusResultVo {
+
+    @Schema(description = "规格商品编号")
+    private String goodsSku;
+
+    @Schema(description = "操作结果(1成功,0失败)")
+    private String result;
+
+    @Schema(description = "结果备注,失败为失败原因")
+    private String msg;
+}

+ 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;
+}

+ 13 - 2
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/zhongche/RemoteZhongChePullService.java

@@ -4,10 +4,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.domain.bo.OrderConfirmBo;
-import org.dromara.external.api.zhongche.domain.bo.OrderRejectBo;
+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;
 
 /**
@@ -15,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;
     //拒单
@@ -27,4 +32,10 @@ public interface RemoteZhongChePullService {
     GoodsUpdateVo mallAftersaleReturnGoodsReceived(AfterSaleReturnReceivedBo bo) throws ZhongcheException;
     //确认退款
     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;
     /**
      * 发货单编号
      * 必填

+ 82 - 0
ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/RemoteApiOrderService.java

@@ -0,0 +1,82 @@
+package org.dromara.product.api;
+
+import org.dromara.product.api.domain.bo.ApiApplyReturnBo;
+import org.dromara.product.api.domain.bo.ApiOrderDeliverBo;
+import org.dromara.product.api.domain.bo.ApiWithdrawReturnBo;
+import org.dromara.product.api.domain.bo.RemoteOrderBo;
+import org.dromara.product.api.domain.dto.ApiOrderDeliverDto;
+import org.dromara.product.api.domain.dto.ApiTrackDto;
+import org.dromara.product.api.domain.dto.OrderDto;
+
+import java.util.List;
+
+/**
+ * @author
+ * @date 2026/5/15 上午9:08
+ */
+public interface RemoteApiOrderService {
+
+    /**
+     * 创建订单
+     *
+     * @param remoteOrderBo 订单信息
+     */
+    Long apiCreateOrder(RemoteOrderBo remoteOrderBo);
+
+    /**
+     * 获取订单信息
+     *
+     * @param orderNo 订单编号
+     */
+    OrderDto apiGetOrder(String orderNo);
+
+    /*订单确认*/
+    void confirmOrder(RemoteOrderBo remoteOrderBo);
+
+    /**
+     * 确认收货
+     *
+     * @param remoteOrderBo 订单信息(包含orderId或orderNo)
+     * @return 是否成功
+     */
+    Boolean apiConfirmReceipt(RemoteOrderBo remoteOrderBo);
+
+    /**
+     * 取消订单
+     *
+     * @param remoteOrderBo 订单信息
+     */
+    int apiCancelOrder(RemoteOrderBo remoteOrderBo);
+
+    /**
+     * 申请售后
+     *
+     * @param apiApplyReturnBo 售后申请信息
+     * @return 售后单ID
+     */
+    Long apiApplyReturn(ApiApplyReturnBo apiApplyReturnBo);
+
+    /**
+     * 撤回售后
+     *
+     * @param apiWithdrawReturnBo 撤回售后信息(包含returnId或returnNo)
+     * @return 影响行数
+     */
+    int apiWithdrawReturn(ApiWithdrawReturnBo apiWithdrawReturnBo);
+
+    /**
+     * 查看当前订单的发货记录信息
+     *
+     * @param apiOrderDeliverBo 订单发货查询信息(包含orderId或orderNo)
+     * @return 发货记录列表
+     */
+    List<ApiOrderDeliverDto> selectOrderDeliver(ApiOrderDeliverBo apiOrderDeliverBo);
+
+    /**
+     * 查看物流信息
+     *
+     * @param apiOrderDeliverBo 售后单编号
+     * @return 物流轨迹信息
+     */
+    ApiTrackDto selectTrack(ApiOrderDeliverBo apiOrderDeliverBo);
+}

+ 5 - 0
ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/RemoteExternalOrderService.java

@@ -31,6 +31,11 @@ public interface RemoteExternalOrderService {
     * */
     void notice(OrderNoticeDto bo);
 
+    /**
+    * 订单发货
+    * */
+    void deliverOrder(Long orderId);
+
     /**
      * 获取订单编号
      * @param ZCorderNo

+ 166 - 0
ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/domain/bo/ApiApplyReturnBo.java

@@ -0,0 +1,166 @@
+package org.dromara.product.api.domain.bo;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * API申请售后业务对象
+ *
+ * @author System
+ * @date 2026-05-15
+ */
+@Data
+public class ApiApplyReturnBo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 原订单ID(orderId和orderNo二选一)
+     */
+    private Long orderId;
+
+    /**
+     * 原订单编号(orderId和orderNo二选一)
+     */
+    private String orderNo;
+
+    /**
+     * 售后服务类型(如:退货、换货、仅退款等)
+     */
+    @NotBlank(message = "售后服务类型不能为空")
+    private String serviceType;
+
+    /**
+     * 退货原因id
+     */
+    private Long returnReasonId;
+
+    /**
+     * 退货原因
+     */
+    private String returnReason;
+
+    /**
+     * 问题描述
+     */
+    private String problemDescription;
+
+    /**
+     * 凭证图片URL(多张图片用逗号分隔)
+     */
+    private String voucherPhoto;
+
+    /**
+     * 运费金额
+     */
+    private BigDecimal shippingFee;
+
+    /**
+     * 是否承担运费(0-否 1-是)
+     */
+    private String isShippingFee;
+
+    /**
+     * 售后备注
+     */
+    private String afterSalesRemarks;
+
+    /**
+     * 退货方式(如:上门取件、自行寄回)
+     */
+    private String returnMethod;
+
+    /**
+     * 取件人姓名(上门取件时必填)
+     */
+    private String chargebackName;
+
+    /**
+     * 取件联系电话(上门取件时必填)
+     */
+    private String chargebackPhone;
+
+    /**
+     * 预约取件时间(上门取件时必填,格式:yyyy-MM-dd HH:mm:ss)
+     */
+    private String chargebackPickupTime;
+
+    /**
+     * 取件省(上门取件时必填)
+     */
+    private String chargebackProvincial;
+
+    /**
+     * 取件市(上门取件时必填)
+     */
+    private String chargebackCity;
+
+    /**
+     * 取件区/县(上门取件时必填)
+     */
+    private String chargebackCounty;
+
+    /**
+     * 取件详细地址(上门取件时必填)
+     */
+    private String chargebackAddress;
+
+    /**
+     * 退货商品列表
+     */
+    @NotNull(message = "退货商品列表不能为空")
+    private List<ApiReturnItem> returnItems;
+
+    /**
+     * API退货商品项
+     */
+    @Data
+    public static class ApiReturnItem implements Serializable {
+        @Serial
+        private static final long serialVersionUID = 1L;
+
+        /**
+         * 原订单明细ID
+         */
+        @NotNull(message = "订单明细ID不能为空")
+        private Long orderProductId;
+
+        /**
+         * 商品ID
+         */
+        private Long productId;
+
+        /**
+         * 商品名称
+         */
+        private String productName;
+
+        /**
+         * 本次退货数量
+         */
+        @NotNull(message = "退货数量不能为空")
+        private Long returnQuantity;
+
+        /**
+         * 商品单价
+         */
+        private BigDecimal unitPrice;
+
+        /**
+         * 该商品的具体退货原因
+         */
+        private String reasonDetail;
+
+        /**
+         * 备注
+         */
+        private String remark;
+    }
+}

+ 90 - 0
ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/domain/bo/ApiOrderDeliverBo.java

@@ -0,0 +1,90 @@
+package org.dromara.product.api.domain.bo;
+
+import lombok.Data;
+
+@Data
+public class ApiOrderDeliverBo {
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 订单id
+     */
+    private Long orderId;
+
+    /**
+     * 订单编号
+     */
+    private String orderCode;
+
+    /**
+     * 订单发货编号
+     */
+    private String deliverCode;
+
+    /**
+     * 物流包裹号
+     */
+    private String logisticPackNo;
+
+    /**
+     * 发货方式
+     */
+    private String deliverMethod;
+
+    /**
+     * 送货人姓名
+     */
+    private String deliverMan;
+
+    /**
+     * 送货人联系电话
+     */
+    private String phone;
+
+    /**
+     * 物流状态
+     */
+    private String logisticsStatus;
+
+    /**
+     * 发货备注
+     */
+    private String deliverRemark;
+
+    /**
+     * 装箱/验货备注
+     */
+    private String checklistRemark;
+
+    /**
+     * 承运物流公司
+     */
+    private Long logisticsCompanyId;
+
+    private String logisticsCompanyCode;
+
+    /**
+     * 物流单号
+     */
+    private String logisticNo;
+
+    /**
+     * 包裹状态
+     */
+    private String logisticPackStatus;
+
+    /**
+     * 收货人电话
+     */
+    private String consigneePhone;
+
+    private String dataSource;
+
+    /**
+     * 备注
+     */
+    private String remark;
+}

+ 35 - 0
ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/domain/bo/ApiWithdrawReturnBo.java

@@ -0,0 +1,35 @@
+package org.dromara.product.api.domain.bo;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * API撤回售后业务对象
+ *
+ * @author System
+ * @date 2026-05-15
+ */
+@Data
+public class ApiWithdrawReturnBo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 售后单ID(returnId和returnNo二选一)
+     */
+    private Long returnId;
+
+    /**
+     * 售后单号(returnId和returnNo二选一)
+     */
+    private String returnNo;
+
+    /**
+     * 撤回原因
+     */
+    private String withdrawReason;
+}

+ 83 - 0
ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/domain/bo/RemoteOrderBo.java

@@ -0,0 +1,83 @@
+package org.dromara.product.api.domain.bo;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Set;
+
+@Data
+public class RemoteOrderBo implements Serializable {
+    /**
+     * 订单ID(用于取消订单等操作)
+     */
+    private Long orderId;
+
+    /**
+     * 订单编号(用于取消订单等操作)
+     */
+    private String orderNo;
+
+    /**
+     * 收货地址ID
+     */
+    @NotNull(message = "收货地址不能为空")
+    private Long shippingAddressId;
+
+    /**
+     * 配送时间(格式:yyyy-MM-dd)
+     */
+//    @NotBlank(message = "配送时间不能为空")
+    private String deliveryDate; // 前端传字符串,后端转为 Date
+
+
+    /*支付方式*/
+    private String payType;
+
+    /*费用类型*/
+    private String expenseType;
+
+    /**
+     * 采购事由
+     */
+//    @NotBlank(message = "采购事由不能为空")
+    private String purchaseReason;
+
+    /**
+     * 订单备注
+     */
+    private String remark;
+
+    /**
+     * 运费(元)
+     */
+    private BigDecimal shippingFee;
+
+    /**
+     * 订单来源
+     */
+    private String orderSource;
+
+    /**
+     * 商品信息
+     */
+    private List<ApiOrderProduct> productInfo;
+
+    @Data
+    public class ApiOrderProduct {
+
+        /**
+         * 商品ID
+         */
+        @NotNull(message = "商品ID不能为空")
+        private Long productId;
+
+        /**
+         * 商品数量
+         */
+        @NotNull(message = "商品数量不能为空")
+        private Long productNum;
+    }
+}

+ 181 - 0
ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/domain/dto/ApiOrderDeliverDto.java

@@ -0,0 +1,181 @@
+package org.dromara.product.api.domain.dto;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import org.dromara.product.api.domain.bo.ApiApplyReturnBo;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * API订单发货记录DTO
+ *
+ * @author System
+ * @date 2026-05-15
+ */
+@Data
+public class ApiOrderDeliverDto implements Serializable {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 订单id
+     */
+    private Long orderId;
+
+    /**
+     * 订单编号
+     */
+    private String orderCode;
+
+    /**
+     * 订单发货编号
+     */
+    private String deliverCode;
+
+    /**
+     * 物流包裹号
+     */
+    private String logisticPackNo;
+
+    /**
+     * 发货方式
+     */
+    private String deliverMethod;
+
+    /**
+     * 送货人姓名
+     */
+    private String deliverMan;
+
+    /**
+     * 送货人联系电话
+     */
+    private String phone;
+
+    /**
+     * 物流状态
+     */
+    private String logisticsStatus;
+
+    /**
+     * 发货备注
+     */
+    private String deliverRemark;
+
+    /**
+     * 装箱/验货备注
+     */
+    private String checklistRemark;
+
+    /**
+     * 承运物流公司
+     */
+    private Long logisticsCompanyId;
+
+    private String logisticsCompanyCode;
+
+    /**
+     * 物流单号
+     */
+    private String logisticNo;
+
+    /**
+     * 包裹状态
+     */
+    private String logisticPackStatus;
+
+    /**
+     * 收货人电话
+     */
+    private String consigneePhone;
+
+    private String dataSource;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 退货商品列表
+     */
+    private List<ApiOrderDeliverProduct> deliverProductList;
+
+    @Data
+    public class ApiOrderDeliverProduct implements Serializable {
+
+        @Serial
+        private static final long serialVersionUID = 1L;
+
+        /**
+         * 主键ID
+         */
+        private Long id;
+
+        /**
+         * 发货单
+         */
+        private Long deliverId;
+
+        /**
+         * 商品编号
+         */
+        private Long productId;
+
+        /**
+         * 产品编号(业务编码)
+         */
+        private String productNo;
+
+        /**
+         * 商品名称
+         */
+        private String productName;
+
+        /**
+         * 商品单位
+         */
+        private Long productUnitId;
+
+        /**
+         * 商品单位
+         */
+        private String productUnit;
+
+        /**
+         * 本次发货数量
+         */
+        private Long deliverNum;
+
+        /**
+         * 订单单价(元)
+         */
+        private BigDecimal orderPrice;
+
+        /**
+         * 行小计金额(元)
+         */
+        private BigDecimal subtotal;
+
+        /**
+         * 备注
+         */
+        private String remark;
+
+        private String dataSource;
+
+        private String orderNo;
+
+
+    }
+
+    private boolean flag;
+
+    private String message;
+}

+ 69 - 0
ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/domain/dto/ApiTrackDto.java

@@ -0,0 +1,69 @@
+package org.dromara.product.api.domain.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class ApiTrackDto implements Serializable {
+    /**
+     * 消息体
+     */
+    private String message;
+
+    /**
+     * 快递单当前状态,默认为0在途,1揽收,2疑难,3签收,4退签,5派件,8清关,14拒签等10个基础物流状态
+     */
+    private String state;
+
+    /**
+     * 是否签收标记,0未签收,1已签收,请忽略,明细状态请参考state字段
+     */
+    private String ischeck;
+
+    /**
+     * 快递单明细状态标记,暂未实现,请忽略
+     */
+    private String condition;
+
+    /**
+     * 快递公司编码,一律用小写字母
+     */
+    private String com;
+
+    /**
+     * 单号
+     */
+    private String nu;
+
+    /**
+     * 通讯状态,请忽略
+     */
+    private String status;
+
+    /**
+     * 最新查询结果,数组,包含多项,全量,倒序(即时间最新的在最前),每项都是对象,对象包含字段请展开
+     */
+    private List<TrackData> data;
+
+    @Data
+    public class TrackData implements Serializable {
+        private static final long serialVersionUID = 1L;
+
+        /**
+         * 时间,原始格式
+         */
+        private String time;
+
+        /**
+         * 格式化后时间
+         */
+        private String ftime;
+
+        /**
+         * 内容
+         */
+        private String context;
+    }
+}

+ 265 - 0
ruoyi-api/ruoyi-api-order/src/main/java/org/dromara/product/api/domain/dto/OrderDto.java

@@ -0,0 +1,265 @@
+package org.dromara.product.api.domain.dto;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * API订单DTO
+ *
+ * @author System
+ * @date 2026-05-15
+ */
+@Data
+public class OrderDto implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 订单编号
+     */
+    private String orderNo;
+
+    /**
+     * 客户ID
+     */
+    private Long customerId;
+
+    /**
+     * 客户编号
+     */
+    private String customerCode;
+
+    /**
+     * 用户ID
+     */
+    private Long userId;
+
+    /**
+     * 收货地址ID
+     */
+    private Long shippingAddressId;
+
+    /**
+     * 采购事由
+     */
+    private String purchaseReason;
+
+    /**
+     * 支付方式
+     */
+    private String payType;
+
+    /**
+     * 发货仓库
+     */
+    private Long warehouseId;
+
+    /**
+     * 预计送达时间
+     */
+    private Date expectedDeliveryTime;
+
+    /**
+     * 商品总数量
+     */
+    private Long productQuantity;
+
+    /**
+     * 运费(元)
+     */
+    private BigDecimal shippingFee;
+
+    /**
+     * 订单总金额(元)
+     */
+    private BigDecimal totalAmount;
+
+    /**
+     * 应付金额(元)
+     */
+    private BigDecimal payableAmount;
+
+    /**
+     * 支付状态
+     */
+    private String paymentStatus;
+
+    /**
+     * 订单来源
+     */
+    private String orderSource;
+
+    /**
+     * 订单状态
+     */
+    private String orderStatus;
+
+    /**
+     * 下单时间
+     */
+    private Date orderTime;
+
+    /**
+     * 确认时间
+     */
+    private Date confirmTime;
+
+    /**
+     * 发货时间
+     */
+    private Date shippingTime;
+
+    /**
+     * 收货时间
+     */
+    private Date receivingTime;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 审核状态(0 待审核 1已通过 2已驳回)
+     */
+    private String checkStatus;
+
+    /**
+     * 是否需要审核(0 需要审核 1不需要)
+     */
+    private String isNeedCheck;
+
+    /**
+     * 费用类型
+     */
+    private String expenseType;
+
+    /**
+     * 订单商品列表
+     */
+    private List<OrderProductDto> orderProductList;
+
+    /**
+     * 订单商品DTO
+     */
+    @Data
+    public static class OrderProductDto implements Serializable {
+        @Serial
+        private static final long serialVersionUID = 1L;
+
+        /**
+         * 主键ID
+         */
+        private Long id;
+
+        /**
+         * 订单ID
+         */
+        private Long orderId;
+
+        /**
+         * 订单编号
+         */
+        private String orderNo;
+
+        /**
+         * 商品ID
+         */
+        private Long productId;
+
+        /**
+         * 商品编码
+         */
+        private String productNo;
+
+        /**
+         * 商品名称
+         */
+        private String productName;
+
+        /**
+         * 商品单位ID
+         */
+        private Long productUnitId;
+
+        /**
+         * 商品单位
+         */
+        private String productUnit;
+
+        /**
+         * 商品图片
+         */
+        private String productImage;
+
+        /**
+         * 下单价格
+         */
+        private BigDecimal orderPrice;
+
+        /**
+         * 市场价格
+         */
+        private BigDecimal marketPrice;
+
+        /**
+         * 税率
+         */
+        private BigDecimal taxRate;
+
+        /**
+         * 分类名称
+         */
+        private String categoryName;
+
+        /**
+         * 采购价
+         */
+        private BigDecimal purchasingPrice;
+
+        /**
+         * 最小起订量
+         */
+        private Long minOrderQuantity;
+
+        /**
+         * 最低售价
+         */
+        private BigDecimal minSellingPrice;
+
+        /**
+         * 下单数量
+         */
+        private Long orderQuantity;
+
+        /**
+         * 已发货数量
+         */
+        private Long deliveredQuantity;
+
+        /**
+         * 未发货数量
+         */
+        private Long undeliveredQuantity;
+
+        /**
+         * 小计
+         */
+        private BigDecimal subtotal;
+    }
+
+    private boolean flag;
+
+    private String message;
+}

+ 24 - 2
ruoyi-api/ruoyi-api-product/src/main/java/org/dromara/product/api/RemoteCategoryService.java

@@ -1,5 +1,8 @@
 package org.dromara.product.api;
 
+import org.dromara.product.api.domain.CategoryDto;
+
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -9,7 +12,26 @@ import java.util.Set;
  */
 public interface RemoteCategoryService {
 
-    Map<Long,Map<String,String>> getallCategoryNameById(Map<Long,Long> categoryMap);
+    Map<Long, Map<String, String>> getallCategoryNameById(Map<Long, Long> categoryMap);
+
+    Map<Long, String> getCategoryNamebyIds(Set<Long> ids);
+
+    Long insertCategory(List<CategoryDto> categoryDtos);
+
+    /**
+     * 根据分类ID查询分类树结构
+     *
+     * @param categoryId 分类ID
+     * @return 分类树结构列表(包含子分类)
+     */
+    List<CategoryDto> getCategoryTreeById(Long categoryId);
 
-    Map<Long,String> getCategoryNamebyIds(Set<Long> ids);
+    /**
+     * 智能更新分类树(增量更新,保留原有ID)
+     *
+     * @param rootCategoryId 根分类ID
+     * @param newCategoryTree 新的分类树数据
+     * @return 是否更新成功
+     */
+    Boolean updateCategoryTree(Long rootCategoryId, List<CategoryDto> newCategoryTree);
 }

+ 2 - 2
ruoyi-api/ruoyi-api-product/src/main/java/org/dromara/product/api/RemoteProductService.java

@@ -100,10 +100,10 @@ public interface RemoteProductService {
 
     /**
      * 给订单商品赋值
-     * @param productIds
+     * @param productNos
      * @return
      */
-    List<OrderProductDto> buildOrderProduct(List<Long> productIds);
+    List<OrderProductDto> buildOrderProduct(List<String> productNos);
 
     /**
      * 库存锁定

+ 141 - 0
ruoyi-api/ruoyi-api-product/src/main/java/org/dromara/product/api/domain/CategoryDto.java

@@ -0,0 +1,141 @@
+package org.dromara.product.api.domain;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+public class CategoryDto implements Serializable {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 分类编号
+     */
+    private String categoryNo;
+
+    /**
+     * 分类名称
+     */
+    private String categoryName;
+
+    /**
+     * 父级分类ID
+     */
+    private Long parentId;
+
+    /**
+     * 祖籍列表
+     */
+    private String ancestors;
+
+    /**
+     * 分类层级(1=一级,2=二级, 3三级)
+     */
+    private Long classLevel;
+
+    /**
+     * 是否显示(1=显示,0=隐藏)
+     */
+    private Long isShow;
+
+    /**
+     * 是否在GPS中显示
+     */
+    private Long isShowGps;
+
+    /**
+     * 折扣率(可能为JSON或文本)
+     */
+    private BigDecimal discountRate;
+
+    /**
+     * 拼音码(用于快速检索)
+     */
+    private String pyCode;
+
+    /**
+     * 分类描述
+     */
+    private String classDescription;
+
+    /**
+     * 数据来源
+     */
+    private String dataSource;
+
+    /**
+     * 自定义标签1
+     */
+    private String oneLable1;
+
+    /**
+     * 自定义标签2
+     */
+    private String oneLable2;
+
+    /**
+     * 自定义链接1
+     */
+    private String oneLink1;
+
+    /**
+     * 自定义链接2
+     */
+    private String oneLink2;
+
+    /**
+     * 排序值,默认为0
+     */
+    private Long sort;
+
+    /**
+     * 颜色(如CSS颜色值)
+     */
+    private String color;
+
+    /**
+     * 采购编号
+     */
+    private String purchaseNo;
+
+    /**
+     * 采购名称
+     */
+    private String purchaseName;
+
+    /**
+     * 采购负责人编号
+     */
+    private String purchaseManagerNo;
+
+    /**
+     * 采购负责人姓名
+     */
+    private String purchaseManagerName;
+
+    /**
+     * 所属平台 (0=平台,1=工业品,2=福利,3=企业购,4=大客户)
+     */
+    private Long platform;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 审核人
+     */
+    private Long reviewerId;
+
+    /**
+     * 子分类列表(用于树形结构)
+     */
+    private List<CategoryDto> children;
+}

+ 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);
 }

+ 2 - 0
ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteComStaffService.java

@@ -22,4 +22,6 @@ public interface RemoteComStaffService {
 
     RemoteComStaffVo selectStaffByStaffName(String staffName);
 
+    RemoteComStaffVo selectStaffByUserId(Long userId);
+
 }

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

@@ -79,4 +79,11 @@ public interface RemoteDeptService {
 
     Map<Long, String> selectDeptNameByIds(Set<Long> ids);
 
+    /**
+     * 根据部门ID查询所有子部门(正常状态)
+     *
+     * @param deptId 部门ID
+     */
+    List<Long> selectDeptIdsByDeptId(Long deptId);
+
 }

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

@@ -44,6 +44,13 @@ public interface RemoteUserService {
      */
     LoginUser getUserInfoByPhonenumber(String phonenumber, String tenantId) throws UserException;
 
+    /**
+     * 通过手机号查询用户信息
+     *
+     * @param phonenumber 手机号
+     * @return 结果
+     */
+    LoginUser getUserInfoByPhonenumber(String phonenumber) throws UserException;
     /**
      * 通过邮箱查询用户信息
      *

+ 51 - 0
ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteUserWechatService.java

@@ -0,0 +1,51 @@
+package org.dromara.system.api;
+
+import org.dromara.system.api.domain.vo.RemoteUserWechatVo;
+
+/**
+ * 小程序用户关联服务
+ *
+ * @author LionLi
+ */
+public interface RemoteUserWechatService {
+
+    /**
+     * 通过openid查询小程序用户信息
+     *
+     * @param openId 微信openid
+     * @return 结果
+     */
+    RemoteUserWechatVo getUserInfoByOpenid(String openId);
+
+    /**
+     * 通过手机号查询小程序用户信息
+     *
+     * @param phoneNumber 手机号
+     * @return 结果
+     */
+    RemoteUserWechatVo getUserInfoByPhoneNumber(String phoneNumber);
+
+    /**
+     * 新增小程序用户关联
+     *
+     * @param userWechat 小程序用户关联信息
+     * @return 结果
+     */
+    Boolean insertUserWechat(RemoteUserWechatVo userWechat);
+
+    /**
+     * 修改小程序用户关联
+     *
+     * @param userWechat 小程序用户关联信息
+     * @return 结果
+     */
+    Boolean updateUserWechat(RemoteUserWechatVo userWechat);
+
+    /**
+     * 通过ID查询小程序用户信息
+     *
+     * @param id 主键
+     * @return 结果
+     */
+    RemoteUserWechatVo getUserInfoById(Long id);
+}

+ 4 - 0
ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/bo/RemoteUserBo.java

@@ -132,6 +132,10 @@ public class RemoteUserBo implements Serializable {
 
     private String delFlag;
 
+    private String source;
+
+    private String openId;
+
     public RemoteUserBo(Long userId) {
         this.userId = userId;
     }

+ 2 - 0
ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/vo/RemoteComStaffVo.java

@@ -27,6 +27,8 @@ public class RemoteComStaffVo implements Serializable {
      */
     private String staffCode;
 
+    private Long userId;
+
     /**
      * 姓名
      */

+ 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;
+}

+ 95 - 0
ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/vo/RemoteUserWechatVo.java

@@ -0,0 +1,95 @@
+package org.dromara.system.api.domain.vo;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 小程序用户关联视图对象
+ *
+ * @author LionLi
+ */
+@Data
+@NoArgsConstructor
+public class RemoteUserWechatVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 用户ID
+     */
+    private Long userId;
+
+    /**
+     * 微信小程序唯一标识
+     */
+    private String openId;
+    /**
+    * 公众号唯一标识
+    * */
+    private String gzhOpenId;
+
+    /**
+     * 微信开放平台唯一标识
+     */
+    private String unionId;
+
+    /**
+     * 微信昵称
+     */
+    private String nickname;
+
+    /**
+     * 头像URL
+     */
+    private String avatarUrl;
+
+    /**
+     * 性别:  0. 男; 1. 女;2. 未知;
+     */
+    private Long gender;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 电话号码
+     */
+    private String phoneNumber;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 微信API临时访问令牌
+     */
+    private String accessToken;
+
+    /**
+     * access_token的有效期(秒)
+     */
+    private Long expireIn;
+
+    /**
+     * AppID
+     */
+    private String appId;
+}

+ 3 - 3
ruoyi-auth/src/main/java/org/dromara/auth/controller/Auth2Controller.java

@@ -49,9 +49,9 @@ public class Auth2Controller {
     private final static String ZHONGCHE_DEVELOPER_PUBLIC_KEY = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE9ITEKJdH9o1K9AeQYY7zNMo/q5/cdce+9jbawURTPEpBKAx4VkB+lRkb5e5YL+Be4pPM464rPvLyfqGNJvL6uQ==";
 
     //同济电商私钥
-    private final static String TONGJI_DEVELOPER_PRIVATE_KEY = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgQu0H97EPqkgz1YS5LkzZNmkG3mS5Er8rJ2LSoJtuOlGgCgYIKoEcz1UBgi2hRANCAARP6NYwTHpW2QTL8A2f2hpgunEpDVkJBhErBQPLqNS/Si5Q+9I9wUpCYdk1EvB5Hw6yzkE4bYk5IZM1j+/SnNFn";
+    private final static String TONGJI_DEVELOPER_PRIVATE_KEY = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgkRuHZ2UkqHOv+TpwYFkccmIJpE4Tje63UFV++O1AxTKgCgYIKoEcz1UBgi2hRANCAASL+QeNJvix0bhOunIyO/s1as0aGkQ6am3rf/4eb17UOnJzVo6xvKOFPRA/5rG0rFggU5hYwe70ElN/xWT/Cy2g";
     //同济企采公钥
-    private final static String TONGJI_DEVELOPER_PUBLIC_KEY = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgQu0H97EPqkgz1YS5LkzZNmkG3mS5Er8rJ2LSoJtuOlGgCgYIKoEcz1UBgi2hRANCAARP6NYwTHpW2QTL8A2f2hpgunEpDVkJBhErBQPLqNS/Si5Q+9I9wUpCYdk1EvB5Hw6yzkE4bYk5IZM1j+/SnNFn";
+    private final static String TONGJI_DEVELOPER_PUBLIC_KEY = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAECeORp+9YlmSobsiULe0D1obWOxjTG4aAeufqhtXEwy9BhpbLKQjjifXHKcb92ozx0VBtt5Yt9E7U06+hc0x/tQ==";
     /**
      * 获取 Access Token
      * @param username 用户名
@@ -216,7 +216,7 @@ public class Auth2Controller {
     }
 
     /**
-     * 获取 Access Token  ZHONGChe
+     * 获取 Access Token  TONGJI
      * 注册地址:武汉市硚口区古田二路长丰村长丰乡15栋1号5室
      * 供应商名称:优易达(武汉)有限公司
      * 管理员手机号:18062697722

+ 278 - 59
ruoyi-auth/src/main/java/org/dromara/auth/controller/MiniTokenController.java

@@ -5,7 +5,9 @@ import cn.dev33.satoken.stp.StpUtil;
 import cn.dev33.satoken.stp.parameter.SaLoginParameter;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import jakarta.validation.constraints.NotNull;
@@ -13,17 +15,24 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.apache.seata.spring.annotation.GlobalTransactional;
-import org.dromara.auth.domain.SysUserWechat;
 import org.dromara.auth.domain.bo.SysUserWechatBo;
-import org.dromara.auth.domain.vo.SysUserWechatVo;
-import org.dromara.auth.service.MiniAuthService;
+import org.dromara.auth.util.HttpClientUtil;
 import org.dromara.common.core.domain.R;
+import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.utils.ServletUtils;
+import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.common.tenant.helper.TenantHelper;
+import org.dromara.customer.api.RemoteCustomerService;
 import org.dromara.resource.api.RemoteFileService;
 import org.dromara.resource.api.domain.RemoteFile;
+import org.dromara.system.api.RemoteClientService;
+import org.dromara.system.api.RemoteUserService;
+import org.dromara.system.api.RemoteUserWechatService;
+import org.dromara.system.api.domain.vo.RemoteClientVo;
+import org.dromara.system.api.domain.vo.RemoteUserWechatVo;
 import org.dromara.system.api.model.LoginUser;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
@@ -33,6 +42,7 @@ import org.springframework.web.bind.annotation.*;
 import org.springframework.web.client.RestTemplate;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 
@@ -47,11 +57,23 @@ import java.util.Objects;
 @RestController
 @RequestMapping("/wx")
 public class MiniTokenController {
+    public static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";
 
-    private final MiniAuthService miniAuthService;
     @DubboReference
     private RemoteFileService remoteFileService;
 
+    @DubboReference
+    private RemoteUserService remoteUserService;
+
+    @DubboReference
+    private final RemoteClientService remoteClientService;
+
+    @DubboReference
+    private RemoteUserWechatService remoteUserWechatService;
+
+    @DubboReference
+    private RemoteCustomerService remoteCustomerService;
+
     @Value("${tr.wechat.secret}")
     private String appSecret;
 
@@ -63,58 +85,210 @@ public class MiniTokenController {
      * */
     @SaIgnore
     @PostMapping("/login")
-    public R<SysUserWechatVo> login(@RequestBody SysUserWechatBo wechatBo) {
+    public R<RemoteUserWechatVo> login(@RequestBody SysUserWechatBo wechatBo) {
         log.info("微信用户登录:{}", wechatBo.getCode());
 
         // 从请求头中获取 tenantId
-        String tenantId = ServletUtils.getHeader(Objects.requireNonNull(ServletUtils.getRequest()), "tenantId");
-        log.info("从请求头获取到 tenantId: {}", tenantId);
+//        String tenantId = ServletUtils.getHeader(Objects.requireNonNull(ServletUtils.getRequest()), "tenantId");
+//        log.info("从请求头获取到 tenantId: {}", tenantId);
+
+        String tenantId = "000000";
 
         // 在动态租户上下文中执行登录逻辑
         return TenantHelper.dynamic(tenantId, () -> {
-            SysUserWechat wechat = miniAuthService.wxLogin(wechatBo);
-            LoginUser loginUser = new LoginUser();
-            loginUser.setUserId(wechat.getUserId());
-            loginUser.setNickname(wechat.getNickname());
-            loginUser.setUserType("app_user");
-            loginUser.setOpenid(wechat.getOpenId());
-            loginUser.setTenantId(tenantId); // 设置租户ID到登录用户
-
-            // 配置登录参数
-            SaLoginParameter model = new SaLoginParameter();
-            model.setDeviceType("xcx"); // 小程序设备类型
-            model.setTimeout(30 * 24 * 60 * 60); // 30天过期时间
-            model.setActiveTimeout(7 * 24 * 60 * 60); // 7天活跃超时
-            model.setExtra(LoginHelper.CLIENT_KEY, "miniprogram_client_id_2025"); // 使用系统认可的APP端客户端ID
-
-            //生成token
-            LoginHelper.login(loginUser, model);
-            // 获取token信息
-            String accessToken = StpUtil.getTokenValue();
-            Long expireIn = StpUtil.getTokenTimeout();
-            SysUserWechatVo wechatVo = BeanUtil.copyProperties(wechat, SysUserWechatVo.class);
-            wechatVo.setOpenId(wechat.getOpenId());
-            wechatVo.setAccessToken(accessToken);
-            wechatVo.setExpireIn(expireIn);
-            return R.ok(wechatVo);
+            try {
+                RemoteClientVo client = remoteClientService.queryByClientId(wechatBo.getClientId());
+                if (client == null) {
+                    return R.fail("客户端不存在");
+                }
+                // 1. 调用 Service 层逻辑获取 openid
+                String openid = getOpenid(wechatBo.getCode());
+                if (openid == null) {
+                    return R.fail("登录code无效,登录失败");
+                }
+
+                // 2. 通过 openid 查询用户
+                RemoteUserWechatVo wechat = remoteUserWechatService.getUserInfoByOpenid(openid);
+
+                // 3. 如果用户不存在,返回引导注册信息
+                if (wechat == null) {
+                    log.info("检测到新用户 (OpenID: {}), 引导注册", openid);
+                    RemoteUserWechatVo wechatVo = new RemoteUserWechatVo();
+                    wechatVo.setOpenId(openid);
+                    wechatVo.setAppId(appId);
+                    return R.warn("用户未注册,请前往注册", wechatVo);
+                }
+
+                Long customerId = null;
+                if(ObjectUtil.isNotEmpty(wechat.getUserId())){
+                    customerId = remoteCustomerService.selectCustomerIdByUserId(wechat.getUserId());
+                    if (Objects.isNull(customerId)) {
+                        return R.warn("该手机号未注册客户,请先注册");
+                    }
+                }
+
+
+                // --- 登录成功逻辑 (用户已存在) ---
+                LoginUser loginUser = new LoginUser();
+                loginUser.setUserId(wechat.getUserId());
+                loginUser.setNickname(wechat.getNickname());
+                loginUser.setUserType("app_user");
+                loginUser.setOpenid(wechat.getOpenId());
+                loginUser.setTenantId(tenantId);
+                loginUser.setClientKey(client.getClientKey());
+                loginUser.setDeviceType(client.getDeviceType());
+                loginUser.setCustomerId(customerId);
+
+                SaLoginParameter model = new SaLoginParameter();
+                model.setTimeout(client.getTimeout());
+                model.setActiveTimeout(client.getActiveTimeout());
+                model.setExtra(LoginHelper.CLIENT_KEY, client.getClientId());
+
+                LoginHelper.login(loginUser, model);
+                String accessToken = StpUtil.getTokenValue();
+                Long expireIn = StpUtil.getTokenTimeout();
+
+                wechat.setAccessToken(accessToken);
+                wechat.setExpireIn(expireIn);
+
+                return R.ok(wechat);
+
+            } catch (Exception e) {
+                // 其他异常正常抛出
+                log.error("登录异常", e);
+                return R.fail("登录失败: " + e.getMessage());
+            }
         });
     }
 
+    /*
+     * 小程序登录手机号
+     * */
+    @SaIgnore
+    @PostMapping("/loginByPhone")
+    public R<RemoteUserWechatVo> loginByPhone(@RequestBody Map<String, String> data) {
+        try {
+            String code = data.get("code");
+            String openId = data.get("openId");
+            String clientId = data.get("clientId");
+            log.info("手机号快捷登录,获取临时code: {}", code);
+
+            // 获取 tenantId
+//            String tenantId = ServletUtils.getHeader(Objects.requireNonNull(ServletUtils.getRequest()), "tenantId");
+
+            String tenantId = "000000";
+            RemoteClientVo client = remoteClientService.queryByClientId(clientId);
+            if (client == null) {
+                return R.fail("客户端不存在");
+            }
+            return TenantHelper.dynamic(tenantId, () -> {
+                // 1. 通过 code 换取手机号
+                String phoneNumber = getPhoneNumberByCode(code);
+                if (phoneNumber == null) {
+                    return R.fail("获取手机号失败");
+                }
+                log.info("获取到手机号: {}", phoneNumber);
+                RemoteUserWechatVo userVo = null;
+                LoginUser userInfoByPhonenumber = remoteUserService.getUserInfoByPhonenumber(phoneNumber);
+                if (ObjectUtil.isEmpty(userInfoByPhonenumber)) {
+                    return R.warn("该手机号未注册,请先注册");
+                }
+                if (ObjectUtil.isNotEmpty(userInfoByPhonenumber)) {
+                    RemoteUserWechatVo sysUserWechat = remoteUserWechatService.getUserInfoByPhoneNumber(phoneNumber);
+                    if (ObjectUtil.isEmpty(sysUserWechat)) {
+                        // 创建新的微信关联记录
+                        RemoteUserWechatVo newUserWechat = new RemoteUserWechatVo();
+                        newUserWechat.setOpenId(openId);
+                        newUserWechat.setStatus("0");
+
+                        // --- 核心修复:处理昵称 ---
+                        // 静默登录没传昵称,生成默认昵称
+                        String nickName = "用户_" + openId.substring(openId.length() - 8);
+                        newUserWechat.setUserId(userInfoByPhonenumber.getUserId());
+                        newUserWechat.setPhoneNumber(phoneNumber);
+                        // 保存微信关联表
+                        newUserWechat.setNickname(nickName); // 保存默认昵称
+                        // --- 处理头像 ---
+                        newUserWechat.setAvatarUrl("/default/avatar.png"); // 默认头像
+
+                        Boolean insert = remoteUserWechatService.insertUserWechat(newUserWechat);
+                        if (insert) {
+                            userVo = newUserWechat;
+                        }else{
+                            return R.fail("保存微信关联失败");
+                        }
+                    } else {
+                        userVo = sysUserWechat;
+                    }
+                }
+
+                // 2. 根据手机号查询用户
+                //  user = miniAuthService.queryByPhoneNumber(phoneNumber);
+
+                // 如果业务逻辑是“查不到就注册”,请取消下面的注释
+                // if (user == null) {
+                //     user = miniAuthService.registerByPhoneNumber(phoneNumber);
+                // }
+                Long customerId = null;
+                if (ObjectUtil.isNotEmpty(userVo.getUserId())) {
+                    customerId = remoteCustomerService.selectCustomerIdByUserId(userVo.getUserId());
+                    if (Objects.isNull(customerId)) {
+                        return R.warn("该手机号未注册客户,请先注册");
+                    }
+                }
+
+                // 3. 登录逻辑(与 /login 接口保持一致)
+                LoginUser loginUser = new LoginUser();
+                loginUser.setUserId(userVo.getUserId());
+                loginUser.setNickname(userVo.getNickname());
+                loginUser.setUserType("app_user");
+                loginUser.setOpenid(userVo.getOpenId());
+                loginUser.setTenantId(tenantId);
+                loginUser.setClientKey(client.getClientKey());
+                loginUser.setDeviceType(client.getDeviceType());
+                loginUser.setCustomerId(customerId);
+
+
+                SaLoginParameter model = new SaLoginParameter();
+                model.setDeviceType(client.getDeviceType());
+                model.setTimeout(client.getTimeout());
+                model.setActiveTimeout(client.getActiveTimeout());
+                model.setExtra(LoginHelper.CLIENT_KEY, client.getClientId());
+                LoginHelper.login(loginUser, model);
+                String accessToken = StpUtil.getTokenValue();
+                Long expireIn = StpUtil.getTokenTimeout();
+
+                userVo.setAccessToken(accessToken);
+                userVo.setExpireIn(expireIn);
+
+                return R.ok(userVo);
+            });
+        } catch (Exception e) {
+            log.error("手机号登录失败", e);
+            return R.fail("登录失败");
+        }
+    }
+
 
     @SaIgnore
     @PostMapping("/bindPhone")
     @GlobalTransactional
-    public R<SysUserWechatVo> getUserPhone(@RequestBody Map<String, Object> phoneData) {
+    public R<RemoteUserWechatVo> getUserPhone(@RequestBody Map<String, Object> phoneData) {
         try {
             String code = (String) phoneData.get("code");
             Long userId = Long.valueOf(phoneData.get("userId").toString());
+            String clientId = (String) phoneData.get("clientId");
 
             log.info("获取手机号请求 - userId: {}, code: {}", userId, code);
 
             // 从请求头中获取 tenantId
-            String tenantId = ServletUtils.getHeader(Objects.requireNonNull(ServletUtils.getRequest()), "tenantId");
-            log.info("从请求头获取到 tenantId: {}", tenantId);
-
+//            String tenantId = ServletUtils.getHeader(Objects.requireNonNull(ServletUtils.getRequest()), "tenantId");
+//            log.info("从请求头获取到 tenantId: {}", tenantId);
+            String tenantId = "000000";
+            RemoteClientVo client = remoteClientService.queryByClientId(clientId);
+            if (client == null) {
+                return R.fail("客户端不存在");
+            }
             // 在动态租户上下文中执行绑定手机号逻辑
             return TenantHelper.dynamic(tenantId, () -> {
                 // 1. 通过手机号专用code直接获取手机号(新方法)
@@ -131,17 +305,21 @@ public class MiniTokenController {
                 log.info("解密得到手机号: {}", phoneNumber.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
 
                 // 3. 更新用户手机号
-                SysUserWechatVo user = miniAuthService.queryById(userId);
+                RemoteUserWechatVo user = remoteUserWechatService.getUserInfoById(userId);
                 if (user == null) {
                     return R.fail("用户不存在");
                 }
+                Long customerId = null;
+                if (ObjectUtil.isNotEmpty(user.getUserId())) {
+                    customerId = remoteCustomerService.selectCustomerIdByUserId(user.getUserId());
+                    if (Objects.isNull(customerId)) {
+                        return R.warn("该手机号未注册客户,请先注册");
+                    }
+                }
 
                 user.setPhoneNumber(phoneNumber);
-                // 创建BO对象进行更新
-                SysUserWechatBo updateBo = new SysUserWechatBo();
-                updateBo.setUserId(userId);
-                updateBo.setPhoneNumber(phoneNumber);
-                miniAuthService.updateByBo(updateBo);
+                // 通过远程调用更新
+                remoteUserWechatService.updateUserWechat(user);
 
                 // 4. 重新生成token并返回用户信息
                 LoginUser loginUser = new LoginUser();
@@ -150,13 +328,15 @@ public class MiniTokenController {
                 loginUser.setUserType("app_user");
                 loginUser.setOpenid(user.getOpenId());
                 loginUser.setTenantId(tenantId); // 设置租户ID到登录用户
-
+                loginUser.setClientKey(client.getClientKey());
+                loginUser.setDeviceType(client.getDeviceType());
+                loginUser.setCustomerId(customerId);
                 // 配置登录参数
                 SaLoginParameter model = new SaLoginParameter();
-                model.setDeviceType("xcx");
-                model.setTimeout(30 * 24 * 60 * 60);
-                model.setActiveTimeout(7 * 24 * 60 * 60);
-                model.setExtra(LoginHelper.CLIENT_KEY, "miniprogram_client_id_2025");
+                model.setDeviceType(client.getDeviceType());
+                model.setTimeout(client.getTimeout());
+                model.setActiveTimeout(client.getActiveTimeout());
+                model.setExtra(LoginHelper.CLIENT_KEY, client.getClientId());
 
                 // 生成token
                 LoginHelper.login(loginUser, model);
@@ -164,7 +344,7 @@ public class MiniTokenController {
                 // 获取token信息
                 String accessToken = StpUtil.getTokenValue();
                 Long expireIn = StpUtil.getTokenTimeout();
-                SysUserWechatVo userVo = new SysUserWechatVo();
+                RemoteUserWechatVo userVo = new RemoteUserWechatVo();
                 userVo.setOpenId(user.getOpenId());
                 userVo.setUserId(user.getUserId());
                 userVo.setStatus(user.getStatus());
@@ -187,9 +367,53 @@ public class MiniTokenController {
     /*
      * 获取手机号
      * */
-    @PostMapping("/getPhoneNumber")
-    public Object getPhoneNumber(@RequestBody Map<String, String> data) {
-        return R.ok(getPhoneNumberByCode(data.get("code")));
+    @PostMapping("/getOpenId")
+    public Object getOpenId(@RequestBody Map<String, String> data) {
+        return R.ok(getOpenid(data.get("code")));
+    }
+
+    private String getOpenid(String code) {
+        // 1. 获取配置(注意:这里获取的是后端配置的 AppID,必须与前端小程序的 AppID 一致)
+
+        // 2. 构建参数
+        Map<String, String> map = new HashMap<>();
+        map.put("appid", appId);
+        map.put("secret", appSecret);
+        map.put("js_code", code);
+        map.put("grant_type", "authorization_code");
+
+        try {
+            // 3. 调用微信接口
+            String json = HttpClientUtil.doGet(WX_LOGIN, map);
+            log.info("微信接口返回: {}", json);
+
+            // 4. 解析结果
+            com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(json);
+
+            // 5. 【关键】先检查有没有错误码
+            if (jsonObject.containsKey("errcode")) {
+                int errCode = jsonObject.getIntValue("errcode");
+                String errMsg = jsonObject.getString("errmsg");
+                log.error("微信登录失败: code={}, error={}", errCode, errMsg);
+                // 抛出异常或返回 null,让上层知道登录失败
+                throw new RuntimeException("微信登录失败: " + errMsg);
+            }
+
+            // 6. 获取 OpenID
+            String openid = jsonObject.getString("openid");
+            if (StringUtils.isEmpty(openid)) {
+                throw new RuntimeException("微信返回openid为空");
+            }
+
+            // 7. (可选) 获取 UnionID - 如果你需要打通公众号/App 账号体系
+            String unionId = jsonObject.getString("unionid");
+
+            return openid;
+
+        } catch (Exception e) {
+            log.error("调用微信接口异常", e);
+            throw new RuntimeException("网络连接微信服务失败", e);
+        }
     }
 
     private String getPhoneNumberByCode(String code) {
@@ -285,14 +509,9 @@ public class MiniTokenController {
      */
     private boolean isPhoneNumberExists(String phoneNumber, Long excludeUserId) {
         try {
-            // 这里需要调用service层方法查询数据库
-            // 由于没有现成的方法,暂时返回false,建议后续完善
-            // WxVsUser existingUser = vsUserService.selectByPhoneNumber(phoneNumber);
-            // return existingUser != null && !existingUser.getUserId().equals(excludeUserId);
-
             log.info("检查手机号是否存在: {} (排除用户: {})",
                 phoneNumber.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"), excludeUserId);
-            SysUserWechat existingUser = miniAuthService.queryByPhoneNumber(phoneNumber);
+            RemoteUserWechatVo existingUser = remoteUserWechatService.getUserInfoByPhoneNumber(phoneNumber);
             return existingUser != null && !existingUser.getUserId().equals(excludeUserId);
         } catch (Exception e) {
             log.error("检查手机号重复时发生异常", e);
@@ -332,8 +551,8 @@ public class MiniTokenController {
     }
 
     @GetMapping("/userInfo/{userId}")
-    public R<SysUserWechatVo> getInfo(@NotNull(message = "主键不能为空")
+    public R<RemoteUserWechatVo> getInfo(@NotNull(message = "主键不能为空")
                                       @PathVariable("userId") Long id) {
-        return R.ok(miniAuthService.queryById(id));
+        return R.ok(remoteUserWechatService.getUserInfoById(id));
     }
 }

+ 2 - 2
ruoyi-auth/src/main/java/org/dromara/auth/controller/TokenController.java

@@ -238,8 +238,8 @@ public class TokenController {
         LoginBody loginBody = JsonUtils.parseObject(body, LoginBody.class);
         ValidatorUtils.validate(loginBody);
         // 授权类型和客户端id
-        String clientId = "e5cd7e4891bf95d1d19206ce24a7b32e";
-        String grantType = "password";
+        String clientId = loginBody.getClientId();
+        String grantType = loginBody.getGrantType();
         RemoteClientVo clientVo = remoteClientService.queryByClientId(clientId);
 
         // 查询不到 client 或 client 内不包含 grantType

+ 6 - 73
ruoyi-auth/src/main/java/org/dromara/auth/domain/bo/SysUserWechatBo.java

@@ -1,99 +1,32 @@
 package org.dromara.auth.domain.bo;
 
-import io.github.linpeilie.annotations.AutoMapper;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
 import lombok.Data;
-import lombok.EqualsAndHashCode;
-import org.dromara.auth.domain.SysUserWechat;
-import org.dromara.common.core.validate.AddGroup;
-import org.dromara.common.core.validate.EditGroup;
-import org.dromara.common.mybatis.core.domain.BaseEntity;
 
 /**
- * 小程序用户关联业务对象 sys_user_wechat
+ * 小程序用户登录业务对象
  *
  * @author LionLi
  */
 @Data
-@EqualsAndHashCode(callSuper = true)
-@AutoMapper(target = SysUserWechat.class, reverseConvertGenerate = false)
-public class SysUserWechatBo extends BaseEntity {
+public class SysUserWechatBo {
 
     /**
-     * 主键ID
+     * 微信登录code
      */
-    private Long id;
-
-    private Long userId;
-
-    /**
-     * 微信小程序唯一标识
-     */
-    private String openId;
+    private String code;
 
     /**
-     * 微信开放平台唯一标识
+     * 客户端id
      */
-    @NotBlank(message = "微信开放平台唯一标识不能为空", groups = {AddGroup.class, EditGroup.class})
-    private String unionId;
+    private String clientId;
 
     /**
      * 微信昵称
      */
-    @NotBlank(message = "微信昵称不能为空", groups = {AddGroup.class, EditGroup.class})
     private String nickname;
 
     /**
      * 头像URL
      */
-    @NotBlank(message = "头像URL不能为空", groups = {AddGroup.class, EditGroup.class})
     private String avatarUrl;
-
-    /**
-     * 性别:  0. 男; 1. 女;2. 未知;
-     */
-    @NotNull(message = "性别(0=未知,1=男,2=女)不能为空", groups = {AddGroup.class, EditGroup.class})
-    private Long gender;
-
-    /**
-     * 微信会话密钥(仅后端临时存储,需加密!)
-     */
-    @NotBlank(message = "微信会话密钥(仅后端临时存储,需加密!)不能为空", groups = {AddGroup.class, EditGroup.class})
-    private String sessionKey;
-
-    /**
-     * 微信API临时访问令牌
-     */
-    @NotBlank(message = "微信API临时访问令牌不能为空", groups = {AddGroup.class, EditGroup.class})
-    private String accessToken;
-
-    /**
-     * access_token的有效期(秒)
-     */
-    @NotNull(message = "access_token的有效期(秒)不能为空", groups = {AddGroup.class, EditGroup.class})
-    private Long expireIn;
-
-    /**
-     * 用于刷新access_token的令牌
-     */
-    @NotBlank(message = "用于刷新access_token的令牌不能为空", groups = {AddGroup.class, EditGroup.class})
-    private String refreshToken;
-
-    /**
-     * 状态(0正常 1停用)
-     */
-    @NotBlank(message = "状态(0正常 1停用)不能为空", groups = {AddGroup.class, EditGroup.class})
-    private String status;
-
-    /**
-     * 备注
-     */
-    @NotBlank(message = "备注不能为空", groups = {AddGroup.class, EditGroup.class})
-    private String remark;
-
-    private String code;
-
-    private String phoneNumber;
-
 }

+ 0 - 17
ruoyi-auth/src/main/java/org/dromara/auth/service/MiniAuthService.java

@@ -1,17 +0,0 @@
-package org.dromara.auth.service;
-
-
-import org.dromara.auth.domain.SysUserWechat;
-import org.dromara.auth.domain.bo.SysUserWechatBo;
-import org.dromara.auth.domain.vo.SysUserWechatVo;
-
-public interface MiniAuthService {
-
-    SysUserWechat wxLogin(SysUserWechatBo wechatBo);
-
-    SysUserWechatVo queryById(Long id);
-
-    Boolean updateByBo(SysUserWechatBo bo);
-
-    SysUserWechat queryByPhoneNumber(String phoneNumber);
-}

+ 0 - 299
ruoyi-auth/src/main/java/org/dromara/auth/service/impl/MiniAuthServiceImpl.java

@@ -1,299 +0,0 @@
-package org.dromara.auth.service.impl;
-
-import cn.hutool.crypto.digest.BCrypt;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.dubbo.config.annotation.DubboReference;
-import org.apache.seata.spring.annotation.GlobalTransactional;
-import org.dromara.auth.domain.SysUserWechat;
-import org.dromara.auth.domain.bo.SysUserWechatBo;
-import org.dromara.auth.domain.vo.SysUserWechatVo;
-import org.dromara.auth.mapper.SysUserWechatMapper;
-import org.dromara.auth.properties.WeChatProperties;
-import org.dromara.auth.service.MiniAuthService;
-import org.dromara.auth.util.HttpClientUtil;
-import org.dromara.common.core.utils.MapstructUtils;
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.oss.core.OssClient;
-import org.dromara.common.oss.entity.UploadResult;
-import org.dromara.common.oss.factory.OssFactory;
-import org.dromara.common.satoken.utils.LoginHelper;
-import org.dromara.common.tenant.helper.TenantHelper;
-import org.dromara.system.api.RemoteUserService;
-import org.dromara.system.api.domain.bo.RemoteUserBo;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.client.RestTemplate;
-
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @program: photo-studio
- * @description:
- * @author: king
- * @create: 2025-12-05 10:43
- * @version: 1.0
- **/
-@Slf4j
-@Service
-public class MiniAuthServiceImpl implements MiniAuthService {
-    public static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";
-
-    @DubboReference
-    private RemoteUserService remoteUserService;
-
-    @Autowired
-    private WeChatProperties weChatProperties;
-    @Autowired
-    private SysUserWechatMapper wechatMapper;
-
-    @Override
-    @GlobalTransactional
-    @Transactional(rollbackFor = Exception.class)
-    public SysUserWechat wxLogin(SysUserWechatBo wechatBo) {
-
-        String openid = getOpenid(wechatBo.getCode());
-
-        // 判断openid是否为空,如果为空表示登录失败,抛出异常
-        if (openid == null) {
-            throw new RuntimeException("登录code为空,登录失败");
-        }
-
-        LambdaQueryWrapper<SysUserWechat> lqw =
-            new LambdaQueryWrapper<SysUserWechat>().eq(SysUserWechat::getOpenId, openid);
-        // 判断当前用户是否为新用户
-        SysUserWechat user = wechatMapper.selectOne(lqw);
-        // 如果是新用户,自动完成注册(写入昵称与头像)
-        if (user == null) {
-            user = new SysUserWechat();
-            user.setOpenId(openid);
-            user.setStatus("0");
-
-            // 从当前租户上下文中获取 tenantId 并设置
-            String tenantId = TenantHelper.getTenantId();
-            if (StringUtils.isNotBlank(tenantId)) {
-                user.setTenantId(tenantId);
-                log.info("注册新用户,设置 tenantId: {}", tenantId);
-            } else {
-                log.warn("注册新用户时未获取到 tenantId");
-            }
-
-            if (StringUtils.isNotBlank(wechatBo.getNickname())) {
-                user.setNickname(wechatBo.getNickname());
-            }
-            if (StringUtils.isNotBlank(wechatBo.getAvatarUrl())) {
-                String ossUrl = transferImageToOss(wechatBo.getAvatarUrl());
-                if (StringUtils.isNotBlank(ossUrl)) {
-                    if (ossUrl.length() > 200) {
-                        ossUrl = ossUrl.substring(0, 200);
-                    }
-                    user.setAvatarUrl(ossUrl);
-                }
-            }
-            // 创建系统用户
-            RemoteUserBo remoteUserBo = new RemoteUserBo();
-            remoteUserBo.setDeptId(null);
-            remoteUserBo.setUserName(wechatBo.getNickname());
-            remoteUserBo.setNickName(wechatBo.getNickname());
-            remoteUserBo.setPhonenumber(wechatBo.getPhoneNumber());
-            // remoteUserBo.setRoleId(1996816313015631873L);
-            remoteUserBo.setPassword(BCrypt.hashpw("123456"));
-            remoteUserBo.setUserSonType("4"); // 小程序用户
-            remoteUserBo.setTenantId(LoginHelper.getTenantId());
-            remoteUserBo.setStatus("0"); // 正常状态
-            Long userId = remoteUserService.addUser(remoteUserBo);
-            user.setUserId(userId);
-            if (wechatMapper.insert(user) > 0) {
-                log.info("用户注册成功");
-            } else {
-                log.error("用户注册失败");
-            }
-        } else {
-            // 老用户:如本次登录携带了新的昵称或头像,与库中不同则更新
-            boolean needUpdate = false;
-            if (StringUtils.isNotBlank(wechatBo.getNickname()) && !wechatBo.getNickname().equals(user.getNickname())) {
-                user.setNickname(wechatBo.getNickname());
-                log.info("设置昵称完成");
-                needUpdate = true;
-            }
-            if (StringUtils.isNotBlank(wechatBo.getAvatarUrl()) && !wechatBo.getAvatarUrl().equals(user.getAvatarUrl())) {
-                String ossUrl = transferImageToOss(wechatBo.getAvatarUrl());
-                if (StringUtils.isNotBlank(ossUrl)) {
-                    if (ossUrl.length() > 200) {
-                        ossUrl = ossUrl.substring(0, 200);
-                    }
-                    user.setAvatarUrl(ossUrl);
-                    needUpdate = true;
-                }
-            }
-            if (needUpdate) {
-                log.info("设置昵称完成  : {}", user.getNickname());
-                int flag = wechatMapper.updateById(user);
-                if (flag > 0) {
-                    log.info("更新用户信息成功");
-                } else {
-                    log.error("更新用户信息失败");
-                }
-            }
-        }
-
-        // 返回这个用户对象
-        return user;
-    }
-
-
-    private String getOpenid(String code) {
-        log.info("微信接口服务,获得当前微信用户的openid{}", code);
-        // 调用微信接口服务,获得当前微信用户的openid
-        log.info("微信接口服务,获得当前微信用户的Appid{}", weChatProperties.getAppid());
-        log.info("微信接口服务,获得当前微信用户的Secret{}", weChatProperties.getSecret());
-
-        Map<String, String> map = new HashMap<>();
-        map.put("appid", weChatProperties.getAppid());
-        map.put("secret", weChatProperties.getSecret());
-        map.put("js_code", code);
-        map.put("grant_type", "authorization_code");
-        String json = HttpClientUtil.doGet(WX_LOGIN, map);
-        log.info("微信接口服务,获得当前微信用户的json{}", json);
-        JSONObject jsonObject = JSON.parseObject(json);
-        String openid = jsonObject.getString("openid");
-        log.info("微信接口服务,获得当前微信用户的openid{}", openid);
-        return openid;
-    }
-
-
-    /**
-     * 将传入的头像地址转存到OSS并返回最终URL
-     * 支持 http(s) 链接 与 data:image/...;base64 格式
-     */
-    private String transferImageToOss(String source) {
-        if (StringUtils.isBlank(source)) {
-            return null;
-        }
-
-        // 如果已经是OSS地址,直接返回
-        if (source.startsWith("https://oss.") || source.contains(".aliyuncs.com") ||
-            source.contains(".qiniucdn.com") || source.contains("hxsjkj.com")) {
-            log.info("头像已是OSS地址,直接使用: {}", source.substring(0, Math.min(50, source.length())));
-            return source;
-        }
-
-        try {
-            byte[] imageBytes;
-            String suffix = ".jpg";
-            String contentType = "image/jpeg";
-
-            // 1) 处理 Base64 格式
-            if (source.startsWith("data:image/")) {
-                log.info("检测到Base64图片,开始解码并上传");
-                int comma = source.indexOf(',');
-                if (comma > 0) {
-                    String meta = source.substring(5, comma); // image/png;base64
-                    if (meta.contains("/")) {
-                        String ext = meta.substring(meta.indexOf('/') + 1);
-                        if (ext.contains(";")) {
-                            ext = ext.substring(0, ext.indexOf(';'));
-                        }
-                        suffix = "." + ext;
-                        contentType = "image/" + ext;
-                    }
-                    String base64 = source.substring(comma + 1);
-                    imageBytes = Base64.getDecoder().decode(base64);
-                } else {
-                    log.warn("Base64格式不正确");
-                    return null;
-                }
-            }
-            // 2) 处理 HTTP(S) 外部链接(微信头像等)
-            else if (source.startsWith("http://") || source.startsWith("https://")) {
-                log.info("检测到外部图片URL,开始下载: {}", source.substring(0, Math.min(50, source.length())));
-                imageBytes = downloadImageBytes(source);
-                if (imageBytes == null || imageBytes.length == 0) {
-                    log.warn("下载图片失败");
-                    return null;
-                }
-                // 根据URL推断扩展名
-                if (source.contains(".png")) {
-                    suffix = ".png";
-                    contentType = "image/png";
-                } else if (source.contains(".webp")) {
-                    suffix = ".webp";
-                    contentType = "image/webp";
-                } else if (source.contains(".gif")) {
-                    suffix = ".gif";
-                    contentType = "image/gif";
-                }
-            } else {
-                log.warn("不支持的图片格式: {}", source.substring(0, Math.min(50, source.length())));
-                return null;
-            }
-
-            // 3) 上传到 OSS
-            if (imageBytes == null || imageBytes.length == 0) {
-                log.warn("图片字节为空,无法上传");
-                return null;
-            }
-
-            log.info("开始上传图片到OSS,大小: {} bytes", imageBytes.length);
-            OssClient storage = OssFactory.instance();
-            UploadResult uploadResult = storage.uploadSuffix(imageBytes, suffix, contentType);
-            String ossUrl = uploadResult.getUrl();
-            log.info("图片上传成功,OSS URL: {}", ossUrl);
-            return ossUrl;
-
-        } catch (Exception e) {
-            log.error("头像转存OSS失败", e);
-            return null;
-        }
-    }
-
-    /**
-     * 下载网络图片为字节数组
-     */
-    private byte[] downloadImageBytes(String url) {
-        try {
-            RestTemplate restTemplate = new RestTemplate();
-            ResponseEntity<byte[]> response = restTemplate.getForEntity(url, byte[].class);
-            if (response.getStatusCode().is2xxSuccessful()) {
-                return response.getBody();
-            }
-            log.warn("下载图片失败,状态码: {}", response.getStatusCode());
-            return null;
-        } catch (Exception e) {
-            log.error("下载图片异常: {}", url, e);
-            return null;
-        }
-    }
-
-    private void validEntityBeforeSave(SysUserWechat entity) {
-        //TODO 做一些数据校验,如唯一约束
-    }
-
-    @Override
-    public SysUserWechatVo queryById(Long id) {
-        return wechatMapper.selectVoById(id);
-    }
-
-
-    @Override
-    public Boolean updateByBo(SysUserWechatBo bo) {
-        SysUserWechat update = MapstructUtils.convert(bo, SysUserWechat.class);
-        validEntityBeforeSave(update);
-        return wechatMapper.updateById(update) > 0;
-    }
-
-    @Override
-    public SysUserWechat queryByPhoneNumber(String phoneNumber) {
-        LambdaQueryWrapper<SysUserWechat> lqw =
-            new LambdaQueryWrapper<SysUserWechat>().eq(SysUserWechat::getPhoneNumber, phoneNumber);
-        return wechatMapper.selectOne(lqw);
-    }
-
-
-}

+ 1 - 1
ruoyi-auth/src/main/java/org/dromara/auth/service/impl/PasswordAuthStrategy.java

@@ -89,7 +89,7 @@ public class PasswordAuthStrategy implements IAuthStrategy {
         });
         if(ObjectUtil.isNotEmpty(loginUser.getSupplierId())) {
             Long supplierStatus = remoteSupplierInfoService.selectSupplierStatusById(loginUser.getSupplierId());
-            if(!Objects.equals(supplierStatus,1L)){
+            if(supplierStatus !=1L && supplierStatus !=4L){
                 throw new ServiceException("供应商用户未审核通过");
             }
         }

+ 3 - 1
ruoyi-auth/src/main/resources/application.yml

@@ -36,4 +36,6 @@ spring:
 tr:
   wechat:
     appid: wx3d002d66868332a1
-    secret: 269c120e6973c2a15a97f564d2c4c65
+    # 注意:请从微信公众平台获取正确的32位AppSecret
+    # 当前配置的secret长度不足,请访问 https://mp.weixin.qq.com/ 查看或重置
+    secret: 269c120e6973c2a15a97f564d2c4c655

+ 106 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/jiaotou/JiaoTouResult.java

@@ -0,0 +1,106 @@
+package org.dromara.common.core.domain.jiaotou;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.dromara.common.core.constant.HttpStatus;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 响应信息主体
+ *
+ * @author Lion Li
+ */
+@Data
+@NoArgsConstructor
+public class JiaoTouResult<T> implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 成功
+     */
+    public static final String SUCCESS = "200";
+
+    /**
+     * 失败
+     */
+    public static final String FAIL = "500";
+
+    /**
+     * 消息状态码
+     */
+    private String code;
+
+    /**
+     * 是否成功
+     * */
+    private boolean success;
+
+    /**
+     * 消息内容
+     */
+    private String msg;
+
+    /**
+     * 数据对象
+     */
+    private T data;
+
+    public static <T> JiaoTouResult<T> ok() {
+        return restResult(null, SUCCESS, "操作成功");
+    }
+
+    public static <T> JiaoTouResult<T> ok(T data) {
+        return restResult(data, SUCCESS, "操作成功");
+    }
+
+    public static <T> JiaoTouResult<T> ok(String msg) {
+        return restResult(null, SUCCESS, msg);
+    }
+
+    public static <T> JiaoTouResult<T> ok(String msg, T data) {
+        return restResult(data, SUCCESS, msg);
+    }
+
+    public static <T> JiaoTouResult<T> fail() {
+        return restResult(null, FAIL, "操作失败");
+    }
+
+    public static <T> JiaoTouResult<T> fail(String msg) {
+        return restResult(null, FAIL, msg);
+    }
+
+    public static <T> JiaoTouResult<T> fail(T data) {
+        return restResult(data, FAIL, "操作失败");
+    }
+
+    public static <T> JiaoTouResult<T> fail(String msg, T data) {
+        return restResult(data, FAIL, msg);
+    }
+
+    public static <T> JiaoTouResult<T> fail(String code, String msg) {
+        return restResult(null, code, msg);
+    }
+
+
+    private static <T> JiaoTouResult<T> restResult(T data, String code, String msg) {
+        JiaoTouResult<T> r = new JiaoTouResult<>();
+        r.setCode(code);
+        r.setData(data);
+        r.setSuccess(String.valueOf(HttpStatus.SUCCESS).equals(code));
+        r.setMsg(msg);
+        return r;
+    }
+
+    public static <T> Boolean isError(JiaoTouResult<T> ret) {
+        return !isSuccess(ret);
+    }
+
+    public static <T> Boolean isSuccess(JiaoTouResult<T> ret) {
+        return JiaoTouResult.SUCCESS .equals(ret.getCode()) ;
+    }
+
+}

+ 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;
     /**
      * 详细地址
      */

+ 5 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/AssigneeTypeConstants.java

@@ -17,6 +17,11 @@ public enum AssigneeTypeConstants {
      */
     PARTNER("bp", "伙伴商"),
 
+    /**
+     * 营销平台
+     */
+    MKT("mkt" ,"营销平台"),
+
     /**
      * 伙伴商
      */

+ 19 - 1
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/OrderSourceEnum.java

@@ -9,7 +9,23 @@ public enum OrderSourceEnum {
     /**
      * 前台提交
      */
-    BEFORE_ADD("0", "前台提交"),
+    PC_ADD("0", "pc"),
+
+    /**
+     * 小程序提交
+     */
+    MINI_ADD("2", "mini小程序"),
+
+    /**
+     * h5提交
+     */
+    H5_ADD("3", "h5"),
+
+    /**
+     * api提交
+     */
+    Api_ADD("4", "api"),
+
 
     /**
      * 后台新增
@@ -17,6 +33,8 @@ public enum OrderSourceEnum {
     AFTER_ADD("1", "后台新增");
 
 
+
+
     private final String code;
     private final String info;
 

+ 7 - 1
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java

@@ -121,7 +121,12 @@ public class PlatformDataScopeInterceptor implements Interceptor {
         "statement_order",
         "statement_detail",
         "statement_product",
-        "invoice_info"
+        "invoice_info",
+        "sys_user_wechat",
+        "mini_page_set",
+        "maintain_info",
+        "maintenance_server_item",
+        "ep_"
         // 注意:前缀匹配需特殊处理(如 qrtz_),见 isIgnoreTable 方法
     ));
 
@@ -244,6 +249,7 @@ public class PlatformDataScopeInterceptor implements Interceptor {
             || tableName.startsWith("external_")
             || tableName.startsWith("protocol_")
             || tableName.startsWith("ns_diy_")
+            || tableName.startsWith("ep_")
             ;
     }
 

+ 2 - 1
ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/SequenceUtils.java

@@ -188,7 +188,8 @@ public class SequenceUtils {
         // 明确指定 bean name 为 "redisTemplate"
         RedisTemplate<String, Object> redisTemplate = SpringUtils.getBean("redisTemplate", RedisTemplate.class);
 
-        String dateKey = DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN); // 如 "yyyyMMdd"
+        // 使用 yyMMdd 格式而不是 yyyyMMdd,使年份变为2位
+        String dateKey = DateUtil.format(new Date(), "yyMMdd"); // 如 "260511"
         String businessKey = prefix + dateKey;
 
         Long seq = redisTemplate.opsForValue().increment(businessKey);

+ 6 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/pc/PcStatementOrderController.java

@@ -19,6 +19,7 @@ import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.Arrays;
+import java.util.Map;
 
 /**
  * PC端 - 对账单管理
@@ -72,6 +73,11 @@ public class PcStatementOrderController extends BaseController {
         if (bo.getIsPaymentStatus() != null && !bo.getIsPaymentStatus().isEmpty()) {
             wrapper.eq(StatementOrder::getIsPaymentStatus, bo.getIsPaymentStatus());
         }
+        Map<String, Object> params = bo.getParams();
+        if (params != null) {
+            wrapper.between(params.get("beginTime") != null && params.get("endTime") != null,
+                StatementOrder::getStatementDate, params.get("beginTime"), params.get("endTime"));
+        }
 
         // 使用新添加的 PC 端专用方法
         return statementOrderService.queryPageListByWrapper(wrapper, pageQuery);

+ 4 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/impl/StatementInvoiceServiceImpl.java

@@ -140,6 +140,10 @@ public class StatementInvoiceServiceImpl extends ServiceImpl<StatementInvoiceMap
         lqw.eq(bo.getInvoiceTime() != null, StatementInvoice::getInvoiceTime, bo.getInvoiceTime());
         lqw.eq(StringUtils.isNotBlank(bo.getRejectRemark()), StatementInvoice::getRejectRemark, bo.getRejectRemark());
         lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), StatementInvoice::getPlatformCode, bo.getPlatformCode());
+        if (params != null) {
+            lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
+                StatementInvoice::getInvoiceTime, params.get("beginTime"), params.get("endTime"));
+        }
         return lqw;
     }
 

+ 14 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/CustomerInfoController.java

@@ -15,6 +15,7 @@ import org.dromara.common.log.annotation.Log;
 import org.dromara.common.log.enums.BusinessType;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.common.web.core.BaseController;
 import org.dromara.customer.domain.bo.CustomerClaimBo;
 import org.dromara.customer.domain.bo.CustomerInfoBo;
@@ -30,6 +31,7 @@ import org.dromara.system.api.RemoteProductTaxrateService;
 import org.dromara.system.api.*;
 import org.dromara.system.api.domain.vo.RemoteComCompanyVo;
 import org.dromara.system.api.domain.vo.RemoteComCustomerLevelVo;
+import org.dromara.system.api.domain.vo.RemoteComStaffVo;
 import org.springframework.http.MediaType;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -77,6 +79,18 @@ public class CustomerInfoController extends BaseController {
      */
     @GetMapping("/list")
     public TableDataInfo<CustomerInfoVo> list(CustomerInfoBo bo, PageQuery pageQuery) {
+        Long userId = LoginHelper.getLoginUser().getUserId();
+        RemoteComStaffVo remoteComStaffVo = remoteComStaffService.selectStaffByUserId(userId);
+
+        // 设置数据权限过滤:只能查看自己创建的、或者是业务负责人、或者是客服支持的客户
+        if (remoteComStaffVo != null && remoteComStaffVo.getStaffId() != null) {
+            Long staffId = remoteComStaffVo.getStaffId();
+            // 将权限条件传递到查询条件中
+            bo.setCreateBy(userId);
+            bo.setSalesPersonId(staffId);
+            bo.setServiceStaffId(staffId);
+        }
+
         return customerInfoService.queryPageList(bo, pageQuery);
     }
 

+ 11 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierInfoController.java

@@ -276,4 +276,15 @@ public class SupplierInfoController extends BaseController {
 
         return R.ok(partnerfoVoList);
     }
+
+    /**
+     * 将供应商表数据同步到临时表
+     */
+    @Log(title = "供应商信息同步", businessType = BusinessType.OTHER)
+    @PostMapping("/syncToTemporary")
+    public R<Void> syncToTemporary() {
+        return toAjax(supplierInfoService.syncToTemporaryTable());
+    }
+
+
 }

+ 9 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/pc/CustomerRegisterController.java

@@ -46,6 +46,15 @@ public class CustomerRegisterController {
         return R.ok(customerInfoVoList);
     }
 
+    /**
+     * 验证验证码
+     */
+    @PutMapping("/validateCode")
+    public R<Void> verifyCode(@RequestBody CustomerRegisterBo bo) {
+        customerInfoService.verifyCode(bo);
+        return R.ok();
+    }
+
     /**
      * 验证密码与验证码
      */

+ 1 - 2
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/pc/PcComplaintsSuggestionsController.java

@@ -29,10 +29,9 @@ public class PcComplaintsSuggestionsController extends BaseController {
     private final IComplaintsSuggestionsService pcComplaintsSuggestionsService;
 
     @GetMapping("/list")
-    public TableDataInfo<ComplaintsSuggestionsVo> getComplaintsSuggestions(PageQuery pageQuery) {
+    public TableDataInfo<ComplaintsSuggestionsVo> getComplaintsSuggestions(ComplaintsSuggestionsBo bo,PageQuery pageQuery) {
         // 获取当前登录用户的企业ID
         Long customerId = LoginHelper.getLoginUser().getCustomerId();
-        ComplaintsSuggestionsBo bo = new ComplaintsSuggestionsBo();
         bo.setCustomerId(customerId);
         return pcComplaintsSuggestionsService.queryPageList(bo, pageQuery);
     }

+ 5 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/pc/PcContactController.java

@@ -161,4 +161,9 @@ public class PcContactController extends BaseController {
 
         return toAjax(customerContactService.deleteWithValidByIds(List.of(ids), true));
     }
+    /*设置主联系人*/
+    @PutMapping("/changeIsPrimary")
+    public R<Void> changeIsPrimary(@RequestBody CustomerContactBo bo) {
+        return toAjax(customerContactService.changeIsPrimary(bo));
+    }
 }

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác