Просмотр исходного кода

Merge branch 'master' into zl

# Conflicts:
#	ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBaseServiceImpl.java
林小张 3 месяцев назад
Родитель
Сommit
37d821b57b
100 измененных файлов с 6418 добавлено и 271 удалено
  1. 5 4
      pom.xml
  2. 2 1
      ruoyi-api/pom.xml
  3. 5 0
      ruoyi-api/ruoyi-api-bom/pom.xml
  4. 28 0
      ruoyi-api/ruoyi-api-customer/pom.xml
  5. 10 0
      ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/RemoteCustomerService.java
  6. 25 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDeptService.java
  7. 6 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/vo/RemoteDeptVo.java
  8. 27 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/OrderAssignStatus.java
  9. 27 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/OrderSplitStatus.java
  10. 21 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/SysPlatformYesNo.java
  11. 54 6
      ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java
  12. 20 9
      ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/SequenceUtils.java
  13. 213 0
      ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/PlatformHelper.java
  14. 8 0
      ruoyi-modules/ruoyi-customer/pom.xml
  15. 7 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/CustomerDeptController.java
  16. 2 44
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/CustomerDept.java
  17. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/CustomerSalesInfo.java
  18. 1 5
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/CustomerDeptBo.java
  19. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/CustomerSalesInfoBo.java
  20. 27 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerDeptTreeVo.java
  21. 2 9
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerDeptVo.java
  22. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerSalesInfoVo.java
  23. 25 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/dubbo/RemoteCustomerServiceImpl.java
  24. 4 2
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerDeptService.java
  25. 4 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerInfoService.java
  26. 137 70
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerDeptServiceImpl.java
  27. 115 89
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerInfoServiceImpl.java
  28. 0 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerSalesInfoServiceImpl.java
  29. 4 0
      ruoyi-modules/ruoyi-order/pom.xml
  30. 119 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderAssignmentController.java
  31. 18 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderMainController.java
  32. 106 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderReturnController.java
  33. 106 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderReturnItemController.java
  34. 106 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderRevenueDetailController.java
  35. 116 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderRevenueHeaderController.java
  36. 83 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderAssignment.java
  37. 15 8
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderMain.java
  38. 2 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderProduct.java
  39. 13 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderProductAssignRule.java
  40. 220 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderReturn.java
  41. 88 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderReturnItem.java
  42. 103 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderRevenueDetail.java
  43. 113 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderRevenueHeader.java
  44. 78 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderAssignmentBo.java
  45. 20 4
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderMainBo.java
  46. 2 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderProductBo.java
  47. 217 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderReturnBo.java
  48. 80 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderReturnItemBo.java
  49. 95 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderRevenueDetailBo.java
  50. 112 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderRevenueHeaderBo.java
  51. 18 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderSplitAssignBo.java
  52. 91 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderAssignmentVo.java
  53. 27 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderMainVo.java
  54. 5 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderProductVo.java
  55. 100 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderReturnItemVo.java
  56. 267 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderReturnVo.java
  57. 118 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderRevenueDetailVo.java
  58. 138 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderRevenueHeaderVo.java
  59. 15 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderAssignmentMapper.java
  60. 13 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderProductMapper.java
  61. 18 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderReturnItemMapper.java
  62. 15 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderReturnMapper.java
  63. 21 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderRevenueDetailMapper.java
  64. 15 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderRevenueHeaderMapper.java
  65. 73 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderAssignmentService.java
  66. 9 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderMainService.java
  67. 70 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderReturnItemService.java
  68. 70 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderReturnService.java
  69. 70 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderRevenueDetailService.java
  70. 75 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderRevenueHeaderService.java
  71. 373 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderAssignmentServiceImpl.java
  72. 2 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderDeliverServiceImpl.java
  73. 49 8
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderMainServiceImpl.java
  74. 142 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderReturnItemServiceImpl.java
  75. 265 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderReturnServiceImpl.java
  76. 145 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderRevenueDetailServiceImpl.java
  77. 294 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderRevenueHeaderServiceImpl.java
  78. 7 0
      ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderAssignmentMapper.xml
  79. 23 0
      ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderProductMapper.xml
  80. 14 0
      ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderReturnItemMapper.xml
  81. 7 0
      ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderReturnMapper.xml
  82. 14 0
      ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderRevenueDetailMapper.xml
  83. 7 0
      ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderRevenueHeaderMapper.xml
  84. 117 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/ComCurrencyController.java
  85. 118 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/ComRevenueExpenseController.java
  86. 67 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/ComCurrency.java
  87. 77 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/ComRevenueExpense.java
  88. 60 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/ComCurrencyBo.java
  89. 72 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/ComRevenueExpenseBo.java
  90. 76 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/ComCurrencyVo.java
  91. 90 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/ComRevenueExpenseVo.java
  92. 33 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java
  93. 15 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/ComCurrencyMapper.java
  94. 15 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/ComRevenueExpenseMapper.java
  95. 76 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/IComCurrencyService.java
  96. 76 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/IComRevenueExpenseService.java
  97. 4 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDeptService.java
  98. 40 8
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/ComCompanyServiceImpl.java
  99. 158 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/ComCurrencyServiceImpl.java
  100. 160 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/ComRevenueExpenseServiceImpl.java

+ 5 - 4
pom.xml

@@ -91,6 +91,10 @@
                 <nacos.password>nacos</nacos.password>
                 <logstash.address>127.0.0.1:4560</logstash.address>
             </properties>
+            <activation>
+                <!-- 默认环境 -->
+                <activeByDefault>true</activeByDefault>
+            </activation>
         </profile>
         <profile>
             <id>xiaolu</id>
@@ -104,10 +108,7 @@
                 <nacos.password>nacos</nacos.password>
                 <logstash.address>127.0.0.1:4560</logstash.address>
             </properties>
-            <activation>
-                <!-- 默认环境 -->
-                <activeByDefault>true</activeByDefault>
-            </activation>
+
         </profile>
         <profile>
             <id>prod</id>

+ 2 - 1
ruoyi-api/pom.xml

@@ -15,7 +15,8 @@
         <module>ruoyi-api-workflow</module>
         <module>ruoyi-api-product</module>
         <module>ruoyi-api-external</module>
-	    <module>ruoyi-api-order</module>
+        <module>ruoyi-api-order</module>
+        <module>ruoyi-api-customer</module>
     </modules>
 
     <artifactId>ruoyi-api</artifactId>

+ 5 - 0
ruoyi-api/ruoyi-api-bom/pom.xml

@@ -57,6 +57,11 @@
                 <artifactId>ruoyi-api-order</artifactId>
                 <version>${revision}</version>
             </dependency>
+            <dependency>
+                <groupId>org.dromara</groupId>
+                <artifactId>ruoyi-api-customer</artifactId>
+                <version>${revision}</version>
+            </dependency>
 
         </dependencies>
     </dependencyManagement>

+ 28 - 0
ruoyi-api/ruoyi-api-customer/pom.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.dromara</groupId>
+        <artifactId>ruoyi-api</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>ruoyi-api-customer</artifactId>
+
+    <description>
+        ruoyi-api-customer 客户模块接口模块
+    </description>
+
+    <dependencies>
+
+        <!-- RuoYi Common Core-->
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-core</artifactId>
+        </dependency>
+
+
+    </dependencies>
+
+</project>

+ 10 - 0
ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/RemoteCustomerService.java

@@ -0,0 +1,10 @@
+package org.dromara.customer.api;
+
+import java.util.Map;
+import java.util.Set;
+
+public interface RemoteCustomerService {
+
+    /*根据ids查询客户名称*/
+    Map<Long, String> selectCustomerNameByIds(Set<Long> ids);
+}

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

@@ -1,8 +1,11 @@
 package org.dromara.system.api;
 
+import cn.hutool.core.lang.tree.Tree;
 import org.dromara.system.api.domain.vo.RemoteDeptVo;
 
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * 部门服务
@@ -19,6 +22,8 @@ public interface RemoteDeptService {
      */
     String selectDeptNameByIds(String deptIds);
 
+    RemoteDeptVo selectDeptById(Long deptId);
+
     /**
      * 根据部门ID查询部门负责人
      *
@@ -38,4 +43,24 @@ public interface RemoteDeptService {
 
     RemoteDeptVo insertDept(RemoteDeptVo vo);
 
+    List<RemoteDeptVo> selectDeptByIds(List<Long> deptIds);
+
+    /**
+     * 查询部门树结构信息
+     *
+     * @param dept 部门信息
+     * @return 部门树信息集合
+     */
+    List<Tree<Long>> selectDeptTreeList(RemoteDeptVo dept);
+
+    /**
+     * 构建前端所需要下拉树结构
+     *
+     * @param depts 部门列表
+     * @return 下拉树结构列表
+     */
+    List<Tree<Long>> buildDeptTreeSelect(List<RemoteDeptVo> depts);
+
+    Map<Long, String> selectDeptNameByIds(Set<Long> ids);
+
 }

+ 6 - 0
ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/vo/RemoteDeptVo.java

@@ -36,6 +36,12 @@ public class RemoteDeptVo implements Serializable {
 
     private Long customerId;
 
+    private String status;
+
+    private Integer orderNum;
+
+    private Long companyId;
+
 
     private String platformCode;
 

+ 27 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/OrderAssignStatus.java

@@ -0,0 +1,27 @@
+package org.dromara.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 用户状态
+ *
+ * @author ruoyi
+ */
+@Getter
+@AllArgsConstructor
+public enum OrderAssignStatus {
+    /**
+     * 待分配
+     */
+    WAIT_ASSIGN("0", "待分配"),
+    /**
+     * 已分配
+     */
+    ASSIGNED("1", "已分配");
+
+
+    private final String code;
+    private final String info;
+
+}

+ 27 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/OrderSplitStatus.java

@@ -0,0 +1,27 @@
+package org.dromara.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 用户状态
+ *
+ * @author ruoyi
+ */
+@Getter
+@AllArgsConstructor
+public enum OrderSplitStatus {
+    /**
+     * 未拆单
+     */
+    WAIT_SPLIT("0", "未拆单"),
+    /**
+     * 已拆单
+     */
+    SPLITED("1", "已拆单");
+
+
+    private final String code;
+    private final String info;
+
+}

+ 21 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/SysPlatformYesNo.java

@@ -0,0 +1,21 @@
+package org.dromara.common.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum SysPlatformYesNo {
+
+    /**
+     * 是
+     */
+    YES("0", "是"),
+    /**
+     * 否
+     */
+    NO("1", "否");
+
+    private final String code;
+    private final String info;
+}

+ 54 - 6
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java

@@ -1,5 +1,6 @@
 package org.dromara.common.mybatis.interceptor;
 
+import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
 import lombok.extern.slf4j.Slf4j;
 import net.sf.jsqlparser.expression.Expression;
 import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
@@ -25,6 +26,7 @@ import java.util.Set;
 /**
  * 平台数据隔离拦截器
  * 自动在 SELECT 语句中注入 platform_code = '当前平台' 条件
+ * 支持通过 PlatformHelper.ignore() 临时忽略平台隔离
  *
  * @author YourName
  */
@@ -41,6 +43,7 @@ public class PlatformDataScopeInterceptor implements Interceptor {
         "sys_post",
         "sys_user_post",
         "sys_config",
+        "sys_dept",
         "sys_dict",
         "sys_dict_type",
         "sys_dict_data",
@@ -57,6 +60,7 @@ public class PlatformDataScopeInterceptor implements Interceptor {
         "customer_info_tag",
         "invoice_type",
         "customer_info",
+        "customer_dept",
         "com_bank",
         "settlement_level",
         "settlement_method",
@@ -67,14 +71,12 @@ public class PlatformDataScopeInterceptor implements Interceptor {
         "order_pay_set",
         "customer_shipping_address",
         "customer_sales_info",
+        "order_main",
+        "order_product",
         "com_",
         "product_"
-
-
-        // 注意:前缀匹配需特殊处理(如 qrtz_),见 isIgnoreTable 方法
     ));
 
-
     @Override
     public Object intercept(Invocation invocation) throws Throwable {
         StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
@@ -86,11 +88,16 @@ public class PlatformDataScopeInterceptor implements Interceptor {
             return invocation.proceed();
         }
 
+        // 新增:检查是否应忽略平台数据隔离(由 PlatformHelper.ignore() 触发)
+        if (isIgnorePlatform()) {
+            return invocation.proceed();
+        }
+
         String platform = PlatformContext.getPlatform();
 
         // 总控平台:直接放行,不注入任何条件
         if (SysPlatformCode.MAIN.getCode().equals(platform)) {
-            return invocation.proceed(); // ← 核心:提前返回
+            return invocation.proceed();
         }
 
         // 原有逻辑:仅对非 main 平台生效
@@ -178,10 +185,41 @@ public class PlatformDataScopeInterceptor implements Interceptor {
             return true;
         }
 
-        // 前缀匹配(例如以 "qrtz_" 开头的表)
+        // 前缀匹配
         return tableName.startsWith("qrtz_") || tableName.startsWith("product_") || tableName.startsWith("com_");
     }
 
+    /**
+     * 判断当前是否应忽略平台数据隔离
+     * 复用 MyBatis-Plus 的 IgnoreStrategy.tenantLine 作为开关
+     */
+    private boolean isIgnorePlatform() {
+        try {
+            Object ignoreStrategyLocal = ReflectUtil.getStaticFieldValue(
+                InterceptorIgnoreHelper.class, "IGNORE_STRATEGY_LOCAL"
+            );
+            if (ignoreStrategyLocal instanceof ThreadLocal) {
+                Object strategy = ((ThreadLocal<?>) ignoreStrategyLocal).get();
+                if (strategy != null) {
+                    try {
+                        Field tenantLineField = strategy.getClass().getDeclaredField("tenantLine");
+                        tenantLineField.setAccessible(true);
+                        Boolean tenantLine = (Boolean) tenantLineField.get(strategy);
+                        if (Boolean.TRUE.equals(tenantLine)) {
+                            log.debug("PlatformDataScopeInterceptor: ignored due to tenantLine=true");
+                            return true;
+                        }
+                    } catch (NoSuchFieldException | IllegalAccessException ignored) {
+                        // 字段不存在或无法访问,视为未忽略
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.warn("Failed to check ignore platform status", e);
+        }
+        return false;
+    }
+
     @Override
     public Object plugin(Object target) {
         return Plugin.wrap(target, this);
@@ -214,6 +252,16 @@ public class PlatformDataScopeInterceptor implements Interceptor {
             }
         }
 
+        public static Object getStaticFieldValue(Class<?> clazz, String fieldName) {
+            try {
+                Field field = getField(clazz, fieldName);
+                field.setAccessible(true);
+                return field.get(null);
+            } catch (Exception e) {
+                throw new RuntimeException("Get static field value error: " + fieldName, e);
+            }
+        }
+
         private static Field getField(Class<?> clazz, String fieldName) {
             while (clazz != null) {
                 try {

+ 20 - 9
ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/SequenceUtils.java

@@ -8,8 +8,15 @@ import org.dromara.common.core.utils.SpringUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.redisson.api.RIdGenerator;
 import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
 
 import java.time.Duration;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
 
 /**
  * 发号器工具类
@@ -178,18 +185,22 @@ public class SequenceUtils {
     }
 
     public static String generateOrderCode(String prefix) {
-        // 构建带日期的 key,确保每天重置流水号
-        String dateKey = DateUtil.format(DateUtil.date(), DatePattern.PURE_DATE_FORMATTER);
-        String businessKey = prefix + dateKey;
+        // 明确指定 bean name 为 "redisTemplate"
+        RedisTemplate<String, Object> redisTemplate = SpringUtils.getBean("redisTemplate", RedisTemplate.class);
 
-        // 每天过期,保证每天从 0001 开始
-        Duration expireTime = Duration.ofDays(1);
+        String dateKey = DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN); // 如 "yyyyMMdd"
+        String businessKey = prefix + dateKey;
 
-        // 获取补零后的4位流水号
-        String paddedSeq = SequenceUtils.nextPaddedIdStr(businessKey, expireTime, 4);
+        Long seq = redisTemplate.opsForValue().increment(businessKey);
+        if (seq == 1L) {
+            long secondsUntilEndOfDay = LocalDateTime.now().until(
+                LocalDate.now().plusDays(1).atStartOfDay(),
+                ChronoUnit.SECONDS
+            );
+            redisTemplate.expire(businessKey, secondsUntilEndOfDay, TimeUnit.SECONDS);
+        }
 
-        // 拼接最终单号
-        return businessKey + paddedSeq;
+        return businessKey + String.format("%04d", seq);
     }
 
     /*生成20位发货单号方法*/

+ 213 - 0
ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/PlatformHelper.java

@@ -0,0 +1,213 @@
+package org.dromara.common.tenant.helper;
+
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.context.model.SaStorage;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy;
+import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.constant.GlobalConstants;
+import org.dromara.common.core.context.PlatformContext;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.common.satoken.utils.LoginHelper;
+
+import java.util.Stack;
+import java.util.function.Supplier;
+
+@Slf4j
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class PlatformHelper {
+
+    private static final String DYNAMIC_PLATFORM_KEY = GlobalConstants.GLOBAL_REDIS_KEY + "dynamicPlatform";
+
+    private static final ThreadLocal<String> TEMP_DYNAMIC_PLATFORM = new ThreadLocal<>();
+
+    private static final ThreadLocal<Stack<Integer>> REENTRANT_IGNORE = ThreadLocal.withInitial(Stack::new);
+
+    /**
+     * 平台功能是否启用
+     */
+    public static boolean isEnable() {
+        return Convert.toBool(SpringUtils.getProperty("platform.enable"), false);
+    }
+
+    /**
+     * 开启忽略平台(需手动调用 disableIgnore 关闭)
+     * 复用 tenantLine 作为平台忽略标志(与 PlatformDataScopeInterceptor 配合)
+     */
+    public static void enableIgnore() {
+        InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build());
+        Stack<Integer> reentrantStack = REENTRANT_IGNORE.get();
+        reentrantStack.push(reentrantStack.size() + 1);
+    }
+
+    /**
+     * 关闭忽略平台
+     */
+    public static void disableIgnore() {
+        IgnoreStrategy current = InterceptorIgnoreHelper.getIgnoreStrategy("tenant");
+        if (current == null) {
+            return;
+        }
+
+        Stack<Integer> reentrantStack = REENTRANT_IGNORE.get();
+        boolean isOutermost = reentrantStack.isEmpty() || reentrantStack.pop() == 1;
+
+        if (!isOutermost) {
+            // 嵌套调用,仅关闭 tenantLine
+            current.setTenantLine(false);
+            return;
+        }
+
+        // 判断是否还有其他忽略项
+        boolean hasOtherIgnore = Boolean.TRUE.equals(current.getDynamicTableName())
+            || Boolean.TRUE.equals(current.getBlockAttack())
+            || Boolean.TRUE.equals(current.getIllegalSql())
+            || Boolean.TRUE.equals(current.getDataPermission())
+            || CollectionUtil.isNotEmpty(current.getOthers());
+
+        if (hasOtherIgnore) {
+            // 保留其他忽略项,仅关闭 tenantLine
+            current.setTenantLine(false);
+        } else {
+            // 完全无忽略项,清除整个策略
+            InterceptorIgnoreHelper.clearIgnoreStrategy();
+        }
+    }
+
+    /**
+     * 在忽略平台上下文中执行(无返回值)
+     */
+    public static void ignore(Runnable handle) {
+        enableIgnore();
+        try {
+            handle.run();
+        } finally {
+            disableIgnore();
+        }
+    }
+
+    /**
+     * 在忽略平台上下文中执行(有返回值)
+     */
+    public static <T> T ignore(Supplier<T> handle) {
+        enableIgnore();
+        try {
+            return handle.get();
+        } finally {
+            disableIgnore();
+        }
+    }
+
+    /**
+     * 设置动态平台(仅当前线程或全局)
+     *
+     * @param platformCode 平台编码,如 "web", "app"
+     * @param global       是否全局生效(需用户已登录)
+     */
+    public static void setDynamic(String platformCode, boolean global) {
+        if (!isEnable()) {
+            return;
+        }
+        if (!global || !LoginHelper.isLogin()) {
+            TEMP_DYNAMIC_PLATFORM.set(platformCode);
+            return;
+        }
+
+        String cacheKey = DYNAMIC_PLATFORM_KEY + ":" + LoginHelper.getUserId();
+        RedisUtils.setCacheObject(cacheKey, platformCode);
+        SaHolder.getStorage().set(cacheKey, platformCode);
+    }
+
+    public static void setDynamic(String platformCode) {
+        setDynamic(platformCode, false);
+    }
+
+    /**
+     * 获取动态平台
+     */
+    public static String getDynamic() {
+        if (!isEnable()) {
+            return null;
+        }
+        String platform = TEMP_DYNAMIC_PLATFORM.get();
+        if (StringUtils.isNotBlank(platform)) {
+            return platform;
+        }
+
+        SaStorage storage = SaHolder.getStorage();
+        if (storage == null || LoginHelper.getUserId() == null) {
+            return null;
+        }
+
+        String cacheKey = DYNAMIC_PLATFORM_KEY + ":" + LoginHelper.getUserId();
+        platform = storage.getString(cacheKey);
+        if (StringUtils.isNotBlank(platform)) {
+            return "-1".equals(platform) ? null : platform;
+        }
+
+        platform = RedisUtils.getCacheObject(cacheKey);
+        storage.set(cacheKey, StringUtils.isBlank(platform) ? "-1" : platform);
+        return platform;
+    }
+
+    /**
+     * 清除动态平台
+     */
+    public static void clearDynamic() {
+        if (!isEnable()) {
+            return;
+        }
+        TEMP_DYNAMIC_PLATFORM.remove();
+
+        SaStorage storage = SaHolder.getStorage();
+        if (storage != null && LoginHelper.getUserId() != null) {
+            String cacheKey = DYNAMIC_PLATFORM_KEY + ":" + LoginHelper.getUserId();
+            RedisUtils.deleteObject(cacheKey);
+            storage.delete(cacheKey);
+        }
+    }
+
+    /**
+     * 在指定动态平台下执行(自动清理)
+     */
+    public static void dynamic(String platformCode, Runnable handle) {
+        setDynamic(platformCode);
+        try {
+            handle.run();
+        } finally {
+            clearDynamic();
+        }
+    }
+
+    public static <T> T dynamic(String platformCode, Supplier<T> handle) {
+        setDynamic(platformCode);
+        try {
+            return handle.get();
+        } finally {
+            clearDynamic();
+        }
+    }
+
+    /**
+     * 获取当前平台(动态平台优先,否则从 PlatformContext 获取)
+     *
+     * @return 当前生效的 platformCode
+     */
+    public static String getPlatform() {
+        if (!isEnable()) {
+            return null;
+        }
+        String platform = getDynamic();
+        if (StringUtils.isBlank(platform)) {
+            platform = PlatformContext.getPlatform();
+        }
+        return platform;
+    }
+}

+ 8 - 0
ruoyi-modules/ruoyi-customer/pom.xml

@@ -108,6 +108,14 @@
             <groupId>org.dromara</groupId>
             <artifactId>ruoyi-api-workflow</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-customer</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-customer</artifactId>
+        </dependency>
 
     </dependencies>
 

+ 7 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/CustomerDeptController.java

@@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.customer.domain.vo.CustomerDeptTreeVo;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -45,6 +46,12 @@ public class CustomerDeptController extends BaseController {
         return R.ok(list);
     }
 
+    @GetMapping("/tree")
+    public R<List<CustomerDeptTreeVo>> getCustomerDeptTree(@RequestParam Long customerId) {
+        List<CustomerDeptTreeVo> list = customerDeptService.getCustomerDeptTree(customerId);
+        return R.ok(list);
+    }
+
     /**
      * 导出客户部门信息列表
      */

+ 2 - 44
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/CustomerDept.java

@@ -25,39 +25,14 @@ public class CustomerDept extends TenantEntity {
     /**
      * ID
      */
-    @TableId(value = "id")
-    private Long id;
-
-    /**
-     * 部门编号
-     */
-    private String deptNo;
-
-    /**
-     * 部门名称
-     */
-    private String deptName;
-
-    /**
-     * 父部门id
-     */
-    private Long parentId;
-
-    /**
-     * 祖级列表
-     */
-    private String ancestors;
+    @TableId(value = "dept_id")
+    private Long deptId;
 
     /**
      * 客户编号
      */
     private Long customerId;
 
-    /**
-     * 部门层级(如1级、2级等)
-     */
-    private Long departmentLevel;
-
     /**
      * 年度预算
      */
@@ -118,21 +93,4 @@ public class CustomerDept extends TenantEntity {
      */
     private Long recharge;
 
-    /**
-     * 状态(0正常 1停用)
-     */
-    private String status;
-
-    /**
-     * 删除标志(0代表存在 2代表删除)
-     */
-    @TableLogic
-    private String delFlag;
-
-    /**
-     * 备注
-     */
-    private String remark;
-
-
 }

+ 1 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/CustomerSalesInfo.java

@@ -72,7 +72,7 @@ public class CustomerSalesInfo extends TenantEntity {
     /**
      * 信用管理方式
      */
-    private String creditManagement;
+    private Long creditManagementId;
 
     /**
      * 信用支付密码

+ 1 - 5
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/CustomerDeptBo.java

@@ -25,7 +25,7 @@ public class CustomerDeptBo extends BaseEntity {
     /**
      * ID
      */
-    private Long id;
+    private Long deptId;
 
     /**
      * 部门编号
@@ -35,7 +35,6 @@ public class CustomerDeptBo extends BaseEntity {
     /**
      * 部门名称
      */
-    @NotBlank(message = "部门名称不能为空", groups = {AddGroup.class, EditGroup.class})
     private String deptName;
 
     /**
@@ -61,19 +60,16 @@ public class CustomerDeptBo extends BaseEntity {
     /**
      * 年度预算
      */
-    @NotNull(message = "年度预算不能为空", groups = {AddGroup.class, EditGroup.class})
     private BigDecimal yearlyBudget;
 
     /**
      * 已使用预算
      */
-    @NotNull(message = "已使用预算不能为空", groups = {AddGroup.class, EditGroup.class})
     private BigDecimal usedBudget;
 
     /**
      * 月度限额
      */
-    @NotNull(message = "月度限额不能为空", groups = {AddGroup.class, EditGroup.class})
     private BigDecimal monthLimit;
 
     /**

+ 1 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/CustomerSalesInfoBo.java

@@ -72,7 +72,7 @@ public class CustomerSalesInfoBo extends BaseEntity {
     /**
      * 信用管理方式
      */
-    private String creditManagement;
+    private Long creditManagementId;
 
     /**
      * 信用支付密码

+ 27 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerDeptTreeVo.java

@@ -0,0 +1,27 @@
+package org.dromara.customer.domain.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+public class CustomerDeptTreeVo implements Serializable {
+
+    private Long deptId;            // = dept_id
+    private Long parentId;      // 来自 sys_dept
+    private String deptName;    // 来自 sys_dept
+    private Integer orderNum;   // 排序
+
+    // 业务字段(来自 customer_dept)
+    private BigDecimal yearlyBudget;
+    private BigDecimal usedBudget;
+    private BigDecimal monthLimit;
+    private String bindAddress;
+    private String bindStatus;
+    private String status;      // 来自 sys_dept(启用/停用)
+
+    // 可选:是否叶子节点(前端有时需要)
+    private Boolean hasChildren = false;
+
+}

+ 2 - 9
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerDeptVo.java

@@ -31,8 +31,8 @@ public class CustomerDeptVo implements Serializable {
     /**
      * ID
      */
-    @ExcelProperty(value = "ID")
-    private Long id;
+    @ExcelProperty(value = "dept_id")
+    private Long deptId;
 
     /**
      * 部门编号
@@ -64,13 +64,6 @@ public class CustomerDeptVo implements Serializable {
     @ExcelProperty(value = "客户编号")
     private Long customerId;
 
-    /**
-     * 部门层级(如1级、2级等)
-     */
-    @ExcelProperty(value = "部门层级", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(readConverterExp = "如=1级、2级等")
-    private BigDecimal departmentLevel;
-
     /**
      * 年度预算
      */

+ 1 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerSalesInfoVo.java

@@ -90,7 +90,7 @@ public class CustomerSalesInfoVo implements Serializable {
      * 信用管理方式
      */
     @ExcelProperty(value = "信用管理方式")
-    private String creditManagement;
+    private Long creditManagementId;
 
     /**
      * 信用支付密码

+ 25 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/dubbo/RemoteCustomerServiceImpl.java

@@ -0,0 +1,25 @@
+package org.dromara.customer.dubbo;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.dromara.customer.api.RemoteCustomerService;
+import org.dromara.customer.service.ICustomerInfoService;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+import java.util.Set;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+@DubboService
+public class RemoteCustomerServiceImpl implements RemoteCustomerService {
+
+    private final ICustomerInfoService customerInfoService;
+
+    @Override
+    public Map<Long, String> selectCustomerNameByIds(Set<Long> ids) {
+        return customerInfoService.selectCustomerNameByIds(ids);
+    }
+}

+ 4 - 2
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerDeptService.java

@@ -2,6 +2,7 @@ package org.dromara.customer.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import org.dromara.customer.domain.CustomerDept;
+import org.dromara.customer.domain.vo.CustomerDeptTreeVo;
 import org.dromara.customer.domain.vo.CustomerDeptVo;
 import org.dromara.customer.domain.bo.CustomerDeptBo;
 
@@ -14,7 +15,7 @@ import java.util.List;
  * @author LionLi
  * @date 2025-12-18
  */
-public interface ICustomerDeptService extends IService<CustomerDept>{
+public interface ICustomerDeptService extends IService<CustomerDept> {
 
     /**
      * 查询客户部门信息
@@ -24,7 +25,6 @@ public interface ICustomerDeptService extends IService<CustomerDept>{
      */
     CustomerDeptVo queryById(Long id);
 
-
     /**
      * 查询符合条件的客户部门信息列表
      *
@@ -33,6 +33,8 @@ public interface ICustomerDeptService extends IService<CustomerDept>{
      */
     List<CustomerDeptVo> queryList(CustomerDeptBo bo);
 
+    List<CustomerDeptTreeVo> getCustomerDeptTree(Long customerId);
+
     /**
      * 新增客户部门信息
      *

+ 4 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerInfoService.java

@@ -15,6 +15,8 @@ import org.dromara.customer.domain.vo.MessagePublishCustomerVo;
 import java.math.BigDecimal;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * 客户信息Service接口
@@ -104,6 +106,8 @@ public interface ICustomerInfoService extends IService<CustomerInfo> {
     /*设置客户标签*/
     int setCustomerInfoTag(List<Long> customerIds, List<Long> tagIds);
 
+    Map<Long, String> selectCustomerNameByIds(Set<Long> ids);
+
     /**
      * 校验并批量删除客户信息信息
      *

+ 137 - 70
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerDeptServiceImpl.java

@@ -1,27 +1,33 @@
 package org.dromara.customer.service.impl;
 
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import org.dromara.common.core.constant.SystemConstants;
-import org.dromara.common.core.exception.ServiceException;
-import org.dromara.common.core.utils.MapstructUtils;
-import org.dromara.common.core.utils.StringUtils;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.lang.tree.Tree;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.dromara.common.redis.utils.SequenceUtils;
-import org.springframework.stereotype.Service;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.dromara.common.core.context.PlatformContext;
+import org.dromara.common.core.enums.IsDefault;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.customer.domain.CustomerDept;
+import org.dromara.customer.domain.CustomerInfo;
 import org.dromara.customer.domain.bo.CustomerDeptBo;
+import org.dromara.customer.domain.vo.CustomerDeptTreeVo;
 import org.dromara.customer.domain.vo.CustomerDeptVo;
-import org.dromara.customer.domain.CustomerDept;
 import org.dromara.customer.mapper.CustomerDeptMapper;
 import org.dromara.customer.service.ICustomerDeptService;
+import org.dromara.system.api.RemoteDeptService;
+import org.dromara.system.api.domain.vo.RemoteDeptVo;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
-import java.time.Duration;
-import java.util.List;
-import java.util.Map;
-import java.util.Collection;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 客户部门信息Service业务层处理
@@ -34,6 +40,9 @@ import java.util.Collection;
 @Service
 public class CustomerDeptServiceImpl extends ServiceImpl<CustomerDeptMapper, CustomerDept> implements ICustomerDeptService {
 
+    @DubboReference
+    private RemoteDeptService remoteDeptService;
+
     private static final String DEPT_NO_KEY = "customer_dept:dept_no";
 
     private final CustomerDeptMapper baseMapper;
@@ -62,16 +71,64 @@ public class CustomerDeptServiceImpl extends ServiceImpl<CustomerDeptMapper, Cus
         return baseMapper.selectVoList(lqw);
     }
 
+    @Override
+    public List<CustomerDeptTreeVo> getCustomerDeptTree(Long customerId) {
+        if (customerId == null) {
+            return Collections.emptyList();
+        }
+
+        // 1. 查 customer_dept
+        List<CustomerDept> customerDepts = baseMapper.selectList(
+            new LambdaQueryWrapper<CustomerDept>()
+                .eq(CustomerDept::getCustomerId, customerId)
+        );
+
+        if (CollUtil.isEmpty(customerDepts)) {
+            return Collections.emptyList();
+        }
+
+        // 2. 查 sys_dept
+        List<Long> deptIds = customerDepts.stream()
+            .map(CustomerDept::getDeptId)
+            .collect(Collectors.toList());
+
+        List<RemoteDeptVo> sysDepts = remoteDeptService.selectDeptByIds(deptIds);
+
+        Map<Long, RemoteDeptVo> deptMap = sysDepts.stream()
+            .collect(Collectors.toMap(RemoteDeptVo::getDeptId, d -> d));
+
+        // 3. 合并 + 安全排序
+        return customerDepts.stream()
+            .filter(cd -> deptMap.containsKey(cd.getDeptId()))
+            .map(cd -> {
+                RemoteDeptVo sys = deptMap.get(cd.getDeptId());
+                CustomerDeptTreeVo vo = new CustomerDeptTreeVo();
+                vo.setDeptId(sys.getDeptId());
+                vo.setParentId(sys.getParentId());
+                vo.setDeptName(sys.getDeptName());
+                vo.setOrderNum(sys.getOrderNum()); // 可能为 null!
+                vo.setStatus(sys.getStatus());
+
+                vo.setYearlyBudget(cd.getYearlyBudget());
+                vo.setUsedBudget(cd.getUsedBudget());
+                vo.setMonthLimit(cd.getMonthLimit());
+                vo.setBindAddress(cd.getBindAddress());
+                vo.setBindStatus(cd.getBindStatus());
+
+                return vo;
+            })
+            .sorted(Comparator.comparing(
+                CustomerDeptTreeVo::getOrderNum,
+                Comparator.nullsLast(Comparator.naturalOrder()) // ✅ 安全处理 null
+            ))
+            .collect(Collectors.toList());
+    }
+
     private LambdaQueryWrapper<CustomerDept> buildQueryWrapper(CustomerDeptBo bo) {
         Map<String, Object> params = bo.getParams();
         LambdaQueryWrapper<CustomerDept> lqw = Wrappers.lambdaQuery();
-        lqw.orderByAsc(CustomerDept::getId);
-        lqw.eq(StringUtils.isNotBlank(bo.getDeptNo()), CustomerDept::getDeptNo, bo.getDeptNo());
-        lqw.like(StringUtils.isNotBlank(bo.getDeptName()), CustomerDept::getDeptName, bo.getDeptName());
-        lqw.eq(bo.getParentId() != null, CustomerDept::getParentId, bo.getParentId());
+        lqw.orderByAsc(CustomerDept::getDeptId);
         lqw.eq(bo.getCustomerId() != null, CustomerDept::getCustomerId, bo.getCustomerId());
-        lqw.eq(StringUtils.isNotBlank(bo.getAncestors()), CustomerDept::getAncestors, bo.getAncestors());
-        lqw.eq(bo.getDepartmentLevel() != null, CustomerDept::getDepartmentLevel, bo.getDepartmentLevel());
         lqw.eq(bo.getYearlyBudget() != null, CustomerDept::getYearlyBudget, bo.getYearlyBudget());
         lqw.eq(bo.getUsedBudget() != null, CustomerDept::getUsedBudget, bo.getUsedBudget());
         lqw.eq(bo.getMonthLimit() != null, CustomerDept::getMonthLimit, bo.getMonthLimit());
@@ -81,74 +138,84 @@ public class CustomerDeptServiceImpl extends ServiceImpl<CustomerDeptMapper, Cus
         lqw.eq(StringUtils.isNotBlank(bo.getDeptManage()), CustomerDept::getDeptManage, bo.getDeptManage());
         lqw.eq(StringUtils.isNotBlank(bo.getIsLimit()), CustomerDept::getIsLimit, bo.getIsLimit());
         lqw.eq(StringUtils.isNotBlank(bo.getSelectYear()), CustomerDept::getSelectYear, bo.getSelectYear());
-        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), CustomerDept::getStatus, bo.getStatus());
         lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), CustomerDept::getPlatformCode, bo.getPlatformCode());
         return lqw;
     }
 
-    /**
-     * 新增客户部门信息
-     *
-     * @param bo 客户部门信息
-     * @return 是否新增成功
-     */
+
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Boolean insertByBo(CustomerDeptBo bo) {
-        bo.setDeptNo(SequenceUtils.nextPaddedIdStr(DEPT_NO_KEY, Duration.ofDays(3650), 5));
+        try {
+            // 1. 参数校验
+            if (bo == null || bo.getCustomerId() == null) {
+                throw new IllegalArgumentException("客户ID不能为空");
+            }
 
-        CustomerDept info = baseMapper.selectById(bo.getParentId());
-        // 如果父节点不为正常状态,则不允许新增子节点
-        if (!SystemConstants.NORMAL.equals(info.getStatus())) {
-            throw new ServiceException("部门停用,不允许新增");
-        }
+            // 2. 构建并插入 sys_dept 部门结构
+            RemoteDeptVo remoteDeptVo = new RemoteDeptVo();
+            remoteDeptVo.setParentId(bo.getParentId());
+            remoteDeptVo.setDeptName(bo.getDeptName());
+            remoteDeptVo.setPlatformCode(PlatformContext.getPlatform());
+
+
+            RemoteDeptVo deptVo = remoteDeptService.insertDept(remoteDeptVo);
+
+            // 3. 校验 deptId 是否回填成功
+            if (deptVo == null || deptVo.getDeptId() == null) {
+                log.error("创建部门失败:未返回有效部门ID");
+            }
 
-        CustomerDept dept = MapstructUtils.convert(bo, CustomerDept.class);
-        dept.setAncestors(info.getAncestors() + StringUtils.SEPARATOR + dept.getParentId());
-        validEntityBeforeSave(dept);
-        boolean flag = baseMapper.insert(dept) > 0;
-        if (flag) {
-            bo.setId(dept.getId());
+            // 4. 插入 customer_dept 业务数据
+            CustomerDept dept = new CustomerDept();
+            dept.setDeptId(deptVo.getDeptId());
+            dept.setCustomerId(bo.getCustomerId());
+            dept.setYearlyBudget(bo.getYearlyBudget());
+            dept.setMonthLimit(bo.getMonthLimit());
+            dept.setUsedBudget(bo.getUsedBudget());
+            dept.setBindStatus(bo.getBindStatus());
+            dept.setBindAddress(bo.getBindAddress());
+
+            boolean success = baseMapper.insert(dept) > 0;
+            if (!success) {
+                log.error("创建部门失败:插入业务数据失败");
+            }
+            return success;
+        } catch (IllegalArgumentException e) {
+            log.error("创建部门失败:{}", e.getMessage());
+            throw new RuntimeException(e);
         }
-        return flag;
     }
 
-    /**
-     * 修改客户部门信息
-     *
-     * @param bo 客户部门信息
-     * @return 是否修改成功
-     */
     @Override
     public Boolean updateByBo(CustomerDeptBo bo) {
-        CustomerDept update = MapstructUtils.convert(bo, CustomerDept.class);
-        validEntityBeforeSave(update);
-        return baseMapper.updateById(update) > 0;
-    }
 
-    /**
-     * 保存前的数据校验
-     */
-    private boolean validEntityBeforeSave(CustomerDept dept) {
-        boolean exist = baseMapper.exists(new LambdaQueryWrapper<CustomerDept>()
-            .eq(CustomerDept::getDeptName, dept.getDeptName())
-            .eq(CustomerDept::getParentId, dept.getParentId())
-            .eq(CustomerDept::getPlatformCode, dept.getPlatformCode())
-            .ne(ObjectUtil.isNotNull(dept.getId()), CustomerDept::getId, dept.getId()));
-        return !exist;
+        if (bo == null || bo.getDeptId() == null || bo.getDeptId() <= 0) {
+            return false;
+        }
+        RemoteDeptVo remoteDeptVo = remoteDeptService.selectDeptById(bo.getDeptId());
+        if (remoteDeptVo == null) {
+            return false;
+        }
+
+        MapstructUtils.convert(bo, CustomerInfo.class);
+
+
+        // 1. 更新主表
+        CustomerInfo entity = MapstructUtils.convert(bo, CustomerInfo.class);
+//        boolean mainUpdated = baseMapper.updateById(entity) > 0;
+//        if (!mainUpdated) {
+//            return false;
+//        }
+//
+//        Long customerId = bo.getId();
+
+
+        return true;
     }
 
-    /**
-     * 校验并批量删除客户部门信息信息
-     *
-     * @param ids     待删除的主键集合
-     * @param isValid 是否进行有效性校验
-     * @return 是否删除成功
-     */
     @Override
     public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if (isValid) {
-            //TODO 做一些业务上的校验,判断是否需要校验
-        }
-        return baseMapper.deleteByIds(ids) > 0;
+        return null;
     }
 }

+ 115 - 89
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerInfoServiceImpl.java

@@ -41,7 +41,8 @@ import java.util.stream.Collectors;
 @RequiredArgsConstructor
 @Service
 public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, CustomerInfo> implements ICustomerInfoService {
-
+    @DubboReference
+    private RemoteDeptService remoteDeptService;
     @DubboReference
     private RemoteComPostService remoteComPostService;
     @DubboReference
@@ -125,7 +126,7 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
 
         Map<Long, String> deptMap = deptIds.isEmpty()
             ? Collections.emptyMap()
-            : remoteComDeptService.selectDeptNameByIds(deptIds);
+            : remoteDeptService.selectDeptNameByIds(deptIds);
 
         // 先转换
         CustomerSalesInfoVo voObj = MapstructUtils.convert(customerSalesInfo, CustomerSalesInfoVo.class);
@@ -251,7 +252,7 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
 
         Map<Long, String> deptMap = deptIds.isEmpty()
             ? Collections.emptyMap()
-            : remoteComDeptService.selectDeptNameByIds(deptIds);
+            : remoteDeptService.selectDeptNameByIds(deptIds);
 
         // === 6. 回填人员和部门名称到 salesInfoVo ===
         for (CustomerSalesInfoVo vo : salesInfoVos) {
@@ -503,104 +504,105 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Boolean insertByBo(CustomerInfoBo bo) {
-        if (bo == null) {
-            return false;
-        }
-        String platform = PlatformContext.getPlatform();
-//        RemoteDeptVo deptVo = remoteDeptService.selectParentDeptByPlatformCode(platform);
+        try {
+            if (bo == null) {
+                return false;
+            }
+            String platform = PlatformContext.getPlatform();
 
-        boolean isNew = bo.getId() == null || bo.getId() <= 0;
+            boolean isNew = bo.getId() == null || bo.getId() <= 0;
 
-        // 1. 处理主表 CustomerInfo
-        CustomerInfo entity = MapstructUtils.convert(bo, CustomerInfo.class);
-        validEntityBeforeSave(entity);
+            // 1. 处理主表 CustomerInfo
+            CustomerInfo entity = MapstructUtils.convert(bo, CustomerInfo.class);
+            validEntityBeforeSave(entity);
 
-        boolean success;
-        if (isNew) {
-            success = baseMapper.insert(entity) > 0;
-            if (success) {
-                bo.setId(entity.getId()); // 回填ID
+            boolean success;
+            if (isNew) {
+                success = baseMapper.insert(entity) > 0;
+                if (success) {
+                    bo.setId(entity.getId()); // 回填ID
+                }
+            } else {
+                success = baseMapper.updateById(entity) > 0;
             }
-        } else {
-            success = baseMapper.updateById(entity) > 0;
-        }
 
-        if (!success) {
-            return false;
-        }
+            if (!success) {
+                return false;
+            }
 
-        Long customerId = entity.getId();
-
-        /*新增客户时给每个客户创建自己的组织架构*/
-//        RemoteDeptVo remoteDeptVo = new RemoteDeptVo();
-//        remoteDeptVo.setParentId(deptVo.getDeptId());
-//        remoteDeptVo.setCustomerId(customerId);
-//        remoteDeptVo.setDeptName(bo.getCustomerName());
-//        remoteDeptVo.setPlatformCode(platform);
-//        remoteDeptService.insertDept(remoteDeptVo);
-        CustomerDept dept = new CustomerDept();
-        dept.setCustomerId(customerId);
-        dept.setDeptName(bo.getCustomerName());
-        dept.setParentId(0L);
-        dept.setYearlyBudget(BigDecimal.ZERO);
-        dept.setYearlyBudget(BigDecimal.ZERO);
-        dept.setMonthLimit(BigDecimal.ZERO);
-        dept.setUsedBudget(BigDecimal.ZERO);
-        dept.setStatus(IsDefault.No.getCode());
-        dept.setBindStatus(IsDefault.No.getCode());
-        customerDeptMapper.insert(dept);
-
-
-        // 2. 获取各子对象
-        CustomerBusinessInfoBo businessBo = bo.getCustomerBusinessBo();
-        CustomerSalesInfoBo salesBo = bo.getCustomerSalesInfoBo();
-        List<CustomerContactBo> contactList = bo.getCustomerContactBoList();
-        List<CustomerInvoiceInfoBo> invoiceList = bo.getCustomerInvoiceInfoBoList();
-
-        // 3. 如果是更新,先删除旧的关联数据
-        if (!isNew) {
-            // 删除业务信息(一对一)
-            customerBusinessInfoMapper.deleteByCustomerId(customerId);
-            // 删除销售信息(一对一)
-            customerSalesInfoMapper.deleteByCustomerId(customerId);
-            // 删除发票信息(一对多)
-            customerInvoiceInfoMapper.deleteByCustomerId(customerId);
-        }
-
-        // 4. 插入新的关联数据(即使为空也安全处理)
-        // 业务信息
-        if (businessBo != null) {
-            CustomerBusinessInfo businessEntity = MapstructUtils.convert(businessBo, CustomerBusinessInfo.class);
-            businessEntity.setCustomerId(customerId);
-            customerBusinessInfoMapper.insert(businessEntity);
-        }
+            Long customerId = entity.getId();
+
+            /*新增客户时给每个客户创建自己的组织架构*/
+            RemoteDeptVo remoteDeptVo = new RemoteDeptVo();
+            remoteDeptVo.setParentId(100L);
+            remoteDeptVo.setDeptName(bo.getCustomerName());
+            remoteDeptVo.setPlatformCode(platform);
+            RemoteDeptVo deptVo = remoteDeptService.insertDept(remoteDeptVo);
+
+            CustomerDept dept = new CustomerDept();
+            dept.setDeptId(deptVo.getDeptId());
+            dept.setCustomerId(customerId);
+            dept.setYearlyBudget(BigDecimal.ZERO);
+            dept.setMonthLimit(BigDecimal.ZERO);
+            dept.setUsedBudget(BigDecimal.ZERO);
+            dept.setBindStatus(IsDefault.No.getCode());
+            customerDeptMapper.insert(dept);
+
+
+            // 2. 获取各子对象
+            CustomerBusinessInfoBo businessBo = bo.getCustomerBusinessBo();
+            CustomerSalesInfoBo salesBo = bo.getCustomerSalesInfoBo();
+            List<CustomerContactBo> contactList = bo.getCustomerContactBoList();
+            List<CustomerInvoiceInfoBo> invoiceList = bo.getCustomerInvoiceInfoBoList();
+
+            // 3. 如果是更新,先删除旧的关联数据
+            if (!isNew) {
+                // 删除业务信息(一对一)
+                customerBusinessInfoMapper.deleteByCustomerId(customerId);
+                // 删除销售信息(一对一)
+                customerSalesInfoMapper.deleteByCustomerId(customerId);
+                // 删除发票信息(一对多)
+                customerInvoiceInfoMapper.deleteByCustomerId(customerId);
+            }
 
-        // 销售信息
-        if (salesBo != null) {
-            CustomerSalesInfo salesEntity = MapstructUtils.convert(salesBo, CustomerSalesInfo.class);
-            salesEntity.setCustomerId(customerId);
-            customerSalesInfoMapper.insert(salesEntity);
-        }
+            // 4. 插入新的关联数据(即使为空也安全处理)
+            // 业务信息
+            if (businessBo != null) {
+                CustomerBusinessInfo businessEntity = MapstructUtils.convert(businessBo, CustomerBusinessInfo.class);
+                businessEntity.setCustomerId(customerId);
+                customerBusinessInfoMapper.insert(businessEntity);
+            }
 
-        // 联系人列表
-        if (contactList != null && !contactList.isEmpty()) {
-            for (CustomerContactBo contactBo : contactList) {
-                CustomerContact contact = MapstructUtils.convert(contactBo, CustomerContact.class);
-                contact.setCustomerId(customerId);
-                customerContactMapper.insert(contact);
+            // 销售信息
+            if (salesBo != null) {
+                CustomerSalesInfo salesEntity = MapstructUtils.convert(salesBo, CustomerSalesInfo.class);
+                salesEntity.setCustomerId(customerId);
+                customerSalesInfoMapper.insert(salesEntity);
             }
-        }
 
-        // 发票信息列表
-        if (invoiceList != null && !invoiceList.isEmpty()) {
-            for (CustomerInvoiceInfoBo invoiceBo : invoiceList) {
-                CustomerInvoiceInfo invoice = MapstructUtils.convert(invoiceBo, CustomerInvoiceInfo.class);
-                invoice.setCustomerId(customerId);
-                customerInvoiceInfoMapper.insert(invoice);
+            // 联系人列表
+            if (contactList != null && !contactList.isEmpty()) {
+                for (CustomerContactBo contactBo : contactList) {
+                    CustomerContact contact = MapstructUtils.convert(contactBo, CustomerContact.class);
+                    contact.setCustomerId(customerId);
+                    customerContactMapper.insert(contact);
+                }
             }
-        }
 
-        return true;
+            // 发票信息列表
+            if (invoiceList != null && !invoiceList.isEmpty()) {
+                for (CustomerInvoiceInfoBo invoiceBo : invoiceList) {
+                    CustomerInvoiceInfo invoice = MapstructUtils.convert(invoiceBo, CustomerInvoiceInfo.class);
+                    invoice.setCustomerId(customerId);
+                    customerInvoiceInfoMapper.insert(invoice);
+                }
+            }
+            log.info("新增客户信息成功:{}", bo);
+            return true;
+        } catch (Exception e) {
+            log.error("新增客户信息失败:{}", e.getMessage());
+            throw new RuntimeException(e);
+        }
     }
 
     /**
@@ -753,6 +755,30 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
         }
     }
 
+    public Map<Long, String> selectCustomerNameByIds(Set<Long> ids) {
+        if (ids == null || ids.isEmpty()) {
+            return Collections.emptyMap();
+        }
+
+        // 限制批量大小
+        if (ids.size() > 1000) {
+            throw new IllegalArgumentException("Batch size exceeds limit: " + ids.size());
+        }
+
+        List<CustomerInfo> customerInfoList = baseMapper.selectByIds(ids);
+        Map<Long, String> resultMap = new HashMap<>(ids.size());
+
+        // 初始化所有请求的 ID 为 null
+        ids.forEach(id -> resultMap.put(id, null));
+
+        if (customerInfoList != null) {
+            customerInfoList.stream()
+                .filter(dept -> dept.getId() != null && dept.getCustomerName() != null)
+                .forEach(dept -> resultMap.put(dept.getId(), dept.getCustomerName()));
+        }
+
+        return resultMap;
+    }
 
     /**
      * 保存前的数据校验

+ 0 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerSalesInfoServiceImpl.java

@@ -82,7 +82,6 @@ public class CustomerSalesInfoServiceImpl extends ServiceImpl<CustomerSalesInfoM
         lqw.eq(bo.getBillDate() != null, CustomerSalesInfo::getBillDate, bo.getBillDate());
         lqw.eq(bo.getBillingDay() != null, CustomerSalesInfo::getBillingDay, bo.getBillingDay());
         lqw.eq(StringUtils.isNotBlank(bo.getOrderAudit()), CustomerSalesInfo::getOrderAudit, bo.getOrderAudit());
-        lqw.eq(StringUtils.isNotBlank(bo.getCreditManagement()), CustomerSalesInfo::getCreditManagement, bo.getCreditManagement());
         lqw.eq(StringUtils.isNotBlank(bo.getCreditPaymentPassword()), CustomerSalesInfo::getCreditPaymentPassword, bo.getCreditPaymentPassword());
         lqw.eq(bo.getPayDays() != null, CustomerSalesInfo::getPayDays, bo.getPayDays());
         lqw.eq(bo.getSalesPersonId() != null, CustomerSalesInfo::getSalesPersonId, bo.getSalesPersonId());

+ 4 - 0
ruoyi-modules/ruoyi-order/pom.xml

@@ -112,6 +112,10 @@
             <groupId>org.dromara</groupId>
             <artifactId>ruoyi-api-order</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-customer</artifactId>
+        </dependency>
 
     </dependencies>
 

+ 119 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderAssignmentController.java

@@ -0,0 +1,119 @@
+package org.dromara.order.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.order.domain.bo.OrderSplitAssignBo;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.order.domain.vo.OrderAssignmentVo;
+import org.dromara.order.domain.bo.OrderAssignmentBo;
+import org.dromara.order.service.IOrderAssignmentService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 订单分配记录
+ * 前端访问路由地址为:/order/orderAssignment
+ *
+ * @author LionLi
+ * @date 2026-01-07
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/orderAssignment")
+public class OrderAssignmentController extends BaseController {
+
+    private final IOrderAssignmentService orderAssignmentService;
+
+    /**
+     * 查询订单分配记录列表
+     */
+//    @SaCheckPermission("order:orderAssignment:list")
+    @GetMapping("/list")
+    public TableDataInfo<OrderAssignmentVo> list(OrderAssignmentBo bo, PageQuery pageQuery) {
+        return orderAssignmentService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出订单分配记录列表
+     */
+//    @SaCheckPermission("order:orderAssignment:export")
+    @Log(title = "订单分配记录", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(OrderAssignmentBo bo, HttpServletResponse response) {
+        List<OrderAssignmentVo> list = orderAssignmentService.queryList(bo);
+        ExcelUtil.exportExcel(list, "订单分配记录", OrderAssignmentVo.class, response);
+    }
+
+    /**
+     * 获取订单分配记录详细信息
+     *
+     * @param id 主键
+     */
+//    @SaCheckPermission("order:orderAssignment:query")
+    @GetMapping("/{id}")
+    public R<OrderAssignmentVo> getInfo(@NotNull(message = "主键不能为空")
+                                        @PathVariable("id") Long id) {
+        return R.ok(orderAssignmentService.queryById(id));
+    }
+
+    /**
+     * 新增订单分配记录
+     */
+//    @SaCheckPermission("order:orderAssignment:add")
+    @Log(title = "订单分配记录", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody OrderAssignmentBo bo) {
+        return toAjax(orderAssignmentService.insertByBo(bo));
+    }
+
+
+    /**
+     * 新增订单分配记录------拆单
+     */
+//    @SaCheckPermission("order:orderAssignment:add")
+    @Log(title = "订单分配记录", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping("/splitAssign")
+    public R<Void> splitAssign(@Validated(AddGroup.class) @RequestBody OrderSplitAssignBo bo) {
+        return toAjax(orderAssignmentService.splitAssign(bo));
+    }
+
+    /**
+     * 修改订单分配记录
+     */
+//    @SaCheckPermission("order:orderAssignment:edit")
+    @Log(title = "订单分配记录", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody OrderAssignmentBo bo) {
+        return toAjax(orderAssignmentService.updateByBo(bo));
+    }
+
+    /**
+     * 删除订单分配记录
+     *
+     * @param ids 主键串
+     */
+//    @SaCheckPermission("order:orderAssignment:remove")
+    @Log(title = "订单分配记录", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(orderAssignmentService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 18 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderMainController.java

@@ -13,6 +13,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.tenant.helper.PlatformHelper;
 import org.dromara.common.web.core.BaseController;
 import org.dromara.order.domain.bo.OrderMainBo;
 import org.dromara.order.domain.vo.OrderMainVo;
@@ -46,6 +47,14 @@ public class OrderMainController extends BaseController {
         return orderMainService.queryPageList(bo, pageQuery);
     }
 
+    /**
+     * 查询分配订单列表
+     */
+    @GetMapping("/assignmentList")
+    public TableDataInfo<OrderMainVo> assignmentList(OrderMainBo bo, PageQuery pageQuery) {
+        return PlatformHelper.ignore(() -> orderMainService.queryPageList(bo, pageQuery));
+    }
+
     /**
      * 查询订单状态数量
      */
@@ -119,4 +128,13 @@ public class OrderMainController extends BaseController {
     public R<Void> changeStatus(@RequestBody OrderMainBo bo) {
         return toAjax(orderMainService.updateStatus(bo));
     }
+
+    /**
+     * 订单审核
+     */
+    @Log(title = "订单主信息", businessType = BusinessType.UPDATE)
+    @PutMapping("/checkStatus")
+    public R<Void> checkStatus(@RequestBody OrderMainBo bo) {
+        return toAjax(orderMainService.updateCheckStatus(bo));
+    }
 }

+ 106 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderReturnController.java

@@ -0,0 +1,106 @@
+package org.dromara.order.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.order.domain.vo.OrderReturnVo;
+import org.dromara.order.domain.bo.OrderReturnBo;
+import org.dromara.order.service.IOrderReturnService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 退货主
+ * 前端访问路由地址为:/order/orderReturn
+ *
+ * @author LionLi
+ * @date 2026-01-05
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/orderReturn")
+public class OrderReturnController extends BaseController {
+
+    private final IOrderReturnService orderReturnService;
+
+    /**
+     * 查询退货主列表
+     */
+//    @SaCheckPermission("order:orderReturn:list")
+    @GetMapping("/list")
+    public TableDataInfo<OrderReturnVo> list(OrderReturnBo bo, PageQuery pageQuery) {
+        return orderReturnService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出退货主列表
+     */
+//    @SaCheckPermission("order:orderReturn:export")
+    @Log(title = "退货主", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(OrderReturnBo bo, HttpServletResponse response) {
+        List<OrderReturnVo> list = orderReturnService.queryList(bo);
+        ExcelUtil.exportExcel(list, "退货主", OrderReturnVo.class, response);
+    }
+
+    /**
+     * 获取退货主详细信息
+     *
+     * @param id 主键
+     */
+//    @SaCheckPermission("order:orderReturn:query")
+    @GetMapping("/{id}")
+    public R<OrderReturnVo> getInfo(@NotNull(message = "主键不能为空")
+                                    @PathVariable("id") Long id) {
+        return R.ok(orderReturnService.queryById(id));
+    }
+
+    /**
+     * 新增退货主
+     */
+//    @SaCheckPermission("order:orderReturn:add")
+    @Log(title = "退货主", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody OrderReturnBo bo) {
+        return toAjax(orderReturnService.insertByBo(bo));
+    }
+
+    /**
+     * 修改退货主
+     */
+//    @SaCheckPermission("order:orderReturn:edit")
+    @Log(title = "退货主", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody OrderReturnBo bo) {
+        return toAjax(orderReturnService.updateByBo(bo));
+    }
+
+    /**
+     * 删除退货主
+     *
+     * @param ids 主键串
+     */
+//    @SaCheckPermission("order:orderReturn:remove")
+    @Log(title = "退货主", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(orderReturnService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 106 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderReturnItemController.java

@@ -0,0 +1,106 @@
+package org.dromara.order.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.order.domain.vo.OrderReturnItemVo;
+import org.dromara.order.domain.bo.OrderReturnItemBo;
+import org.dromara.order.service.IOrderReturnItemService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 退货商品明细
+ * 前端访问路由地址为:/order/orderReturnItem
+ *
+ * @author LionLi
+ * @date 2026-01-05
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/orderReturnItem")
+public class OrderReturnItemController extends BaseController {
+
+    private final IOrderReturnItemService orderReturnItemService;
+
+    /**
+     * 查询退货商品明细列表
+     */
+//    @SaCheckPermission("order:orderReturnItem:list")
+    @GetMapping("/list")
+    public TableDataInfo<OrderReturnItemVo> list(OrderReturnItemBo bo, PageQuery pageQuery) {
+        return orderReturnItemService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出退货商品明细列表
+     */
+//    @SaCheckPermission("order:orderReturnItem:export")
+    @Log(title = "退货商品明细", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(OrderReturnItemBo bo, HttpServletResponse response) {
+        List<OrderReturnItemVo> list = orderReturnItemService.queryList(bo);
+        ExcelUtil.exportExcel(list, "退货商品明细", OrderReturnItemVo.class, response);
+    }
+
+    /**
+     * 获取退货商品明细详细信息
+     *
+     * @param id 主键
+     */
+//    @SaCheckPermission("order:orderReturnItem:query")
+    @GetMapping("/{id}")
+    public R<OrderReturnItemVo> getInfo(@NotNull(message = "主键不能为空")
+                                        @PathVariable("id") Long id) {
+        return R.ok(orderReturnItemService.queryById(id));
+    }
+
+    /**
+     * 新增退货商品明细
+     */
+//    @SaCheckPermission("order:orderReturnItem:add")
+    @Log(title = "退货商品明细", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody OrderReturnItemBo bo) {
+        return toAjax(orderReturnItemService.insertByBo(bo));
+    }
+
+    /**
+     * 修改退货商品明细
+     */
+//    @SaCheckPermission("order:orderReturnItem:edit")
+    @Log(title = "退货商品明细", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody OrderReturnItemBo bo) {
+        return toAjax(orderReturnItemService.updateByBo(bo));
+    }
+
+    /**
+     * 删除退货商品明细
+     *
+     * @param ids 主键串
+     */
+//    @SaCheckPermission("order:orderReturnItem:remove")
+    @Log(title = "退货商品明细", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(orderReturnItemService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 106 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderRevenueDetailController.java

@@ -0,0 +1,106 @@
+package org.dromara.order.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.order.domain.vo.OrderRevenueDetailVo;
+import org.dromara.order.domain.bo.OrderRevenueDetailBo;
+import org.dromara.order.service.IOrderRevenueDetailService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 收入单明细
+ * 前端访问路由地址为:/system/revenueDetail
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/revenueDetail")
+public class OrderRevenueDetailController extends BaseController {
+
+    private final IOrderRevenueDetailService orderRevenueDetailService;
+
+    /**
+     * 查询收入单明细列表
+     */
+//    @SaCheckPermission("order:revenueDetail:list")
+    @GetMapping("/list")
+    public TableDataInfo<OrderRevenueDetailVo> list(OrderRevenueDetailBo bo, PageQuery pageQuery) {
+        return orderRevenueDetailService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出收入单明细列表
+     */
+//    @SaCheckPermission("order:revenueDetail:export")
+    @Log(title = "收入单明细", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(OrderRevenueDetailBo bo, HttpServletResponse response) {
+        List<OrderRevenueDetailVo> list = orderRevenueDetailService.queryList(bo);
+        ExcelUtil.exportExcel(list, "收入单明细", OrderRevenueDetailVo.class, response);
+    }
+
+    /**
+     * 获取收入单明细详细信息
+     *
+     * @param id 主键
+     */
+//    @SaCheckPermission("order:revenueDetail:query")
+    @GetMapping("/{id}")
+    public R<OrderRevenueDetailVo> getInfo(@NotNull(message = "主键不能为空")
+                                           @PathVariable("id") Long id) {
+        return R.ok(orderRevenueDetailService.queryById(id));
+    }
+
+    /**
+     * 新增收入单明细
+     */
+//    @SaCheckPermission("order:revenueDetail:add")
+    @Log(title = "收入单明细", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody OrderRevenueDetailBo bo) {
+        return toAjax(orderRevenueDetailService.insertByBo(bo));
+    }
+
+    /**
+     * 修改收入单明细
+     */
+//    @SaCheckPermission("order:revenueDetail:edit")
+    @Log(title = "收入单明细", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody OrderRevenueDetailBo bo) {
+        return toAjax(orderRevenueDetailService.updateByBo(bo));
+    }
+
+    /**
+     * 删除收入单明细
+     *
+     * @param ids 主键串
+     */
+//    @SaCheckPermission("order:revenueDetail:remove")
+    @Log(title = "收入单明细", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(orderRevenueDetailService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 116 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderRevenueHeaderController.java

@@ -0,0 +1,116 @@
+package org.dromara.order.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.order.domain.vo.OrderRevenueHeaderVo;
+import org.dromara.order.domain.bo.OrderRevenueHeaderBo;
+import org.dromara.order.service.IOrderRevenueHeaderService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 收入单主
+ * 前端访问路由地址为:/system/revenueHeader
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/revenueHeader")
+public class OrderRevenueHeaderController extends BaseController {
+
+    private final IOrderRevenueHeaderService orderRevenueHeaderService;
+
+    /**
+     * 查询收入单主列表
+     */
+//    @SaCheckPermission("order:revenueHeader:list")
+    @GetMapping("/list")
+    public TableDataInfo<OrderRevenueHeaderVo> list(OrderRevenueHeaderBo bo, PageQuery pageQuery) {
+        return orderRevenueHeaderService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出收入单主列表
+     */
+//    @SaCheckPermission("order:revenueHeader:export")
+    @Log(title = "收入单主", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(OrderRevenueHeaderBo bo, HttpServletResponse response) {
+        List<OrderRevenueHeaderVo> list = orderRevenueHeaderService.queryList(bo);
+        ExcelUtil.exportExcel(list, "收入单主", OrderRevenueHeaderVo.class, response);
+    }
+
+    /**
+     * 获取收入单主详细信息
+     *
+     * @param id 主键
+     */
+//    @SaCheckPermission("order:revenueHeader:query")
+    @GetMapping("/{id}")
+    public R<OrderRevenueHeaderVo> getInfo(@NotNull(message = "主键不能为空")
+                                           @PathVariable("id") Long id) {
+        return R.ok(orderRevenueHeaderService.queryById(id));
+    }
+
+    /**
+     * 新增收入单主
+     */
+//    @SaCheckPermission("order:revenueHeader:add")
+    @Log(title = "收入单主", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody OrderRevenueHeaderBo bo) {
+        return toAjax(orderRevenueHeaderService.insertByBo(bo));
+    }
+
+    /**
+     * 修改收入单主
+     */
+//    @SaCheckPermission("order:revenueHeader:edit")
+    @Log(title = "收入单主", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody OrderRevenueHeaderBo bo) {
+        return toAjax(orderRevenueHeaderService.updateByBo(bo));
+    }
+
+    /**
+     * 删除收入单主
+     *
+     * @param ids 主键串
+     */
+//    @SaCheckPermission("order:revenueHeader:remove")
+    @Log(title = "收入单主", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(orderRevenueHeaderService.deleteWithValidByIds(List.of(ids), true));
+    }
+
+    /**
+     * 状态修改
+     */
+//    @SaCheckPermission("order:revenueHeader:edit")
+    @Log(title = "收入单主", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public R<Void> changeStatus(@RequestBody OrderRevenueHeaderBo bo) {
+        return toAjax(orderRevenueHeaderService.updateStatus(bo));
+    }
+}

+ 83 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderAssignment.java

@@ -0,0 +1,83 @@
+package org.dromara.order.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serial;
+
+/**
+ * 订单分配记录对象 order_assignment
+ *
+ * @author LionLi
+ * @date 2026-01-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("order_assignment")
+public class OrderAssignment extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 订单ID,关联订单表
+     */
+    private Long orderId;
+
+    private String orderNo;
+
+    /**
+     * 分配前平台
+     */
+    private String platformBefore;
+
+    /**
+     * 分配后平台
+     */
+    private String platformAfter;
+
+    /**
+     * 分配人
+     */
+    private Long assignedBy;
+
+    /**
+     * 分配时间
+     */
+    private Date assignTime;
+
+    /**
+     * 分配类型:手动/自动
+     */
+    private String assignType;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 分配原因
+     */
+    private String remark;
+
+
+}

+ 15 - 8
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderMain.java

@@ -35,6 +35,11 @@ public class OrderMain extends TenantEntity {
     @TableId(value = "id")
     private Long id;
 
+    /**
+     * 父订单id
+     */
+    private Long parentOrderId;
+
     /**
      * 订单编号
      */
@@ -181,14 +186,14 @@ public class OrderMain extends TenantEntity {
     private Date receivingTime;
 
     /**
-     * 已发货数量
+     * 拆单状态:0=未拆, 1=已拆出子单
      */
-    private Long shippedQuantity;
+    private String splitStatus;
 
     /**
-     * 未发货数量
+     * 是否为拆分子单:0=是, 1=否
      */
-    private Long unshippedQuantity;
+    private String isSplitChild;
 
     /**
      * 包裹数量
@@ -235,10 +240,6 @@ public class OrderMain extends TenantEntity {
      */
     private String orderCategory;
 
-    /**
-     * 商品编码
-     */
-    private String productCode;
 
     /**
      * 取消或异常原因
@@ -262,6 +263,12 @@ public class OrderMain extends TenantEntity {
 
     private String dataSource;
 
+    /*审核状态(0 待审核 1已通过 2已驳回)*/
+    private String checkStatus;
+
+    /*分配状态(0待分配 1已分配 )*/
+    private String assignmentStatus;
+
     /**
      * 删除标志(0代表存在 2代表删除)
      */

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

@@ -159,5 +159,7 @@ public class OrderProduct extends TenantEntity {
      */
     private String remark;
 
+    private String assignmentStatus;
+
 
 }

+ 13 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderProductAssignRule.java

@@ -0,0 +1,13 @@
+package org.dromara.order.domain;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class OrderProductAssignRule implements Serializable {
+
+    private Long itemId;          // order_product.id
+
+    private String targetPlatform; // 目标平台
+}

+ 220 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderReturn.java

@@ -0,0 +1,220 @@
+package org.dromara.order.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import java.math.BigDecimal;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serial;
+
+/**
+ * 退货主对象 order_return
+ *
+ * @author LionLi
+ * @date 2026-01-05
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("order_return")
+public class OrderReturn extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 原订单id
+     */
+    private Long orderId;
+
+    /**
+     * 原订单编号
+     */
+    private String orderNo;
+
+    /**
+     * 售后服务类型(如:退货、换货、仅退款等)
+     */
+    private String serviceType;
+
+    /**
+     * 退货申请时间
+     */
+    private Date returnTime;
+
+    /**
+     * 退货单号
+     */
+    private String returnNo;
+
+    /**
+     * 客户编号
+     */
+    private Long customerId;
+
+    /**
+     * 客户编号
+     */
+    private String customerNo;
+
+    /**
+     * 客户姓名
+     */
+    private String customerName;
+
+    /**
+     * 售后金额
+     */
+    private Long afterSaleAmount;
+
+    /**
+     * 退货订单状态
+     */
+    private String returnStatus;
+
+    /**
+     * 退货商品总数量
+     */
+    private Long returnProductNum;
+
+    /**
+     * 处理完成时间
+     */
+    private Date processingTime;
+
+    /**
+     * 退货原因id
+     */
+    private Long returnReasonId;
+
+    /**
+     * 退货原因
+     */
+    private String returnReason;
+
+    /**
+     * 问题描述
+     */
+    private String problemDescription;
+
+    /**
+     * 凭证图片URL
+     */
+    private String voucherPhoto;
+
+    /**
+     * 运费金额
+     */
+    private BigDecimal shippingFee;
+
+    /**
+     * 是否承担运费
+     */
+    private String isShippingFee;
+
+    /**
+     * 原订单总金额
+     */
+    private BigDecimal orderAmount;
+
+    /**
+     * 实际退款金额
+     */
+    private BigDecimal returnAmount;
+
+    /**
+     * 售后备注
+     */
+    private String afterSalesRemarks;
+
+    /**
+     * 退货方式(如:上门取件、自行寄回)
+     */
+    private String returnMethod;
+
+    /**
+     * 取件人姓名
+     */
+    private String chargebackName;
+
+    /**
+     * 取件联系电话
+     */
+    private String chargebackPhone;
+
+    /**
+     * 预约取件时间
+     */
+    private String chargebackPickupTime;
+
+    /**
+     * 取件省
+     */
+    private String chargebackProvincial;
+
+    /**
+     * 取件市
+     */
+    private String chargebackCity;
+
+    /**
+     * 取件区/县
+     */
+    private String chargebackCounty;
+
+    /**
+     * 取件区/县
+     */
+    private String provincialCityCounty;
+
+    /**
+     * 取件详细地址
+     */
+    private String chargebackAddress;
+
+    /**
+     * 推送状态(如:0-未推送, 1-已推送)
+     */
+    private String pushStatus;
+
+    /**
+     * 物流公司id
+     */
+    private Long logisticsId;
+
+    /**
+     * 物流公司名称
+     */
+    private String logisticsName;
+
+    /**
+     * 物流单号
+     */
+    private String logisticsNo;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 88 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderReturnItem.java

@@ -0,0 +1,88 @@
+package org.dromara.order.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import java.math.BigDecimal;
+
+import java.io.Serial;
+
+/**
+ * 退货商品明细对象 order_return_item
+ *
+ * @author LionLi
+ * @date 2026-01-05
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("order_return_item")
+public class OrderReturnItem extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 关联的退货单ID
+     */
+    private Long returnId;
+
+    /**
+     * 原订单明细ID
+     */
+    private Long orderProductId;
+
+    /**
+     * 商品SKU编码
+     */
+    private String productSku;
+
+    /**
+     * 商品名称
+     */
+    private String productName;
+
+    /**
+     * 本次退货数量
+     */
+    private Long returnQuantity;
+
+    /**
+     * 商品单价
+     */
+    private BigDecimal unitPrice;
+
+    /**
+     * 该项退货总金额
+     */
+    private BigDecimal totalAmount;
+
+    /**
+     * 该商品的具体退货原因
+     */
+    private String reasonDetail;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 103 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderRevenueDetail.java

@@ -0,0 +1,103 @@
+package org.dromara.order.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import java.math.BigDecimal;
+
+import java.io.Serial;
+
+/**
+ * 收入单明细对象 order_revenue_detail
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("order_revenue_detail")
+public class OrderRevenueDetail extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 关联的收入单id
+     */
+    private Long orderRevenueId;
+
+    /**
+     * 收入类型ID
+     */
+    private Long revenueId;
+
+    /**
+     * 收入明细编号
+     */
+    private String revenueCode;
+
+    /**
+     * 税率编码
+     */
+    private String taxRateCode;
+
+    /**
+     * 总金额
+     */
+    private BigDecimal totalAmount;
+
+    /**
+     * 单价
+     */
+    private BigDecimal unitPrice;
+
+    /**
+     * 数量
+     */
+    private Long quantity;
+
+    /**
+     * 平台分账金额
+     */
+    private Long platformAmount;
+
+    /**
+     * 平台单价
+     */
+    private BigDecimal platformPrice;
+
+    /**
+     * 订单类型
+     */
+    private String orderType;
+
+    /**
+     * 明细附件文件路径
+     */
+    private String revFile;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 113 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderRevenueHeader.java

@@ -0,0 +1,113 @@
+package org.dromara.order.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 收入单主对象 order_revenue_header
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("order_revenue_header")
+public class OrderRevenueHeader extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 收入大类
+     */
+    private String revenueType;
+
+    /**
+     * 收入单号
+     */
+    private String orderRevenueCode;
+
+    /**
+     * 关联的主订单号
+     */
+    private String incomeOrderCode;
+
+    /**
+     * 其他收入子类型
+     */
+    private String otherRevenueType;
+
+    /**
+     * 客户id
+     */
+    private Long customerId;
+
+    private String customerName;
+
+    /*客户编号*/
+    private String customerCode;
+
+    private String supplierName;
+
+    private String companyName;
+
+    private String businessDept;
+
+    private String businessStaff;
+
+    private String customerService;
+
+
+    /**
+     * 供应商id
+     */
+    private Long supplierId;
+
+    /**
+     * 是否含税
+     */
+    private String isPrwTax;
+
+    /**
+     * 币种
+     */
+    private Long currencyId;
+
+    /**
+     * 推送状态
+     */
+    private String pushStatus;
+
+    /**
+     * 附件文件路径或URL
+     */
+    private String orderFile;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 78 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderAssignmentBo.java

@@ -0,0 +1,78 @@
+package org.dromara.order.domain.bo;
+
+import org.dromara.order.domain.OrderAssignment;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 订单分配记录业务对象 order_assignment
+ *
+ * @author LionLi
+ * @date 2026-01-07
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = OrderAssignment.class, reverseConvertGenerate = false)
+public class OrderAssignmentBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 订单ID,关联订单表
+     */
+    private Long orderId;
+
+    private String orderNo;
+
+    /**
+     * 分配前平台
+     */
+    private String platformBefore;
+
+    /**
+     * 分配后平台
+     */
+    @NotBlank(message = "分配后平台不能为空", groups = {AddGroup.class, EditGroup.class})
+    private String platformAfter;
+
+    /**
+     * 分配人
+     */
+    private Long assignedBy;
+
+    /**
+     * 分配时间
+     */
+    private Date assignTime;
+
+    /**
+     * 分配类型:手动/自动
+     */
+    private String assignType;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    private String orderIds;
+
+    /**
+     * 分配原因
+     */
+    private String remark;
+
+
+}

+ 20 - 4
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderMainBo.java

@@ -31,6 +31,11 @@ public class OrderMainBo extends BaseEntity {
      */
     private Long id;
 
+    /**
+     * 父订单id
+     */
+    private Long parentOrderId;
+
     /**
      * 订单编号
      */
@@ -182,14 +187,14 @@ public class OrderMainBo extends BaseEntity {
     private Date receivingTime;
 
     /**
-     * 已发货数量
+     * 拆单状态:0=未拆, 1=已拆出子单
      */
-    private Long shippedQuantity;
+    private String splitStatus;
 
     /**
-     * 未发货数量
+     * 是否为拆分子单:0=是, 1=否
      */
-    private Long unshippedQuantity;
+    private String isSplitChild;
 
     /**
      * 包裹数量
@@ -269,6 +274,17 @@ public class OrderMainBo extends BaseEntity {
      */
     private String remark;
 
+    /*审核状态(0 待审核 1已通过 2已驳回)*/
+    private String checkStatus;
+
+    /*分配状态(0待分配 1已分配 )*/
+    private String assignmentStatus;
+
+    /**
+     * 订单状态
+     */
+    private String orderStatuses;
+
     List<OrderProductBo> orderProductBos;
 
 

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

@@ -147,6 +147,8 @@ public class OrderProductBo extends BaseEntity {
 
     private String dataSource;
 
+    private String assignmentStatus;
+
     /**
      * 备注
      */

+ 217 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderReturnBo.java

@@ -0,0 +1,217 @@
+package org.dromara.order.domain.bo;
+
+import org.dromara.order.domain.OrderReturn;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 退货主业务对象 order_return
+ *
+ * @author LionLi
+ * @date 2026-01-05
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = OrderReturn.class, reverseConvertGenerate = false)
+public class OrderReturnBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 原订单id
+     */
+    private Long orderId;
+
+    /**
+     * 原订单编号
+     */
+    private String orderNo;
+
+    /**
+     * 售后服务类型(如:退货、换货、仅退款等)
+     */
+    private String serviceType;
+
+    /**
+     * 退货申请时间
+     */
+    private Date returnTime;
+
+    /**
+     * 退货单号
+     */
+    private String returnNo;
+
+    /**
+     * 客户编号
+     */
+    private Long customerId;
+
+    /**
+     * 客户编号
+     */
+    private String customerNo;
+
+    /**
+     * 客户姓名
+     */
+    private String customerName;
+
+    /**
+     * 售后金额
+     */
+    private Long afterSaleAmount;
+
+    /**
+     * 退货订单状态
+     */
+    private String returnStatus;
+
+    /**
+     * 退货商品总数量
+     */
+    private Long returnProductNum;
+
+    /**
+     * 处理完成时间
+     */
+    private Date processingTime;
+
+    /**
+     * 退货原因id
+     */
+    private Long returnReasonId;
+
+    /**
+     * 退货原因
+     */
+    private String returnReason;
+
+    /**
+     * 问题描述
+     */
+    private String problemDescription;
+
+    /**
+     * 凭证图片URL
+     */
+    private String voucherPhoto;
+
+    /**
+     * 运费金额
+     */
+    private BigDecimal shippingFee;
+
+    /**
+     * 是否承担运费
+     */
+    private String isShippingFee;
+
+    /**
+     * 原订单总金额
+     */
+    private BigDecimal orderAmount;
+
+    /**
+     * 实际退款金额
+     */
+    private BigDecimal returnAmount;
+
+    /**
+     * 售后备注
+     */
+    private String afterSalesRemarks;
+
+    /**
+     * 退货方式(如:上门取件、自行寄回)
+     */
+    private String returnMethod;
+
+    /**
+     * 取件人姓名
+     */
+    private String chargebackName;
+
+    /**
+     * 取件联系电话
+     */
+    private String chargebackPhone;
+
+    /**
+     * 预约取件时间
+     */
+    private String chargebackPickupTime;
+
+    /**
+     * 取件省
+     */
+    private String chargebackProvincial;
+
+    /**
+     * 取件市
+     */
+    private String chargebackCity;
+
+    /**
+     * 取件区/县
+     */
+    private String chargebackCounty;
+
+    /**
+     * 取件区/县
+     */
+    private String provincialCityCounty;
+
+    /**
+     * 取件详细地址
+     */
+    private String chargebackAddress;
+
+    /**
+     * 推送状态(如:0-未推送, 1-已推送)
+     */
+    private String pushStatus;
+
+    /**
+     * 物流公司id
+     */
+    private Long logisticsId;
+
+    /**
+     * 物流公司名称
+     */
+    private String logisticsName;
+
+    /**
+     * 物流单号
+     */
+    private String logisticsNo;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    private List<OrderReturnItemBo> orderReturnItemList;
+
+
+}

+ 80 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderReturnItemBo.java

@@ -0,0 +1,80 @@
+package org.dromara.order.domain.bo;
+
+import org.dromara.order.domain.OrderReturnItem;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+import java.math.BigDecimal;
+
+/**
+ * 退货商品明细业务对象 order_return_item
+ *
+ * @author LionLi
+ * @date 2026-01-05
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = OrderReturnItem.class, reverseConvertGenerate = false)
+public class OrderReturnItemBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 关联的退货单ID
+     */
+    private Long returnId;
+
+    /**
+     * 原订单明细ID
+     */
+    private Long orderProductId;
+
+    /**
+     * 商品SKU编码
+     */
+    private String productSku;
+
+    /**
+     * 商品名称
+     */
+    private String productName;
+
+    /**
+     * 本次退货数量
+     */
+    private Long returnQuantity;
+
+    /**
+     * 商品单价
+     */
+    private BigDecimal unitPrice;
+
+    /**
+     * 该项退货总金额
+     */
+    private BigDecimal totalAmount;
+
+    /**
+     * 该商品的具体退货原因
+     */
+    private String reasonDetail;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 95 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderRevenueDetailBo.java

@@ -0,0 +1,95 @@
+package org.dromara.order.domain.bo;
+
+import org.dromara.order.domain.OrderRevenueDetail;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+import java.math.BigDecimal;
+
+/**
+ * 收入单明细业务对象 order_revenue_detail
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = OrderRevenueDetail.class, reverseConvertGenerate = false)
+public class OrderRevenueDetailBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 关联的收入单id
+     */
+    private Long orderRevenueId;
+
+    /**
+     * 收入类型ID
+     */
+    private Long revenueId;
+
+    /**
+     * 收入明细编号
+     */
+    private String revenueCode;
+
+    /**
+     * 税率编码
+     */
+    private String taxRateCode;
+
+    /**
+     * 总金额
+     */
+    private BigDecimal totalAmount;
+
+    /**
+     * 单价
+     */
+    private BigDecimal unitPrice;
+
+    /**
+     * 数量
+     */
+    private Long quantity;
+
+    /**
+     * 平台分账金额
+     */
+    private Long platformAmount;
+
+    /**
+     * 平台单价
+     */
+    private BigDecimal platformPrice;
+
+    /**
+     * 订单类型
+     */
+    private String orderType;
+
+    /**
+     * 明细附件文件路径
+     */
+    private String revFile;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 112 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderRevenueHeaderBo.java

@@ -0,0 +1,112 @@
+package org.dromara.order.domain.bo;
+
+import org.dromara.order.domain.OrderRevenueDetail;
+import org.dromara.order.domain.OrderRevenueHeader;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+import java.util.List;
+
+/**
+ * 收入单主业务对象 order_revenue_header
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = OrderRevenueHeader.class, reverseConvertGenerate = false)
+public class OrderRevenueHeaderBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 收入大类
+     */
+    private String revenueType;
+
+    /**
+     * 收入单号
+     */
+    private String orderRevenueCode;
+
+    /**
+     * 关联的主订单号
+     */
+    private String incomeOrderCode;
+
+    /**
+     * 其他收入子类型
+     */
+    private String otherRevenueType;
+
+    /**
+     * 客户id
+     */
+    private Long customerId;
+
+    /**
+     * 客户名称
+     */
+    private String customerName;
+
+    /**
+     * 供应商id
+     */
+    private Long supplierId;
+
+    /**
+     * 是否含税
+     */
+    private String isPrwTax;
+
+    /**
+     * 币种
+     */
+    private Long currencyId;
+
+    /**
+     * 推送状态
+     */
+    private String pushStatus;
+
+    /**
+     * 附件文件路径或URL
+     */
+    private String orderFile;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /*客户编号*/
+    private String customerCode;
+
+    private String supplierName;
+
+    private String companyName;
+
+    private String businessDept;
+
+    private String businessStaff;
+
+    private String customerService;
+
+    private List<OrderRevenueDetailBo> orderRevenueDetails;
+
+
+}

+ 18 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderSplitAssignBo.java

@@ -0,0 +1,18 @@
+package org.dromara.order.domain.bo;
+
+import lombok.Data;
+import org.dromara.order.domain.OrderProductAssignRule;
+
+import java.util.List;
+
+@Data
+public class OrderSplitAssignBo {
+
+    private Long orderId; // 父订单ID
+
+    private List<OrderProductAssignRule> itemRules; // 商品分配规则
+
+    private String remark;
+
+
+}

+ 91 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderAssignmentVo.java

@@ -0,0 +1,91 @@
+package org.dromara.order.domain.vo;
+
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.dromara.order.domain.OrderAssignment;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 订单分配记录视图对象 order_assignment
+ *
+ * @author LionLi
+ * @date 2026-01-07
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = OrderAssignment.class)
+public class OrderAssignmentVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 订单ID,关联订单表
+     */
+    @ExcelProperty(value = "订单ID,关联订单表")
+    private Long orderId;
+
+    private String orderNo;
+
+    /**
+     * 分配前平台
+     */
+    @ExcelProperty(value = "分配前平台")
+    private String platformBefore;
+
+    /**
+     * 分配后平台
+     */
+    @ExcelProperty(value = "分配后平台")
+    private String platformAfter;
+
+    /**
+     * 分配人
+     */
+    @ExcelProperty(value = "分配人")
+    private Long assignedBy;
+
+    /**
+     * 分配时间
+     */
+    @ExcelProperty(value = "分配时间")
+    private Date assignTime;
+
+    /**
+     * 分配类型:手动/自动
+     */
+    @ExcelProperty(value = "分配类型:手动/自动")
+    private String assignType;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
+    private String status;
+
+    /**
+     * 分配原因
+     */
+    @ExcelProperty(value = "分配原因")
+    private String remark;
+
+
+}

+ 27 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderMainVo.java

@@ -38,6 +38,11 @@ public class OrderMainVo implements Serializable {
     @ExcelProperty(value = "主键ID")
     private Long id;
 
+    /**
+     * 父订单id
+     */
+    private Long parentOrderId;
+
     /**
      * 订单编号
      */
@@ -325,6 +330,28 @@ public class OrderMainVo implements Serializable {
 
     private String dataSource;
 
+    /*审核状态(0 待审核 1已通过 2已驳回)*/
+    private String checkStatus;
+
+    /*分配状态(0待分配 1已分配 )*/
+    private String assignmentStatus;
+
+    /**
+     * 拆单状态:0=未拆, 1=已拆出子单
+     */
+    private Long splitStatus;
+
+    /**
+     * 是否为拆分子单:0=是, 1=否
+     */
+    private Long isSplitChild;
+
+    private String platformCode;
+
+    private String createTime;
+
+    private String customerName;
+
     private List<OrderProductVo> orderProductList;
 
     private List<OrderDeliverProductVo> deliverProductList;

+ 5 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderProductVo.java

@@ -191,6 +191,11 @@ public class OrderProductVo implements Serializable {
     @ExcelProperty(value = "备注")
     private String remark;
 
+
+    private String platformCode;
+
+    private String assignmentStatus;
+
     private String dataSource;
 
 

+ 100 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderReturnItemVo.java

@@ -0,0 +1,100 @@
+package org.dromara.order.domain.vo;
+
+import java.math.BigDecimal;
+import org.dromara.order.domain.OrderReturnItem;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 退货商品明细视图对象 order_return_item
+ *
+ * @author LionLi
+ * @date 2026-01-05
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = OrderReturnItem.class)
+public class OrderReturnItemVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 关联的退货单ID
+     */
+    @ExcelProperty(value = "关联的退货单ID")
+    private Long returnId;
+
+    /**
+     * 原订单明细ID
+     */
+    @ExcelProperty(value = "原订单明细ID")
+    private Long orderProductId;
+
+    /**
+     * 商品SKU编码
+     */
+    @ExcelProperty(value = "商品SKU编码")
+    private String productSku;
+
+    /**
+     * 商品名称
+     */
+    @ExcelProperty(value = "商品名称")
+    private String productName;
+
+    /**
+     * 本次退货数量
+     */
+    @ExcelProperty(value = "本次退货数量")
+    private Long returnQuantity;
+
+    /**
+     * 商品单价
+     */
+    @ExcelProperty(value = "商品单价")
+    private BigDecimal unitPrice;
+
+    /**
+     * 该项退货总金额
+     */
+    @ExcelProperty(value = "该项退货总金额")
+    private BigDecimal totalAmount;
+
+    /**
+     * 该商品的具体退货原因
+     */
+    @ExcelProperty(value = "该商品的具体退货原因")
+    private String reasonDetail;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
+    private String status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 267 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderReturnVo.java

@@ -0,0 +1,267 @@
+package org.dromara.order.domain.vo;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.dromara.order.domain.OrderReturn;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import org.dromara.order.domain.bo.OrderReturnItemBo;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * 退货主视图对象 order_return
+ *
+ * @author LionLi
+ * @date 2026-01-05
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = OrderReturn.class)
+public class OrderReturnVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 原订单id
+     */
+    @ExcelProperty(value = "原订单id")
+    private Long orderId;
+
+    /**
+     * 原订单编号
+     */
+    @ExcelProperty(value = "原订单编号")
+    private String orderNo;
+
+    /**
+     * 售后服务类型(如:退货、换货、仅退款等)
+     */
+    @ExcelProperty(value = "售后服务类型", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "如=:退货、换货、仅退款等")
+    private String serviceType;
+
+    /**
+     * 退货申请时间
+     */
+    @ExcelProperty(value = "退货申请时间")
+    private Date returnTime;
+
+    /**
+     * 退货单号
+     */
+    @ExcelProperty(value = "退货单号")
+    private String returnNo;
+
+    /**
+     * 客户编号
+     */
+    @ExcelProperty(value = "客户编号")
+    private Long customerId;
+
+    /**
+     * 客户编号
+     */
+    @ExcelProperty(value = "客户编号")
+    private String customerNo;
+
+    /**
+     * 客户姓名
+     */
+    @ExcelProperty(value = "客户姓名")
+    private String customerName;
+
+    /**
+     * 售后金额
+     */
+    @ExcelProperty(value = "售后金额")
+    private Long afterSaleAmount;
+
+    /**
+     * 退货订单状态
+     */
+    @ExcelProperty(value = "退货订单状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "return_order_status")
+    private String returnStatus;
+
+    /**
+     * 退货商品总数量
+     */
+    @ExcelProperty(value = "退货商品总数量")
+    private Long returnProductNum;
+
+    /**
+     * 处理完成时间
+     */
+    @ExcelProperty(value = "处理完成时间")
+    private Date processingTime;
+
+    /**
+     * 退货原因id
+     */
+    @ExcelProperty(value = "退货原因id")
+    private Long returnReasonId;
+
+    /**
+     * 退货原因
+     */
+    @ExcelProperty(value = "退货原因")
+    private String returnReason;
+
+    /**
+     * 问题描述
+     */
+    @ExcelProperty(value = "问题描述")
+    private String problemDescription;
+
+    /**
+     * 凭证图片URL
+     */
+    @ExcelProperty(value = "凭证图片URL")
+    private String voucherPhoto;
+
+    /**
+     * 运费金额
+     */
+    @ExcelProperty(value = "运费金额")
+    private BigDecimal shippingFee;
+
+    /**
+     * 是否承担运费
+     */
+    @ExcelProperty(value = "是否承担运费")
+    private String isShippingFee;
+
+    /**
+     * 原订单总金额
+     */
+    @ExcelProperty(value = "原订单总金额")
+    private BigDecimal orderAmount;
+
+    /**
+     * 实际退款金额
+     */
+    @ExcelProperty(value = "实际退款金额")
+    private BigDecimal returnAmount;
+
+    /**
+     * 售后备注
+     */
+    @ExcelProperty(value = "售后备注")
+    private String afterSalesRemarks;
+
+    /**
+     * 退货方式(如:上门取件、自行寄回)
+     */
+    @ExcelProperty(value = "退货方式", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "如=:上门取件、自行寄回")
+    private String returnMethod;
+
+    /**
+     * 取件人姓名
+     */
+    @ExcelProperty(value = "取件人姓名")
+    private String chargebackName;
+
+    /**
+     * 取件联系电话
+     */
+    @ExcelProperty(value = "取件联系电话")
+    private String chargebackPhone;
+
+    /**
+     * 预约取件时间
+     */
+    @ExcelProperty(value = "预约取件时间")
+    private String chargebackPickupTime;
+
+    /**
+     * 取件省
+     */
+    @ExcelProperty(value = "取件省")
+    private String chargebackProvincial;
+
+    /**
+     * 取件市
+     */
+    @ExcelProperty(value = "取件市")
+    private String chargebackCity;
+
+    /**
+     * 取件区/县
+     */
+    @ExcelProperty(value = "取件区/县")
+    private String chargebackCounty;
+
+    /**
+     * 取件区/县
+     */
+    @ExcelProperty(value = "取件区/县")
+    private String provincialCityCounty;
+
+    /**
+     * 取件详细地址
+     */
+    @ExcelProperty(value = "取件详细地址")
+    private String chargebackAddress;
+
+    /**
+     * 推送状态(如:0-未推送, 1-已推送)
+     */
+    @ExcelProperty(value = "推送状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "如=:0-未推送,,1=-已推送")
+    private String pushStatus;
+
+    /**
+     * 物流公司id
+     */
+    @ExcelProperty(value = "物流公司id")
+    private Long logisticsId;
+
+    /**
+     * 物流公司名称
+     */
+    @ExcelProperty(value = "物流公司名称")
+    private String logisticsName;
+
+    /**
+     * 物流单号
+     */
+    @ExcelProperty(value = "物流单号")
+    private String logisticsNo;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
+    private String status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+    private Date createTime;
+
+    private List<OrderReturnItemVo> orderReturnItemList;
+
+}

+ 118 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderRevenueDetailVo.java

@@ -0,0 +1,118 @@
+package org.dromara.order.domain.vo;
+
+import java.math.BigDecimal;
+import org.dromara.order.domain.OrderRevenueDetail;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 收入单明细视图对象 order_revenue_detail
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = OrderRevenueDetail.class)
+public class OrderRevenueDetailVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 关联的收入单id
+     */
+    @ExcelProperty(value = "关联的收入单id")
+    private Long orderRevenueId;
+
+    /**
+     * 收入类型ID
+     */
+    @ExcelProperty(value = "收入类型ID")
+    private Long revenueId;
+
+    /**
+     * 收入明细编号
+     */
+    @ExcelProperty(value = "收入明细编号")
+    private String revenueCode;
+
+    /**
+     * 税率编码
+     */
+    @ExcelProperty(value = "税率编码")
+    private String taxRateCode;
+
+    /**
+     * 总金额
+     */
+    @ExcelProperty(value = "总金额")
+    private BigDecimal totalAmount;
+
+    /**
+     * 单价
+     */
+    @ExcelProperty(value = "单价")
+    private BigDecimal unitPrice;
+
+    /**
+     * 数量
+     */
+    @ExcelProperty(value = "数量")
+    private Long quantity;
+
+    /**
+     * 平台分账金额
+     */
+    @ExcelProperty(value = "平台分账金额")
+    private Long platformAmount;
+
+    /**
+     * 平台单价
+     */
+    @ExcelProperty(value = "平台单价")
+    private BigDecimal platformPrice;
+
+    /**
+     * 订单类型
+     */
+    @ExcelProperty(value = "订单类型")
+    private String orderType;
+
+    /**
+     * 明细附件文件路径
+     */
+    @ExcelProperty(value = "明细附件文件路径")
+    private String revFile;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
+    private String status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 138 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderRevenueHeaderVo.java

@@ -0,0 +1,138 @@
+package org.dromara.order.domain.vo;
+
+import org.dromara.order.domain.OrderRevenueDetail;
+import org.dromara.order.domain.OrderRevenueHeader;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * 收入单主视图对象 order_revenue_header
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = OrderRevenueHeader.class)
+public class OrderRevenueHeaderVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 收入大类
+     */
+    @ExcelProperty(value = "收入大类")
+    private String revenueType;
+
+    /**
+     * 收入单号
+     */
+    @ExcelProperty(value = "收入单号")
+    private String orderRevenueCode;
+
+    /**
+     * 关联的主订单号
+     */
+    @ExcelProperty(value = "关联的主订单号")
+    private String incomeOrderCode;
+
+    /**
+     * 其他收入子类型
+     */
+    @ExcelProperty(value = "其他收入子类型")
+    private String otherRevenueType;
+
+    /**
+     * 客户id
+     */
+    @ExcelProperty(value = "客户id")
+    private Long customerId;
+
+    /**
+     * 客户名称
+     */
+    private String customerName;
+
+    /**
+     * 供应商id
+     */
+    @ExcelProperty(value = "供应商id")
+    private Long supplierId;
+
+    /**
+     * 是否含税
+     */
+    @ExcelProperty(value = "是否含税", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_platform_yes_no")
+    private String isPrwTax;
+
+    /**
+     * 币种
+     */
+    @ExcelProperty(value = "币种")
+    private Long currencyId;
+
+    /**
+     * 推送状态
+     */
+    @ExcelProperty(value = "推送状态")
+    private String pushStatus;
+
+    /**
+     * 附件文件路径或URL
+     */
+    @ExcelProperty(value = "附件文件路径或URL")
+    private String orderFile;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
+    private String status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+    private Date createTime;
+
+    /*客户编号*/
+    private String customerCode;
+
+    private String supplierName;
+
+    private String companyName;
+
+    private String businessDept;
+
+    private String businessStaff;
+
+    private String customerService;
+
+    private BigDecimal totalAmount;
+
+    private List<OrderRevenueDetailVo> orderRevenueDetailList;
+
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderAssignmentMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.order.mapper;
+
+import org.dromara.order.domain.OrderAssignment;
+import org.dromara.order.domain.vo.OrderAssignmentVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 订单分配记录Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-07
+ */
+public interface OrderAssignmentMapper extends BaseMapperPlus<OrderAssignment, OrderAssignmentVo> {
+
+}

+ 13 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderProductMapper.java

@@ -19,4 +19,17 @@ public interface OrderProductMapper extends BaseMapperPlus<OrderProduct, OrderPr
     List<OrderProductVo> selectProductsWithDelivered(@Param("orderId") Long orderId);
 
     OrderQuantitySummary selectOrderAndDeliveredQuantity(@Param("orderId") Long orderId);
+
+    void updatePlatformAndStatusByOrderIds(
+        @Param("orderIds") List<Long> orderIds,
+        @Param("platformCode") String platformCode,
+        @Param("assignmentStatus") String assignmentStatus
+    );
+
+    void updateForSplitAssign(
+        @Param("itemIds") List<Long> itemIds,
+        @Param("newOrderId") Long newOrderId,
+        @Param("platformCode") String platformCode,
+        @Param("assignmentStatus") String assignmentStatus
+    );
 }

+ 18 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderReturnItemMapper.java

@@ -0,0 +1,18 @@
+package org.dromara.order.mapper;
+
+import org.apache.dubbo.remoting.http12.rest.Param;
+import org.dromara.order.domain.OrderReturnItem;
+import org.dromara.order.domain.vo.OrderReturnItemVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 退货商品明细Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-05
+ */
+public interface OrderReturnItemMapper extends BaseMapperPlus<OrderReturnItem, OrderReturnItemVo> {
+
+    void deleteByOrderReturnId(@Param("orderReturnId") Long orderReturnId);
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderReturnMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.order.mapper;
+
+import org.dromara.order.domain.OrderReturn;
+import org.dromara.order.domain.vo.OrderReturnVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 退货主Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-05
+ */
+public interface OrderReturnMapper extends BaseMapperPlus<OrderReturn, OrderReturnVo> {
+
+}

+ 21 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderRevenueDetailMapper.java

@@ -0,0 +1,21 @@
+package org.dromara.order.mapper;
+
+import org.apache.dubbo.remoting.http12.rest.Param;
+import org.dromara.order.domain.OrderRevenueDetail;
+import org.dromara.order.domain.vo.OrderDeliverProductVo;
+import org.dromara.order.domain.vo.OrderRevenueDetailVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+import java.util.List;
+
+/**
+ * 收入单明细Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+public interface OrderRevenueDetailMapper extends BaseMapperPlus<OrderRevenueDetail, OrderRevenueDetailVo> {
+
+    void deleteByRevenueHeadId(@Param("orderRevenueId") Long orderRevenueId);
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderRevenueHeaderMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.order.mapper;
+
+import org.dromara.order.domain.OrderRevenueHeader;
+import org.dromara.order.domain.vo.OrderRevenueHeaderVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 收入单主Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+public interface OrderRevenueHeaderMapper extends BaseMapperPlus<OrderRevenueHeader, OrderRevenueHeaderVo> {
+
+}

+ 73 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderAssignmentService.java

@@ -0,0 +1,73 @@
+package org.dromara.order.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.order.domain.OrderAssignment;
+import org.dromara.order.domain.bo.OrderSplitAssignBo;
+import org.dromara.order.domain.vo.OrderAssignmentVo;
+import org.dromara.order.domain.bo.OrderAssignmentBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 订单分配记录Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-07
+ */
+public interface IOrderAssignmentService extends IService<OrderAssignment> {
+
+    /**
+     * 查询订单分配记录
+     *
+     * @param id 主键
+     * @return 订单分配记录
+     */
+    OrderAssignmentVo queryById(Long id);
+
+    /**
+     * 分页查询订单分配记录列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 订单分配记录分页列表
+     */
+    TableDataInfo<OrderAssignmentVo> queryPageList(OrderAssignmentBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的订单分配记录列表
+     *
+     * @param bo 查询条件
+     * @return 订单分配记录列表
+     */
+    List<OrderAssignmentVo> queryList(OrderAssignmentBo bo);
+
+    /**
+     * 新增订单分配记录
+     *
+     * @param bo 订单分配记录
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(OrderAssignmentBo bo);
+
+    Boolean splitAssign(OrderSplitAssignBo bo);
+
+    /**
+     * 修改订单分配记录
+     *
+     * @param bo 订单分配记录
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(OrderAssignmentBo bo);
+
+    /**
+     * 校验并批量删除订单分配记录信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 9 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderMainService.java

@@ -64,6 +64,15 @@ public interface IOrderMainService extends IService<OrderMain> {
 
     int updateStatus(OrderMainBo bo);
 
+
+    /**
+     * 修改订单审核状态
+     *
+     * @param bo 订单主信息
+     * @return 是否修改成功
+     */
+    int updateCheckStatus(OrderMainBo bo);
+
     /**
      * 校验并批量删除订单主信息信息
      *

+ 70 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderReturnItemService.java

@@ -0,0 +1,70 @@
+package org.dromara.order.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.order.domain.OrderReturnItem;
+import org.dromara.order.domain.vo.OrderReturnItemVo;
+import org.dromara.order.domain.bo.OrderReturnItemBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 退货商品明细Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-05
+ */
+public interface IOrderReturnItemService extends IService<OrderReturnItem>{
+
+    /**
+     * 查询退货商品明细
+     *
+     * @param id 主键
+     * @return 退货商品明细
+     */
+    OrderReturnItemVo queryById(Long id);
+
+    /**
+     * 分页查询退货商品明细列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 退货商品明细分页列表
+     */
+    TableDataInfo<OrderReturnItemVo> queryPageList(OrderReturnItemBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的退货商品明细列表
+     *
+     * @param bo 查询条件
+     * @return 退货商品明细列表
+     */
+    List<OrderReturnItemVo> queryList(OrderReturnItemBo bo);
+
+    /**
+     * 新增退货商品明细
+     *
+     * @param bo 退货商品明细
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(OrderReturnItemBo bo);
+
+    /**
+     * 修改退货商品明细
+     *
+     * @param bo 退货商品明细
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(OrderReturnItemBo bo);
+
+    /**
+     * 校验并批量删除退货商品明细信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 70 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderReturnService.java

@@ -0,0 +1,70 @@
+package org.dromara.order.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.order.domain.OrderReturn;
+import org.dromara.order.domain.vo.OrderReturnVo;
+import org.dromara.order.domain.bo.OrderReturnBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 退货主Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-05
+ */
+public interface IOrderReturnService extends IService<OrderReturn>{
+
+    /**
+     * 查询退货主
+     *
+     * @param id 主键
+     * @return 退货主
+     */
+    OrderReturnVo queryById(Long id);
+
+    /**
+     * 分页查询退货主列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 退货主分页列表
+     */
+    TableDataInfo<OrderReturnVo> queryPageList(OrderReturnBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的退货主列表
+     *
+     * @param bo 查询条件
+     * @return 退货主列表
+     */
+    List<OrderReturnVo> queryList(OrderReturnBo bo);
+
+    /**
+     * 新增退货主
+     *
+     * @param bo 退货主
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(OrderReturnBo bo);
+
+    /**
+     * 修改退货主
+     *
+     * @param bo 退货主
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(OrderReturnBo bo);
+
+    /**
+     * 校验并批量删除退货主信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 70 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderRevenueDetailService.java

@@ -0,0 +1,70 @@
+package org.dromara.order.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.order.domain.OrderRevenueDetail;
+import org.dromara.order.domain.vo.OrderRevenueDetailVo;
+import org.dromara.order.domain.bo.OrderRevenueDetailBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 收入单明细Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+public interface IOrderRevenueDetailService extends IService<OrderRevenueDetail>{
+
+    /**
+     * 查询收入单明细
+     *
+     * @param id 主键
+     * @return 收入单明细
+     */
+    OrderRevenueDetailVo queryById(Long id);
+
+    /**
+     * 分页查询收入单明细列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 收入单明细分页列表
+     */
+    TableDataInfo<OrderRevenueDetailVo> queryPageList(OrderRevenueDetailBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的收入单明细列表
+     *
+     * @param bo 查询条件
+     * @return 收入单明细列表
+     */
+    List<OrderRevenueDetailVo> queryList(OrderRevenueDetailBo bo);
+
+    /**
+     * 新增收入单明细
+     *
+     * @param bo 收入单明细
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(OrderRevenueDetailBo bo);
+
+    /**
+     * 修改收入单明细
+     *
+     * @param bo 收入单明细
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(OrderRevenueDetailBo bo);
+
+    /**
+     * 校验并批量删除收入单明细信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 75 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderRevenueHeaderService.java

@@ -0,0 +1,75 @@
+package org.dromara.order.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.order.domain.OrderRevenueHeader;
+import org.dromara.order.domain.vo.OrderRevenueHeaderVo;
+import org.dromara.order.domain.bo.OrderRevenueHeaderBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 收入单主Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+public interface IOrderRevenueHeaderService extends IService<OrderRevenueHeader> {
+
+    /**
+     * 查询收入单主
+     *
+     * @param id 主键
+     * @return 收入单主
+     */
+    OrderRevenueHeaderVo queryById(Long id);
+
+    /**
+     * 分页查询收入单主列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 收入单主分页列表
+     */
+    TableDataInfo<OrderRevenueHeaderVo> queryPageList(OrderRevenueHeaderBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的收入单主列表
+     *
+     * @param bo 查询条件
+     * @return 收入单主列表
+     */
+    List<OrderRevenueHeaderVo> queryList(OrderRevenueHeaderBo bo);
+
+    /**
+     * 新增收入单主
+     *
+     * @param bo 收入单主
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(OrderRevenueHeaderBo bo);
+
+    /**
+     * 修改收入单主
+     *
+     * @param bo 收入单主
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(OrderRevenueHeaderBo bo);
+
+    /**
+     * 修改状态
+     */
+    int updateStatus(OrderRevenueHeaderBo bo);
+
+    /**
+     * 校验并批量删除收入单主信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 373 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderAssignmentServiceImpl.java

@@ -0,0 +1,373 @@
+package org.dromara.order.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.context.PlatformContext;
+import org.dromara.common.core.enums.OrderAssignStatus;
+import org.dromara.common.core.enums.OrderSplitStatus;
+import org.dromara.common.core.enums.SysPlatformCode;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.PlatformContextUtil;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.redis.utils.SequenceUtils;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.order.domain.OrderAssignment;
+import org.dromara.order.domain.OrderMain;
+import org.dromara.order.domain.OrderProduct;
+import org.dromara.order.domain.OrderProductAssignRule;
+import org.dromara.order.domain.bo.OrderAssignmentBo;
+import org.dromara.order.domain.bo.OrderSplitAssignBo;
+import org.dromara.order.domain.vo.OrderAssignmentVo;
+import org.dromara.order.domain.vo.OrderMainVo;
+import org.dromara.order.mapper.OrderAssignmentMapper;
+import org.dromara.order.mapper.OrderMainMapper;
+import org.dromara.order.mapper.OrderProductMapper;
+import org.dromara.order.service.IOrderAssignmentService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.Duration;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 订单分配记录Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-07
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class OrderAssignmentServiceImpl extends ServiceImpl<OrderAssignmentMapper, OrderAssignment> implements IOrderAssignmentService {
+
+    private static final String CHILD_ORDER_NO_KEY = "order_main:child_order_no";
+
+    private final OrderAssignmentMapper baseMapper;
+
+    private final OrderMainMapper orderMainMapper;
+
+    private final OrderProductMapper orderProductMapper;
+
+    /**
+     * 查询订单分配记录
+     *
+     * @param id 主键
+     * @return 订单分配记录
+     */
+    @Override
+    public OrderAssignmentVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询订单分配记录列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 订单分配记录分页列表
+     */
+    @Override
+    public TableDataInfo<OrderAssignmentVo> queryPageList(OrderAssignmentBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<OrderAssignment> lqw = buildQueryWrapper(bo);
+        Page<OrderAssignmentVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的订单分配记录列表
+     *
+     * @param bo 查询条件
+     * @return 订单分配记录列表
+     */
+    @Override
+    public List<OrderAssignmentVo> queryList(OrderAssignmentBo bo) {
+        LambdaQueryWrapper<OrderAssignment> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<OrderAssignment> buildQueryWrapper(OrderAssignmentBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<OrderAssignment> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(OrderAssignment::getId);
+        lqw.eq(bo.getOrderId() != null, OrderAssignment::getOrderId, bo.getOrderId());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformBefore()), OrderAssignment::getPlatformBefore, bo.getPlatformBefore());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformAfter()), OrderAssignment::getPlatformAfter, bo.getPlatformAfter());
+        lqw.eq(bo.getAssignedBy() != null, OrderAssignment::getAssignedBy, bo.getAssignedBy());
+        lqw.eq(StringUtils.isNotBlank(bo.getAssignType()), OrderAssignment::getAssignType, bo.getAssignType());
+        if (params != null) {
+            lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
+                OrderAssignment::getAssignTime, params.get("beginTime"), params.get("endTime"));
+        }
+        return lqw;
+    }
+
+    /**
+     * 新增订单分配记录
+     *
+     * @param bo 订单分配记录
+     * @return 是否新增成功
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean insertByBo(OrderAssignmentBo bo) {
+        Date now = new Date();
+        Long operatorId = LoginHelper.getUserId();
+
+        // 1. 解析订单ID列表
+        List<Long> orderIdList = parseOrderIds(bo.getOrderIds());
+
+        // 2. 查询原始订单信息
+        List<OrderMainVo> orderVos = orderMainMapper.selectVoByIds(orderIdList);
+        Map<Long, String> orderIdToPlatformBefore = orderVos.stream()
+            .collect(Collectors.toMap(OrderMainVo::getId, OrderMainVo::getPlatformCode));
+        Map<Long, String> orderNoToMap = orderVos.stream()
+            .collect(Collectors.toMap(OrderMainVo::getId, OrderMainVo::getOrderNo));
+
+        // 3. 准备分配记录 & 主订单更新对象
+        List<OrderAssignment> assignmentsToInsert = new ArrayList<>();
+        List<OrderMain> ordersToUpdate = new ArrayList<>();
+
+        for (Long orderId : orderIdList) {
+            OrderAssignment assignment = buildAssignment(bo, orderId, orderNoToMap, orderIdToPlatformBefore, operatorId, now);
+            validEntityBeforeSave(assignment);
+            assignmentsToInsert.add(assignment);
+
+            OrderMain orderMain = new OrderMain();
+            orderMain.setId(orderId);
+            orderMain.setPlatformCode(bo.getPlatformAfter());
+            orderMain.setAssignmentStatus(OrderAssignStatus.ASSIGNED.getCode());
+            ordersToUpdate.add(orderMain);
+        }
+
+        // 4. 批量插入分配记录
+        boolean insertSuccess = !assignmentsToInsert.isEmpty() && baseMapper.insertBatch(assignmentsToInsert);
+        if (!insertSuccess) {
+            log.error("订单分配记录插入失败");
+            throw new ServiceException("订单分配记录插入失败");
+        }
+
+        // 5. 批量更新订单商品表:设置 platform_code 和 assignment_status
+        if (!orderIdList.isEmpty()) {
+            orderProductMapper.updatePlatformAndStatusByOrderIds(
+                orderIdList,
+                bo.getPlatformAfter(),
+                OrderAssignStatus.ASSIGNED.getCode()
+            );
+        }
+
+        // 6. 批量更新订单主表(在目标平台上下文中执行)
+        String targetPlatform = bo.getPlatformAfter();
+        String currentPlatform = PlatformContext.getPlatform();
+        if (StringUtils.isEmpty(currentPlatform)) {
+            currentPlatform = SysPlatformCode.OMS.getCode();
+        }
+
+        if (SysPlatformCode.OMS.getCode().equals(currentPlatform)) {
+            PlatformContextUtil.executeWithPlatform(targetPlatform, () -> {
+                for (OrderMain order : ordersToUpdate) {
+                    orderMainMapper.updateById(order);
+                }
+                return null;
+            });
+        } else {
+            // 如果已在目标平台上下文,直接更新
+            for (OrderMain order : ordersToUpdate) {
+                orderMainMapper.updateById(order);
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean splitAssign(OrderSplitAssignBo bo) {
+        Long parentId = bo.getOrderId();
+        List<OrderProductAssignRule> rules = bo.getItemRules();
+
+        if (CollUtil.isEmpty(rules)) {
+            throw new ServiceException("未选择任何商品进行分配");
+        }
+
+        Date now = new Date();
+        Long operatorId = LoginHelper.getUserId();
+
+        // 1. 查询父订单
+        OrderMain parentOrder = orderMainMapper.selectById(parentId);
+        if (parentOrder == null) {
+            throw new ServiceException("父订单不存在");
+        }
+        if (OrderSplitStatus.SPLITED.getCode().equals(parentOrder.getSplitStatus())) {
+            throw new ServiceException("该订单已被拆分,不可重复操作");
+        }
+
+        // 2. 查询所有待分配的商品行(验证存在性 & 所属订单)
+        List<Long> itemIds = rules.stream().map(OrderProductAssignRule::getItemId).collect(Collectors.toList());
+        List<OrderProduct> items = orderProductMapper.selectBatchIds(itemIds);
+        Map<Long, OrderProduct> itemMap = items.stream()
+            .collect(Collectors.toMap(OrderProduct::getId, Function.identity()));
+
+        // 验证:所有商品属于该父订单,且未分配
+        for (OrderProductAssignRule rule : rules) {
+            OrderProduct item = itemMap.get(rule.getItemId());
+            if (item == null || !parentId.equals(item.getOrderId())) {
+                throw new ServiceException("商品行不属于该订单或不存在");
+            }
+            if (OrderAssignStatus.ASSIGNED.getCode().equals(item.getAssignmentStatus())) {
+                throw new ServiceException("商品 [" + item.getProductName() + "] 已分配,不可重复操作");
+            }
+        }
+
+        // 3. 按目标平台分组
+        Map<String, List<OrderProductAssignRule>> platformToRules = rules.stream()
+            .collect(Collectors.groupingBy(OrderProductAssignRule::getTargetPlatform));
+        OrderMain childOrder = null;
+        // 4. 为每个平台创建子订单,并迁移商品
+        for (Map.Entry<String, List<OrderProductAssignRule>> entry : platformToRules.entrySet()) {
+            String targetPlatform = entry.getKey();
+            List<OrderProductAssignRule> groupRules = entry.getValue();
+            childOrder = copyParentToChild(parentOrder, targetPlatform);
+            orderMainMapper.insert(childOrder);
+
+            // 迁移商品行:更新 orderId + platform_code + assignment_status
+            List<Long> groupItemIds = groupRules.stream().map(OrderProductAssignRule::getItemId).collect(Collectors.toList());
+            orderProductMapper.updateForSplitAssign(
+                groupItemIds,
+                childOrder.getId(),
+                targetPlatform,
+                OrderAssignStatus.ASSIGNED.getCode()
+            );
+
+            // 插入分配记录(子订单维度)
+            OrderAssignment assignment = new OrderAssignment();
+            assignment.setOrderId(childOrder.getId());
+            assignment.setOrderNo(childOrder.getOrderNo());
+            assignment.setPlatformBefore(parentOrder.getPlatformCode());
+            assignment.setPlatformAfter(targetPlatform);
+            assignment.setAssignedBy(operatorId);
+            assignment.setAssignTime(now);
+            assignment.setAssignType("0"); // 拆单类型
+            assignment.setRemark(bo.getRemark());
+            baseMapper.insert(assignment);
+        }
+
+        // 5. 更新父订单状态:标记为已拆分
+        OrderMain updateParent = new OrderMain();
+        updateParent.setId(parentId);
+        updateParent.setAssignmentStatus(OrderAssignStatus.ASSIGNED.getCode());
+        updateParent.setSplitStatus(OrderSplitStatus.SPLITED.getCode()); // 已拆分
+        // 注意:父订单 platformCode 保持不变(作为入口)
+        orderMainMapper.updateById(updateParent);
+
+        return true;
+    }
+
+
+    private List<Long> parseOrderIds(String orderIdsStr) {
+        if (StringUtils.contains(orderIdsStr, ",")) {
+            return Arrays.stream(orderIdsStr.split(","))
+                .map(String::trim)
+                .filter(StringUtils::isNotBlank)
+                .map(Long::parseLong)
+                .collect(Collectors.toList());
+        } else {
+            return Collections.singletonList(Long.valueOf(orderIdsStr));
+        }
+    }
+
+    private OrderAssignment buildAssignment(OrderAssignmentBo bo, Long orderId,
+                                            Map<Long, String> orderNoMap, Map<Long, String> platformBeforeMap,
+                                            Long operatorId, Date now) {
+        OrderAssignment assignment = new OrderAssignment();
+        assignment.setOrderId(orderId);
+        assignment.setOrderNo(orderNoMap.getOrDefault(orderId, ""));
+        assignment.setPlatformBefore(platformBeforeMap.getOrDefault(orderId, ""));
+        assignment.setPlatformAfter(bo.getPlatformAfter());
+        assignment.setAssignedBy(operatorId);
+        assignment.setAssignTime(now);
+        assignment.setAssignType(bo.getAssignType());
+        assignment.setRemark(bo.getRemark());
+        return assignment;
+    }
+
+
+    private OrderMain copyParentToChild(OrderMain parent, String targetPlatform) {
+        OrderMain child = new OrderMain();
+        String childSeqKey = "child_order_seq:" + parent.getOrderNo();
+        String paddedSeq = SequenceUtils.nextPaddedIdStr(childSeqKey, Duration.ofDays(90), 2);
+        child.setParentOrderId(parent.getId());
+        child.setIsSplitChild("0");
+        child.setPlatformCode(targetPlatform);
+        child.setOrderNo(parent.getOrderNo() + paddedSeq);
+        child.setCompanyId(parent.getCompanyId());
+        child.setCustomerId(parent.getCustomerId());
+        child.setExpectedDeliveryTime(parent.getExpectedDeliveryTime());
+        child.setShippingAddressId(parent.getShippingAddressId());
+        child.setWarehouseId(parent.getWarehouseId());
+        child.setInvoiceType(parent.getInvoiceType());
+        child.setPayType(parent.getPayType());
+        child.setTotalAmount(parent.getTotalAmount());
+        child.setPayableAmount(parent.getPayableAmount());
+        child.setShippingFee(parent.getShippingFee());
+        child.setOrderSource(parent.getOrderSource());
+        child.setBusinessStaff(parent.getBusinessStaff());
+        child.setBusinessDept(parent.getBusinessDept());
+        child.setPurchaseReason(parent.getPurchaseReason());
+        child.setCreditLimit(parent.getCreditLimit());
+        child.setOrderStatus(parent.getOrderStatus());
+        child.setAssignmentStatus(OrderAssignStatus.ASSIGNED.getCode());
+        child.setSplitStatus("0");
+        child.setRemark(parent.getRemark());
+        child.setCheckStatus(parent.getCheckStatus());
+        child.setCreateTime(new Date());
+        child.setUpdateTime(new Date());
+        child.setDataSource(parent.getDataSource());
+        child.setDeliveryType(parent.getDeliveryType());
+        return child;
+    }
+
+    /**
+     * 修改订单分配记录
+     *
+     * @param bo 订单分配记录
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(OrderAssignmentBo bo) {
+        OrderAssignment update = MapstructUtils.convert(bo, OrderAssignment.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(OrderAssignment entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除订单分配记录信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 2 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderDeliverServiceImpl.java

@@ -111,6 +111,8 @@ public class OrderDeliverServiceImpl extends ServiceImpl<OrderDeliverMapper, Ord
         lqw.eq(StringUtils.isNotBlank(bo.getLogisticPackStatus()), OrderDeliver::getLogisticPackStatus, bo.getLogisticPackStatus());
         lqw.eq(StringUtils.isNotBlank(bo.getConsigneePhone()), OrderDeliver::getConsigneePhone, bo.getConsigneePhone());
         lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), OrderDeliver::getPlatformCode, bo.getPlatformCode());
+        lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
+            OrderDeliver::getCreateTime, params.get("beginTime"), params.get("endTime"));
         return lqw;
     }
 

+ 49 - 8
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderMainServiceImpl.java

@@ -7,11 +7,13 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.redis.utils.SequenceUtils;
+import org.dromara.customer.api.RemoteCustomerService;
 import org.dromara.order.domain.OrderMain;
 import org.dromara.order.domain.OrderProduct;
 import org.dromara.order.domain.bo.OrderMainBo;
@@ -27,9 +29,7 @@ import org.dromara.order.service.IOrderMainService;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -43,6 +43,9 @@ import java.util.stream.Collectors;
 @Service
 public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain> implements IOrderMainService {
 
+    @DubboReference
+    private RemoteCustomerService remoteCustomerService;
+
     private final OrderMainMapper baseMapper;
 
     private final OrderProductMapper orderProductMapper;
@@ -91,6 +94,11 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
         Page<OrderMainVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
         List<OrderMainVo> records = result.getRecords();
 
+        if (CollUtil.isNotEmpty(records)) {
+            Set<Long> customerIds = records.stream().map(OrderMainVo::getCustomerId).collect(Collectors.toSet());
+            Map<Long, String> customerMap = remoteCustomerService.selectCustomerNameByIds(customerIds);
+            records.forEach(orderMainVo -> orderMainVo.setCustomerName(customerMap.get(orderMainVo.getCustomerId())));
+        }
         return TableDataInfo.build(result);
     }
 
@@ -119,6 +127,7 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
         lqw.eq(StringUtils.isNotBlank(bo.getCustomerCode()), OrderMain::getCustomerCode, bo.getCustomerCode());
         lqw.eq(StringUtils.isNotBlank(bo.getShipmentNo()), OrderMain::getShipmentNo, bo.getShipmentNo());
         lqw.eq(StringUtils.isNotBlank(bo.getSubOrderNo()), OrderMain::getSubOrderNo, bo.getSubOrderNo());
+        lqw.eq(StringUtils.isNotBlank(bo.getIsSplitChild()), OrderMain::getIsSplitChild, bo.getIsSplitChild());
         lqw.eq(bo.getCompanyId() != null, OrderMain::getCompanyId, bo.getCompanyId());
         lqw.eq(bo.getCustomerId() != null, OrderMain::getCustomerId, bo.getCustomerId());
         lqw.eq(bo.getUserId() != null, OrderMain::getUserId, bo.getUserId());
@@ -144,21 +153,24 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
         lqw.eq(bo.getConfirmTime() != null, OrderMain::getConfirmTime, bo.getConfirmTime());
         lqw.eq(bo.getShippingTime() != null, OrderMain::getShippingTime, bo.getShippingTime());
         lqw.eq(bo.getReceivingTime() != null, OrderMain::getReceivingTime, bo.getReceivingTime());
-        lqw.eq(bo.getShippedQuantity() != null, OrderMain::getShippedQuantity, bo.getShippedQuantity());
-        lqw.eq(bo.getUnshippedQuantity() != null, OrderMain::getUnshippedQuantity, bo.getUnshippedQuantity());
         lqw.eq(bo.getPackageCount() != null, OrderMain::getPackageCount, bo.getPackageCount());
         lqw.eq(bo.getSignedQuantity() != null, OrderMain::getSignedQuantity, bo.getSignedQuantity());
         lqw.eq(bo.getAfterSaleCompleted() != null, OrderMain::getAfterSaleCompleted, bo.getAfterSaleCompleted());
         lqw.eq(bo.getAfterSalePending() != null, OrderMain::getAfterSalePending, bo.getAfterSalePending());
-        lqw.eq(StringUtils.isNotBlank(bo.getDeliveryDesc()), OrderMain::getDeliveryDesc, bo.getDeliveryDesc());
         lqw.eq(StringUtils.isNotBlank(bo.getPushStatus()), OrderMain::getPushStatus, bo.getPushStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getCheckStatus()), OrderMain::getCheckStatus, bo.getCheckStatus());
         lqw.eq(StringUtils.isNotBlank(bo.getAttachmentPath()), OrderMain::getAttachmentPath, bo.getAttachmentPath());
         lqw.eq(StringUtils.isNotBlank(bo.getDeliveryType()), OrderMain::getDeliveryType, bo.getDeliveryType());
         lqw.eq(StringUtils.isNotBlank(bo.getOrderCategory()), OrderMain::getOrderCategory, bo.getOrderCategory());
-        lqw.eq(StringUtils.isNotBlank(bo.getProductCode()), OrderMain::getProductCode, bo.getProductCode());
-        lqw.eq(StringUtils.isNotBlank(bo.getCancelReason()), OrderMain::getCancelReason, bo.getCancelReason());
         lqw.eq(StringUtils.isNotBlank(bo.getExpenseType()), OrderMain::getExpenseType, bo.getExpenseType());
         lqw.eq(StringUtils.isNotBlank(bo.getStatus()), OrderMain::getStatus, bo.getStatus());
+        if (params != null) {
+            lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
+                OrderMain::getOrderTime, params.get("beginTime"), params.get("endTime"));
+        }
+        if (null != bo.getOrderStatuses() && bo.getOrderStatuses().contains(",")) {
+            lqw.in(OrderMain::getOrderStatus, bo.getOrderStatuses().split(","));
+        }
         return lqw;
     }
 
@@ -188,6 +200,21 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
             // 2. 生成订单号并转换主单
             String orderNo = SequenceUtils.generateOrderCode("RS");
             bo.setOrderNo(orderNo);
+            Date originalDate = bo.getOrderTime(); // 假设是 2025-01-06 00:00:00
+            if (originalDate != null) {
+                Calendar calOriginal = Calendar.getInstance();
+                calOriginal.setTime(originalDate);
+
+                Calendar calNow = Calendar.getInstance(); // 获取当前时分秒
+
+                // 保留原日期的年月日,替换时分秒为当前时间
+                calOriginal.set(Calendar.HOUR_OF_DAY, calNow.get(Calendar.HOUR_OF_DAY));
+                calOriginal.set(Calendar.MINUTE, calNow.get(Calendar.MINUTE));
+                calOriginal.set(Calendar.SECOND, calNow.get(Calendar.SECOND));
+                calOriginal.set(Calendar.MILLISECOND, calNow.get(Calendar.MILLISECOND));
+
+                bo.setOrderTime(calOriginal.getTime());
+            }
             OrderMain orderMain = MapstructUtils.convert(bo, OrderMain.class);
 
             validEntityBeforeSave(orderMain);
@@ -254,6 +281,20 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
         return baseMapper.updateById(order);
     }
 
+    /**
+     * 修改审核状态
+     *
+     * @param bo 信息
+     * @return 结果
+     */
+    @Override
+    public int updateCheckStatus(OrderMainBo bo) {
+        OrderMain order = new OrderMain();
+        order.setId(bo.getId());
+        order.setCheckStatus(bo.getCheckStatus());
+        return baseMapper.updateById(order);
+    }
+
     /**
      * 保存前的数据校验
      */

+ 142 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderReturnItemServiceImpl.java

@@ -0,0 +1,142 @@
+package org.dromara.order.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.order.domain.bo.OrderReturnItemBo;
+import org.dromara.order.domain.vo.OrderReturnItemVo;
+import org.dromara.order.domain.OrderReturnItem;
+import org.dromara.order.mapper.OrderReturnItemMapper;
+import org.dromara.order.service.IOrderReturnItemService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 退货商品明细Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-05
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class OrderReturnItemServiceImpl  extends ServiceImpl<OrderReturnItemMapper, OrderReturnItem> implements IOrderReturnItemService {
+
+    private final OrderReturnItemMapper baseMapper;
+
+    /**
+     * 查询退货商品明细
+     *
+     * @param id 主键
+     * @return 退货商品明细
+     */
+    @Override
+    public OrderReturnItemVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询退货商品明细列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 退货商品明细分页列表
+     */
+    @Override
+    public TableDataInfo<OrderReturnItemVo> queryPageList(OrderReturnItemBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<OrderReturnItem> lqw = buildQueryWrapper(bo);
+        Page<OrderReturnItemVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的退货商品明细列表
+     *
+     * @param bo 查询条件
+     * @return 退货商品明细列表
+     */
+    @Override
+    public List<OrderReturnItemVo> queryList(OrderReturnItemBo bo) {
+        LambdaQueryWrapper<OrderReturnItem> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<OrderReturnItem> buildQueryWrapper(OrderReturnItemBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<OrderReturnItem> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(OrderReturnItem::getId);
+        lqw.eq(bo.getReturnId() != null, OrderReturnItem::getReturnId, bo.getReturnId());
+        lqw.eq(bo.getOrderProductId() != null, OrderReturnItem::getOrderProductId, bo.getOrderProductId());
+        lqw.eq(StringUtils.isNotBlank(bo.getProductSku()), OrderReturnItem::getProductSku, bo.getProductSku());
+        lqw.like(StringUtils.isNotBlank(bo.getProductName()), OrderReturnItem::getProductName, bo.getProductName());
+        lqw.eq(bo.getReturnQuantity() != null, OrderReturnItem::getReturnQuantity, bo.getReturnQuantity());
+        lqw.eq(bo.getUnitPrice() != null, OrderReturnItem::getUnitPrice, bo.getUnitPrice());
+        lqw.eq(bo.getTotalAmount() != null, OrderReturnItem::getTotalAmount, bo.getTotalAmount());
+        lqw.eq(StringUtils.isNotBlank(bo.getReasonDetail()), OrderReturnItem::getReasonDetail, bo.getReasonDetail());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), OrderReturnItem::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), OrderReturnItem::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增退货商品明细
+     *
+     * @param bo 退货商品明细
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(OrderReturnItemBo bo) {
+        OrderReturnItem add = MapstructUtils.convert(bo, OrderReturnItem.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改退货商品明细
+     *
+     * @param bo 退货商品明细
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(OrderReturnItemBo bo) {
+        OrderReturnItem update = MapstructUtils.convert(bo, OrderReturnItem.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(OrderReturnItem entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除退货商品明细信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 265 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderReturnServiceImpl.java

@@ -0,0 +1,265 @@
+package org.dromara.order.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.redis.utils.SequenceUtils;
+import org.dromara.order.domain.OrderMain;
+import org.dromara.order.domain.OrderReturn;
+import org.dromara.order.domain.OrderReturnItem;
+import org.dromara.order.domain.OrderRevenueHeader;
+import org.dromara.order.domain.bo.OrderReturnBo;
+import org.dromara.order.domain.bo.OrderReturnItemBo;
+import org.dromara.order.domain.vo.OrderReturnVo;
+import org.dromara.order.mapper.OrderReturnItemMapper;
+import org.dromara.order.mapper.OrderReturnMapper;
+import org.dromara.order.service.IOrderReturnService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * 退货主Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-05
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class OrderReturnServiceImpl extends ServiceImpl<OrderReturnMapper, OrderReturn> implements IOrderReturnService {
+
+    private final OrderReturnMapper baseMapper;
+
+    private final OrderReturnItemMapper orderReturnItemMapper;
+
+    /**
+     * 查询退货主
+     *
+     * @param id 主键
+     * @return 退货主
+     */
+    @Override
+    public OrderReturnVo queryById(Long id) {
+        OrderReturnVo orderReturnVo = baseMapper.selectVoById(id);
+        orderReturnVo.setOrderReturnItemList(orderReturnItemMapper.selectVoList(new LambdaQueryWrapper<OrderReturnItem>()
+            .eq(OrderReturnItem::getReturnId, orderReturnVo.getId())));
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询退货主列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 退货主分页列表
+     */
+    @Override
+    public TableDataInfo<OrderReturnVo> queryPageList(OrderReturnBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<OrderReturn> lqw = buildQueryWrapper(bo);
+        Page<OrderReturnVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的退货主列表
+     *
+     * @param bo 查询条件
+     * @return 退货主列表
+     */
+    @Override
+    public List<OrderReturnVo> queryList(OrderReturnBo bo) {
+        LambdaQueryWrapper<OrderReturn> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<OrderReturn> buildQueryWrapper(OrderReturnBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<OrderReturn> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(OrderReturn::getId);
+        lqw.eq(bo.getOrderId() != null, OrderReturn::getOrderId, bo.getOrderId());
+        lqw.eq(StringUtils.isNotBlank(bo.getOrderNo()), OrderReturn::getOrderNo, bo.getOrderNo());
+        lqw.eq(StringUtils.isNotBlank(bo.getServiceType()), OrderReturn::getServiceType, bo.getServiceType());
+        lqw.eq(bo.getReturnTime() != null, OrderReturn::getReturnTime, bo.getReturnTime());
+        lqw.eq(StringUtils.isNotBlank(bo.getReturnNo()), OrderReturn::getReturnNo, bo.getReturnNo());
+        lqw.eq(bo.getCustomerId() != null, OrderReturn::getCustomerId, bo.getCustomerId());
+        lqw.eq(StringUtils.isNotBlank(bo.getCustomerNo()), OrderReturn::getCustomerNo, bo.getCustomerNo());
+        lqw.like(StringUtils.isNotBlank(bo.getCustomerName()), OrderReturn::getCustomerName, bo.getCustomerName());
+        lqw.eq(bo.getAfterSaleAmount() != null, OrderReturn::getAfterSaleAmount, bo.getAfterSaleAmount());
+        lqw.eq(StringUtils.isNotBlank(bo.getReturnStatus()), OrderReturn::getReturnStatus, bo.getReturnStatus());
+        lqw.eq(bo.getReturnProductNum() != null, OrderReturn::getReturnProductNum, bo.getReturnProductNum());
+        lqw.eq(bo.getProcessingTime() != null, OrderReturn::getProcessingTime, bo.getProcessingTime());
+        lqw.eq(bo.getReturnReasonId() != null, OrderReturn::getReturnReasonId, bo.getReturnReasonId());
+        lqw.eq(StringUtils.isNotBlank(bo.getReturnReason()), OrderReturn::getReturnReason, bo.getReturnReason());
+        lqw.eq(StringUtils.isNotBlank(bo.getProblemDescription()), OrderReturn::getProblemDescription, bo.getProblemDescription());
+        lqw.eq(StringUtils.isNotBlank(bo.getVoucherPhoto()), OrderReturn::getVoucherPhoto, bo.getVoucherPhoto());
+        lqw.eq(bo.getShippingFee() != null, OrderReturn::getShippingFee, bo.getShippingFee());
+        lqw.eq(StringUtils.isNotBlank(bo.getIsShippingFee()), OrderReturn::getIsShippingFee, bo.getIsShippingFee());
+        lqw.eq(bo.getOrderAmount() != null, OrderReturn::getOrderAmount, bo.getOrderAmount());
+        lqw.eq(bo.getReturnAmount() != null, OrderReturn::getReturnAmount, bo.getReturnAmount());
+        lqw.eq(StringUtils.isNotBlank(bo.getAfterSalesRemarks()), OrderReturn::getAfterSalesRemarks, bo.getAfterSalesRemarks());
+        lqw.eq(StringUtils.isNotBlank(bo.getReturnMethod()), OrderReturn::getReturnMethod, bo.getReturnMethod());
+        lqw.like(StringUtils.isNotBlank(bo.getChargebackName()), OrderReturn::getChargebackName, bo.getChargebackName());
+        lqw.eq(StringUtils.isNotBlank(bo.getChargebackPhone()), OrderReturn::getChargebackPhone, bo.getChargebackPhone());
+        lqw.eq(StringUtils.isNotBlank(bo.getChargebackPickupTime()), OrderReturn::getChargebackPickupTime, bo.getChargebackPickupTime());
+        lqw.eq(StringUtils.isNotBlank(bo.getChargebackProvincial()), OrderReturn::getChargebackProvincial, bo.getChargebackProvincial());
+        lqw.eq(StringUtils.isNotBlank(bo.getChargebackCity()), OrderReturn::getChargebackCity, bo.getChargebackCity());
+        lqw.eq(StringUtils.isNotBlank(bo.getChargebackCounty()), OrderReturn::getChargebackCounty, bo.getChargebackCounty());
+        lqw.eq(StringUtils.isNotBlank(bo.getProvincialCityCounty()), OrderReturn::getProvincialCityCounty, bo.getProvincialCityCounty());
+        lqw.eq(StringUtils.isNotBlank(bo.getChargebackAddress()), OrderReturn::getChargebackAddress, bo.getChargebackAddress());
+        lqw.eq(StringUtils.isNotBlank(bo.getPushStatus()), OrderReturn::getPushStatus, bo.getPushStatus());
+        lqw.eq(bo.getLogisticsId() != null, OrderReturn::getLogisticsId, bo.getLogisticsId());
+        lqw.like(StringUtils.isNotBlank(bo.getLogisticsName()), OrderReturn::getLogisticsName, bo.getLogisticsName());
+        lqw.eq(StringUtils.isNotBlank(bo.getLogisticsNo()), OrderReturn::getLogisticsNo, bo.getLogisticsNo());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), OrderReturn::getStatus, bo.getStatus());
+        if (params != null) {
+            lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
+                OrderReturn::getCreateTime, params.get("beginTime"), params.get("endTime"));
+        }
+        return lqw;
+    }
+
+    /**
+     * 新增退货主
+     *
+     * @param bo 退货主
+     * @return 是否新增成功
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean insertByBo(OrderReturnBo bo) {
+
+        if (bo == null) {
+            log.warn("新增退货单失败:入参为空");
+            return false;
+        }
+
+        // 生成单号
+        bo.setReturnNo(SequenceUtils.generateOrderCode("OR"));
+
+        // 转换并校验
+        OrderReturn entity = MapstructUtils.convert(bo, OrderReturn.class);
+        validEntityBeforeSave(entity);
+
+        // 插入主表
+        boolean inserted = baseMapper.insert(entity) > 0;
+        if (!inserted) {
+            log.warn("插入退货单主表失败");
+            return false;
+        }
+
+        // 保存明细
+        saveOrderReturnItems(entity.getId(), bo.getOrderReturnItemList(), false);
+
+        log.info("新增退货单成功,单号: {}", entity.getReturnNo());
+        return true;
+    }
+
+    /**
+     * 修改退货主
+     *
+     * @param bo 退货主
+     * @return 是否修改成功
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean updateByBo(OrderReturnBo bo) {
+
+        if (bo == null || bo.getId() == null) {
+            log.warn("修改退货单失败:BO 或 ID 为空");
+            return false;
+        }
+
+        // 检查主表记录是否存在
+        if (baseMapper.selectById(bo.getId()) == null) {
+            log.warn("修改退货单失败:主表记录不存在,ID={}", bo.getId());
+            return false;
+        }
+
+        // 转换并校验
+        OrderReturn entity = MapstructUtils.convert(bo, OrderReturn.class);
+        validEntityBeforeSave(entity);
+
+        // 更新主表
+        boolean updated = baseMapper.updateById(entity) > 0;
+        if (!updated) {
+            log.warn("更新退货单主表失败,ID={}", bo.getId());
+            return false;
+        }
+
+        // 先删后插明细
+        saveOrderReturnItems(bo.getId(), bo.getOrderReturnItemList(), true);
+
+        log.info("修改退货单成功,ID: {}", bo.getId());
+        return true;
+    }
+
+    /**
+     * 保存收入单明细
+     *
+     * @param orderReturnId 主表ID
+     * @param itemList      明细列表
+     * @param deleteFirst   是否先删除已有明细(true=编辑模式)
+     */
+    private void saveOrderReturnItems(Long orderReturnId, List<OrderReturnItemBo> itemList, boolean deleteFirst) {
+        if (orderReturnId == null) {
+            return;
+        }
+
+        if (deleteFirst) {
+            orderReturnItemMapper.deleteByOrderReturnId(orderReturnId);
+        }
+
+        if (itemList == null || itemList.isEmpty()) {
+            return;
+        }
+
+        List<OrderReturnItem> items = itemList.stream()
+            .filter(Objects::nonNull) // 防止空元素
+            .map(bo -> {
+                OrderReturnItem item = MapstructUtils.convert(bo, OrderReturnItem.class);
+                item.setReturnId(orderReturnId);
+                return item;
+            })
+            .collect(Collectors.toList());
+
+        if (!items.isEmpty()) {
+            orderReturnItemMapper.insertBatch(items);
+        }
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(OrderReturn entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除退货主信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 145 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderRevenueDetailServiceImpl.java

@@ -0,0 +1,145 @@
+package org.dromara.order.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.order.domain.bo.OrderRevenueDetailBo;
+import org.dromara.order.domain.vo.OrderRevenueDetailVo;
+import org.dromara.order.domain.OrderRevenueDetail;
+import org.dromara.order.mapper.OrderRevenueDetailMapper;
+import org.dromara.order.service.IOrderRevenueDetailService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 收入单明细Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class OrderRevenueDetailServiceImpl  extends ServiceImpl<OrderRevenueDetailMapper, OrderRevenueDetail> implements IOrderRevenueDetailService {
+
+    private final OrderRevenueDetailMapper baseMapper;
+
+    /**
+     * 查询收入单明细
+     *
+     * @param id 主键
+     * @return 收入单明细
+     */
+    @Override
+    public OrderRevenueDetailVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询收入单明细列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 收入单明细分页列表
+     */
+    @Override
+    public TableDataInfo<OrderRevenueDetailVo> queryPageList(OrderRevenueDetailBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<OrderRevenueDetail> lqw = buildQueryWrapper(bo);
+        Page<OrderRevenueDetailVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的收入单明细列表
+     *
+     * @param bo 查询条件
+     * @return 收入单明细列表
+     */
+    @Override
+    public List<OrderRevenueDetailVo> queryList(OrderRevenueDetailBo bo) {
+        LambdaQueryWrapper<OrderRevenueDetail> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<OrderRevenueDetail> buildQueryWrapper(OrderRevenueDetailBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<OrderRevenueDetail> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(OrderRevenueDetail::getId);
+        lqw.eq(bo.getOrderRevenueId() != null, OrderRevenueDetail::getOrderRevenueId, bo.getOrderRevenueId());
+        lqw.eq(bo.getRevenueId() != null, OrderRevenueDetail::getRevenueId, bo.getRevenueId());
+        lqw.eq(StringUtils.isNotBlank(bo.getRevenueCode()), OrderRevenueDetail::getRevenueCode, bo.getRevenueCode());
+        lqw.eq(StringUtils.isNotBlank(bo.getTaxRateCode()), OrderRevenueDetail::getTaxRateCode, bo.getTaxRateCode());
+        lqw.eq(bo.getTotalAmount() != null, OrderRevenueDetail::getTotalAmount, bo.getTotalAmount());
+        lqw.eq(bo.getUnitPrice() != null, OrderRevenueDetail::getUnitPrice, bo.getUnitPrice());
+        lqw.eq(bo.getQuantity() != null, OrderRevenueDetail::getQuantity, bo.getQuantity());
+        lqw.eq(bo.getPlatformAmount() != null, OrderRevenueDetail::getPlatformAmount, bo.getPlatformAmount());
+        lqw.eq(bo.getPlatformPrice() != null, OrderRevenueDetail::getPlatformPrice, bo.getPlatformPrice());
+        lqw.eq(StringUtils.isNotBlank(bo.getOrderType()), OrderRevenueDetail::getOrderType, bo.getOrderType());
+        lqw.eq(StringUtils.isNotBlank(bo.getRevFile()), OrderRevenueDetail::getRevFile, bo.getRevFile());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), OrderRevenueDetail::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), OrderRevenueDetail::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增收入单明细
+     *
+     * @param bo 收入单明细
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(OrderRevenueDetailBo bo) {
+        OrderRevenueDetail add = MapstructUtils.convert(bo, OrderRevenueDetail.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改收入单明细
+     *
+     * @param bo 收入单明细
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(OrderRevenueDetailBo bo) {
+        OrderRevenueDetail update = MapstructUtils.convert(bo, OrderRevenueDetail.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(OrderRevenueDetail entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除收入单明细信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 294 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderRevenueHeaderServiceImpl.java

@@ -0,0 +1,294 @@
+package org.dromara.order.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.redis.utils.SequenceUtils;
+import org.dromara.customer.api.RemoteCustomerService;
+import org.dromara.order.domain.OrderRevenueDetail;
+import org.dromara.order.domain.OrderRevenueHeader;
+import org.dromara.order.domain.bo.OrderRevenueDetailBo;
+import org.dromara.order.domain.bo.OrderRevenueHeaderBo;
+import org.dromara.order.domain.vo.OrderRevenueDetailVo;
+import org.dromara.order.domain.vo.OrderRevenueHeaderVo;
+import org.dromara.order.mapper.OrderRevenueDetailMapper;
+import org.dromara.order.mapper.OrderRevenueHeaderMapper;
+import org.dromara.order.service.IOrderRevenueHeaderService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * 收入单主Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class OrderRevenueHeaderServiceImpl extends ServiceImpl<OrderRevenueHeaderMapper, OrderRevenueHeader> implements IOrderRevenueHeaderService {
+
+    @DubboReference
+    private RemoteCustomerService remoteCustomerService;
+
+    private final OrderRevenueHeaderMapper baseMapper;
+
+    private final OrderRevenueDetailMapper orderRevenueDetailMapper;
+
+    /**
+     * 查询收入单主
+     *
+     * @param id 主键
+     * @return 收入单主
+     */
+    @Override
+    public OrderRevenueHeaderVo queryById(Long id) {
+        OrderRevenueHeaderVo orderRevenueHeaderVo = baseMapper.selectVoById(id);
+        orderRevenueHeaderVo.setOrderRevenueDetailList(orderRevenueDetailMapper.selectVoList(new LambdaQueryWrapper<OrderRevenueDetail>()
+            .eq(OrderRevenueDetail::getOrderRevenueId, id)));
+        return orderRevenueHeaderVo;
+    }
+
+    /**
+     * 分页查询收入单主列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 收入单主分页列表
+     */
+    @Override
+    public TableDataInfo<OrderRevenueHeaderVo> queryPageList(OrderRevenueHeaderBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<OrderRevenueHeader> lqw = buildQueryWrapper(bo);
+        Page<OrderRevenueHeaderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        List<OrderRevenueHeaderVo> records = result.getRecords();
+        if (CollUtil.isNotEmpty(records)) {
+            // 1. 提取所有主单 ID
+            List<Long> headerIds = records.stream()
+                .map(OrderRevenueHeaderVo::getId)
+                .collect(Collectors.toList());
+
+            // 2. 一次性查询所有相关明细(IN 查询)
+            List<OrderRevenueDetailVo> detailVos = orderRevenueDetailMapper.selectVoList(
+                new LambdaQueryWrapper<OrderRevenueDetail>()
+                    .in(OrderRevenueDetail::getOrderRevenueId, headerIds)
+            );
+
+            // 3. 按主单 ID 分组:Map<Long, List<OrderRevenueDetailVo>>
+            Map<Long, List<OrderRevenueDetailVo>> detailGroupMap = detailVos.stream()
+                .collect(Collectors.groupingBy(OrderRevenueDetailVo::getOrderRevenueId));
+
+            // 4. 为每个主单设置 totalAmount
+            for (OrderRevenueHeaderVo record : records) {
+                List<OrderRevenueDetailVo> details = detailGroupMap.get(record.getId());
+                if (CollUtil.isNotEmpty(details)) {
+                    BigDecimal total = details.stream()
+                        .map(OrderRevenueDetailVo::getTotalAmount)
+                        .filter(Objects::nonNull) // 防止空值导致 NPE
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+                    record.setTotalAmount(total);
+                } else {
+                    record.setTotalAmount(BigDecimal.ZERO); // 无明细时设为 0
+                }
+            }
+        }
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的收入单主列表
+     *
+     * @param bo 查询条件
+     * @return 收入单主列表
+     */
+    @Override
+    public List<OrderRevenueHeaderVo> queryList(OrderRevenueHeaderBo bo) {
+        LambdaQueryWrapper<OrderRevenueHeader> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<OrderRevenueHeader> buildQueryWrapper(OrderRevenueHeaderBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<OrderRevenueHeader> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(OrderRevenueHeader::getId);
+        lqw.eq(StringUtils.isNotBlank(bo.getRevenueType()), OrderRevenueHeader::getRevenueType, bo.getRevenueType());
+        lqw.eq(StringUtils.isNotBlank(bo.getOrderRevenueCode()), OrderRevenueHeader::getOrderRevenueCode, bo.getOrderRevenueCode());
+        lqw.eq(StringUtils.isNotBlank(bo.getIncomeOrderCode()), OrderRevenueHeader::getIncomeOrderCode, bo.getIncomeOrderCode());
+        lqw.eq(StringUtils.isNotBlank(bo.getOtherRevenueType()), OrderRevenueHeader::getOtherRevenueType, bo.getOtherRevenueType());
+        lqw.like(StringUtils.isNotBlank(bo.getBusinessStaff()), OrderRevenueHeader::getBusinessStaff, bo.getBusinessStaff());
+        lqw.like(StringUtils.isNotBlank(bo.getCustomerService()), OrderRevenueHeader::getCustomerService, bo.getCustomerService());
+        lqw.eq(bo.getCustomerId() != null, OrderRevenueHeader::getCustomerId, bo.getCustomerId());
+        lqw.eq(bo.getSupplierId() != null, OrderRevenueHeader::getSupplierId, bo.getSupplierId());
+        lqw.eq(StringUtils.isNotBlank(bo.getIsPrwTax()), OrderRevenueHeader::getIsPrwTax, bo.getIsPrwTax());
+        lqw.eq(bo.getCurrencyId() != null, OrderRevenueHeader::getCurrencyId, bo.getCurrencyId());
+        lqw.eq(StringUtils.isNotBlank(bo.getPushStatus()), OrderRevenueHeader::getPushStatus, bo.getPushStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getOrderFile()), OrderRevenueHeader::getOrderFile, bo.getOrderFile());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), OrderRevenueHeader::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), OrderRevenueHeader::getPlatformCode, bo.getPlatformCode());
+        if (null != bo.getSearchValue()) {
+            String keyword = bo.getSearchValue().trim();
+            lqw.and(wrapper -> wrapper
+                .like(OrderRevenueHeader::getCustomerName, keyword)
+                .or()
+                .like(OrderRevenueHeader::getOrderRevenueCode, keyword)
+                .or()
+                .like(OrderRevenueHeader::getIncomeOrderCode, keyword)
+                .or()
+                .like(OrderRevenueHeader::getSupplierName, keyword)
+            );
+        }
+        return lqw;
+    }
+
+    /**
+     * 新增收入单主
+     *
+     * @param bo 收入单主
+     * @return 是否新增成功
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean insertByBo(OrderRevenueHeaderBo bo) {
+        if (bo == null) {
+            log.warn("新增收入单失败:入参为空");
+            return false;
+        }
+
+        // 生成单号
+        bo.setOrderRevenueCode(SequenceUtils.generateOrderCode("OR"));
+
+        // 转换并校验
+        OrderRevenueHeader entity = MapstructUtils.convert(bo, OrderRevenueHeader.class);
+        validEntityBeforeSave(entity);
+
+        // 插入主表
+        boolean inserted = baseMapper.insert(entity) > 0;
+        if (!inserted) {
+            log.warn("插入收入单主表失败");
+            return false;
+        }
+
+        // 保存明细
+        saveOrderRevenueDetails(entity.getId(), bo.getOrderRevenueDetails(), false);
+
+        log.info("新增收入单成功,单号: {}", entity.getOrderRevenueCode());
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean updateByBo(OrderRevenueHeaderBo bo) {
+        if (bo == null || bo.getId() == null) {
+            log.warn("修改收入单失败:BO 或 ID 为空");
+            return false;
+        }
+
+        // 检查主表记录是否存在
+        if (baseMapper.selectById(bo.getId()) == null) {
+            log.warn("修改收入单失败:主表记录不存在,ID={}", bo.getId());
+            return false;
+        }
+
+        // 转换并校验
+        OrderRevenueHeader entity = MapstructUtils.convert(bo, OrderRevenueHeader.class);
+        validEntityBeforeSave(entity);
+
+        // 更新主表
+        boolean updated = baseMapper.updateById(entity) > 0;
+        if (!updated) {
+            log.warn("更新收入单主表失败,ID={}", bo.getId());
+            return false;
+        }
+
+        // 先删后插明细
+        saveOrderRevenueDetails(bo.getId(), bo.getOrderRevenueDetails(), true);
+
+        log.info("修改收入单成功,ID: {}", bo.getId());
+        return true;
+    }
+
+    /**
+     * 保存收入单明细
+     *
+     * @param orderRevenueId 主表ID
+     * @param detailList     明细列表
+     * @param deleteFirst    是否先删除已有明细(true=编辑模式)
+     */
+    private void saveOrderRevenueDetails(Long orderRevenueId, List<OrderRevenueDetailBo> detailList, boolean deleteFirst) {
+        if (orderRevenueId == null) {
+            return;
+        }
+
+        if (deleteFirst) {
+            orderRevenueDetailMapper.deleteByRevenueHeadId(orderRevenueId);
+        }
+
+        if (detailList == null || detailList.isEmpty()) {
+            return;
+        }
+
+        List<OrderRevenueDetail> details = detailList.stream()
+            .filter(Objects::nonNull) // 防止空元素
+            .map(bo -> {
+                OrderRevenueDetail detail = MapstructUtils.convert(bo, OrderRevenueDetail.class);
+                detail.setOrderRevenueId(orderRevenueId);
+                return detail;
+            })
+            .collect(Collectors.toList());
+
+        if (!details.isEmpty()) {
+            orderRevenueDetailMapper.insertBatch(details);
+        }
+    }
+
+    /**
+     * 修改状态
+     *
+     * @param bo 信息
+     * @return 结果
+     */
+    @Override
+    public int updateStatus(OrderRevenueHeaderBo bo) {
+        OrderRevenueHeader header = new OrderRevenueHeader();
+        header.setId(bo.getId());
+        header.setStatus(bo.getStatus());
+        return baseMapper.updateById(header);
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(OrderRevenueHeader entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除收入单主信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 7 - 0
ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderAssignmentMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.order.mapper.OrderAssignmentMapper">
+
+</mapper>

+ 23 - 0
ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderProductMapper.xml

@@ -50,4 +50,27 @@
           AND op.del_flag = '0'
     </select>
 
+    <update id="updatePlatformAndStatusByOrderIds">
+        UPDATE order_product
+        SET
+        platform_code = #{platformCode},
+        assignment_status = #{assignmentStatus}
+        WHERE order_id IN
+        <foreach collection="orderIds" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </update>
+
+    <update id="updateForSplitAssign">
+        UPDATE order_product
+        SET
+        order_id = #{newOrderId},
+        platform_code = #{platformCode},
+        assignment_status = #{assignmentStatus}
+        WHERE id IN
+        <foreach collection="itemIds" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </update>
+
 </mapper>

+ 14 - 0
ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderReturnItemMapper.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.order.mapper.OrderReturnItemMapper">
+
+    <delete id="deleteByOrderReturnId" parameterType="java.lang.Long">
+        DELETE
+        FROM order_return_item
+        WHERE return_id = #{orderReturnId}
+    </delete>
+
+
+</mapper>

+ 7 - 0
ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderReturnMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.order.mapper.OrderReturnMapper">
+
+</mapper>

+ 14 - 0
ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderRevenueDetailMapper.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.order.mapper.OrderRevenueDetailMapper">
+
+    <delete id="deleteByRevenueId" parameterType="java.lang.Long">
+        DELETE
+        FROM order_revenue_detail
+        WHERE order_revenue_id = #{orderRevenueId}
+    </delete>
+
+
+</mapper>

+ 7 - 0
ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderRevenueHeaderMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.order.mapper.OrderRevenueHeaderMapper">
+
+</mapper>

+ 117 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/ComCurrencyController.java

@@ -0,0 +1,117 @@
+package org.dromara.system.controller.system;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.system.domain.bo.OrderPaySetBo;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.system.domain.vo.ComCurrencyVo;
+import org.dromara.system.domain.bo.ComCurrencyBo;
+import org.dromara.system.service.IComCurrencyService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 交易币别配置
+ * 前端访问路由地址为:/system/comCurrency
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/comCurrency")
+public class ComCurrencyController extends BaseController {
+
+    private final IComCurrencyService comCurrencyService;
+
+    /**
+     * 查询交易币别配置列表
+     */
+//    @SaCheckPermission("system:comCurrency:list")
+    @GetMapping("/list")
+    public TableDataInfo<ComCurrencyVo> list(ComCurrencyBo bo, PageQuery pageQuery) {
+        return comCurrencyService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出交易币别配置列表
+     */
+//    @SaCheckPermission("system:comCurrency:export")
+    @Log(title = "交易币别配置", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(ComCurrencyBo bo, HttpServletResponse response) {
+        List<ComCurrencyVo> list = comCurrencyService.queryList(bo);
+        ExcelUtil.exportExcel(list, "交易币别配置", ComCurrencyVo.class, response);
+    }
+
+    /**
+     * 获取交易币别配置详细信息
+     *
+     * @param id 主键
+     */
+//    @SaCheckPermission("system:comCurrency:query")
+    @GetMapping("/{id}")
+    public R<ComCurrencyVo> getInfo(@NotNull(message = "主键不能为空")
+                                    @PathVariable("id") Long id) {
+        return R.ok(comCurrencyService.queryById(id));
+    }
+
+    /**
+     * 新增交易币别配置
+     */
+    @SaCheckPermission("system:comCurrency:add")
+    @Log(title = "交易币别配置", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody ComCurrencyBo bo) {
+        return toAjax(comCurrencyService.insertByBo(bo));
+    }
+
+    /**
+     * 修改交易币别配置
+     */
+    @SaCheckPermission("system:comCurrency:edit")
+    @Log(title = "交易币别配置", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody ComCurrencyBo bo) {
+        return toAjax(comCurrencyService.updateByBo(bo));
+    }
+
+    /**
+     * 删除交易币别配置
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("system:comCurrency:remove")
+    @Log(title = "交易币别配置", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(comCurrencyService.deleteWithValidByIds(List.of(ids), true));
+    }
+
+    /**
+     * 状态修改
+     */
+    @SaCheckPermission("system:comCurrency:edit")
+    @Log(title = "交易币别配置", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public R<Void> changeStatus(@RequestBody ComCurrencyBo bo) {
+        return toAjax(comCurrencyService.updateStatus(bo));
+    }
+}

+ 118 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/ComRevenueExpenseController.java

@@ -0,0 +1,118 @@
+package org.dromara.system.controller.system;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.system.domain.bo.ComCurrencyBo;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.system.domain.vo.ComRevenueExpenseVo;
+import org.dromara.system.domain.bo.ComRevenueExpenseBo;
+import org.dromara.system.service.IComRevenueExpenseService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 收入费用设定
+ * 前端访问路由地址为:/system/revenueExpense
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/revenueExpense")
+public class ComRevenueExpenseController extends BaseController {
+
+    private final IComRevenueExpenseService comRevenueExpenseService;
+
+    /**
+     * 查询收入费用设定列表
+     */
+//    @SaCheckPermission("system:revenueExpense:list")
+    @GetMapping("/list")
+    public TableDataInfo<ComRevenueExpenseVo> list(ComRevenueExpenseBo bo, PageQuery pageQuery) {
+        return comRevenueExpenseService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出收入费用设定列表
+     */
+    @SaCheckPermission("system:revenueExpense:export")
+    @Log(title = "收入费用设定", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(ComRevenueExpenseBo bo, HttpServletResponse response) {
+        List<ComRevenueExpenseVo> list = comRevenueExpenseService.queryList(bo);
+        ExcelUtil.exportExcel(list, "收入费用设定", ComRevenueExpenseVo.class, response);
+    }
+
+    /**
+     * 获取收入费用设定详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("system:revenueExpense:query")
+    @GetMapping("/{id}")
+    public R<ComRevenueExpenseVo> getInfo(@NotNull(message = "主键不能为空")
+                                          @PathVariable("id") Long id) {
+        return R.ok(comRevenueExpenseService.queryById(id));
+    }
+
+    /**
+     * 新增收入费用设定
+     */
+    @SaCheckPermission("system:revenueExpense:add")
+    @Log(title = "收入费用设定", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody ComRevenueExpenseBo bo) {
+        return toAjax(comRevenueExpenseService.insertByBo(bo));
+    }
+
+    /**
+     * 修改收入费用设定
+     */
+    @SaCheckPermission("system:revenueExpense:edit")
+    @Log(title = "收入费用设定", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody ComRevenueExpenseBo bo) {
+        return toAjax(comRevenueExpenseService.updateByBo(bo));
+    }
+
+    /**
+     * 删除收入费用设定
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("system:revenueExpense:remove")
+    @Log(title = "收入费用设定", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(comRevenueExpenseService.deleteWithValidByIds(List.of(ids), true));
+    }
+
+
+    /**
+     * 状态修改
+     */
+    @SaCheckPermission("system:revenueExpense:edit")
+    @Log(title = "收入费用设定", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public R<Void> changeStatus(@RequestBody ComCurrencyBo bo) {
+        return toAjax(comRevenueExpenseService.updateStatus(bo));
+    }
+}

+ 67 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/ComCurrency.java

@@ -0,0 +1,67 @@
+package org.dromara.system.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 交易币别配置对象 com_currency
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("com_currency")
+public class ComCurrency extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 货币编码
+     */
+    private String currencyCode;
+
+    /**
+     * 货币名称
+     */
+    private String currencyName;
+
+    /**
+     * 是否显示(0-显示,1-不显示)
+     */
+    private String isShow;
+
+    /**
+     * 数据来源
+     */
+    private String dataSource;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 77 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/ComRevenueExpense.java

@@ -0,0 +1,77 @@
+package org.dromara.system.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 收入费用设定对象 com_revenue_expense
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("com_revenue_expense")
+public class ComRevenueExpense extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 编码
+     */
+    private String revenueCode;
+
+    /**
+     * 费用名称
+     */
+    private String revenueName;
+
+    /**
+     * 费用类(0 是  1否)
+     */
+    private String expenseFlag;
+
+    /**
+     * 收入类(0 是  1否)
+     */
+    private String revenueFlag;
+
+    /**
+     * 是否显示(0-显示,1-不显示)
+     */
+    private String isShow;
+
+    /**
+     * 数据来源
+     */
+    private String dataSource;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 60 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/ComCurrencyBo.java

@@ -0,0 +1,60 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.system.domain.ComCurrency;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 交易币别配置业务对象 com_currency
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = ComCurrency.class, reverseConvertGenerate = false)
+public class ComCurrencyBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 货币编码
+     */
+    private String currencyCode;
+
+    /**
+     * 货币名称
+     */
+    @NotBlank(message = "货币名称不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String currencyName;
+
+    /**
+     * 是否显示(0-显示,1-不显示)
+     */
+    private String isShow;
+
+    /**
+     * 数据来源
+     */
+    private String dataSource;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 72 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/ComRevenueExpenseBo.java

@@ -0,0 +1,72 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.system.domain.ComRevenueExpense;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 收入费用设定业务对象 com_revenue_expense
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = ComRevenueExpense.class, reverseConvertGenerate = false)
+public class ComRevenueExpenseBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 编码
+     */
+    private String revenueCode;
+
+    /**
+     * 费用名称
+     */
+    @NotBlank(message = "费用名称不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String revenueName;
+
+    /**
+     * 费用类(0 是  1否)
+     */
+    @NotBlank(message = "费用类(0 是  1否)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String expenseFlag;
+
+    /**
+     * 收入类(0 是  1否)
+     */
+    @NotBlank(message = "收入类(0 是  1否)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String revenueFlag;
+
+    /**
+     * 是否显示(0-显示,1-不显示)
+     */
+    private String isShow;
+
+    /**
+     * 数据来源
+     */
+    private String dataSource;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 76 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/ComCurrencyVo.java

@@ -0,0 +1,76 @@
+package org.dromara.system.domain.vo;
+
+import org.dromara.system.domain.ComCurrency;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 交易币别配置视图对象 com_currency
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = ComCurrency.class)
+public class ComCurrencyVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 货币编码
+     */
+    @ExcelProperty(value = "货币编码")
+    private String currencyCode;
+
+    /**
+     * 货币名称
+     */
+    @ExcelProperty(value = "货币名称")
+    private String currencyName;
+
+    /**
+     * 是否显示(0-显示,1-不显示)
+     */
+    @ExcelProperty(value = "是否显示", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_platform_yes_no")
+    private String isShow;
+
+    /**
+     * 数据来源
+     */
+    @ExcelProperty(value = "数据来源")
+    private String dataSource;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
+    private String status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 90 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/ComRevenueExpenseVo.java

@@ -0,0 +1,90 @@
+package org.dromara.system.domain.vo;
+
+import org.dromara.system.domain.ComRevenueExpense;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 收入费用设定视图对象 com_revenue_expense
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = ComRevenueExpense.class)
+public class ComRevenueExpenseVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 编码
+     */
+    @ExcelProperty(value = "编码")
+    private String revenueCode;
+
+    /**
+     * 费用名称
+     */
+    @ExcelProperty(value = "费用名称")
+    private String revenueName;
+
+    /**
+     * 费用类(0 是  1否)
+     */
+    @ExcelProperty(value = "费用类(0 是  1否)", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_platform_yes_no")
+    private String expenseFlag;
+
+    /**
+     * 收入类(0 是  1否)
+     */
+    @ExcelProperty(value = "收入类(0 是  1否)", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_platform_yes_no")
+    private String revenueFlag;
+
+    /**
+     * 是否显示(0-显示,1-不显示)
+     */
+    @ExcelProperty(value = "是否显示", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_platform_yes_no")
+    private String isShow;
+
+    /**
+     * 数据来源
+     */
+    @ExcelProperty(value = "数据来源")
+    private String dataSource;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
+    private String status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 33 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java

@@ -1,6 +1,7 @@
 package org.dromara.system.dubbo;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.lang.tree.Tree;
 import lombok.RequiredArgsConstructor;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.dromara.system.api.RemoteDeptService;
@@ -11,6 +12,8 @@ import org.dromara.system.service.ISysDeptService;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * 部门服务
@@ -73,4 +76,34 @@ public class RemoteDeptServiceImpl implements RemoteDeptService {
         sysDeptService.insertDept(dept);
         return BeanUtil.copyProperties(dept, RemoteDeptVo.class);
     }
+
+    @Override
+    public List<RemoteDeptVo> selectDeptByIds(List<Long> deptIds) {
+        List<SysDeptVo> sysDeptVos = sysDeptService.selectDeptByIds(deptIds);
+        return BeanUtil.copyToList(sysDeptVos, RemoteDeptVo.class);
+    }
+
+    @Override
+    public List<Tree<Long>> selectDeptTreeList(RemoteDeptVo dept) {
+        SysDeptBo sysDeptBo = BeanUtil.copyProperties(dept, SysDeptBo.class);
+        List<Tree<Long>> trees = sysDeptService.selectDeptTreeList(sysDeptBo);
+        return trees;
+    }
+
+    @Override
+    public List<Tree<Long>> buildDeptTreeSelect(List<RemoteDeptVo> depts) {
+        List<Tree<Long>> trees = sysDeptService.buildDeptTreeSelect(BeanUtil.copyToList(depts, SysDeptVo.class));
+        return trees;
+    }
+
+    @Override
+    public RemoteDeptVo selectDeptById(Long deptId) {
+        SysDeptVo sysDeptVo = sysDeptService.selectDeptById(deptId);
+        return BeanUtil.copyProperties(sysDeptVo, RemoteDeptVo.class);
+    }
+
+    @Override
+    public Map<Long, String> selectDeptNameByIds(Set<Long> ids) {
+        return sysDeptService.selectDeptNameByIds(ids);
+    }
 }

+ 15 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/ComCurrencyMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.system.mapper;
+
+import org.dromara.system.domain.ComCurrency;
+import org.dromara.system.domain.vo.ComCurrencyVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 交易币别配置Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+public interface ComCurrencyMapper extends BaseMapperPlus<ComCurrency, ComCurrencyVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/ComRevenueExpenseMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.system.mapper;
+
+import org.dromara.system.domain.ComRevenueExpense;
+import org.dromara.system.domain.vo.ComRevenueExpenseVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 收入费用设定Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+public interface ComRevenueExpenseMapper extends BaseMapperPlus<ComRevenueExpense, ComRevenueExpenseVo> {
+
+}

+ 76 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/IComCurrencyService.java

@@ -0,0 +1,76 @@
+package org.dromara.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.system.domain.ComCurrency;
+import org.dromara.system.domain.bo.OrderPaySetBo;
+import org.dromara.system.domain.vo.ComCurrencyVo;
+import org.dromara.system.domain.bo.ComCurrencyBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 交易币别配置Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+public interface IComCurrencyService extends IService<ComCurrency> {
+
+    /**
+     * 查询交易币别配置
+     *
+     * @param id 主键
+     * @return 交易币别配置
+     */
+    ComCurrencyVo queryById(Long id);
+
+    /**
+     * 分页查询交易币别配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 交易币别配置分页列表
+     */
+    TableDataInfo<ComCurrencyVo> queryPageList(ComCurrencyBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的交易币别配置列表
+     *
+     * @param bo 查询条件
+     * @return 交易币别配置列表
+     */
+    List<ComCurrencyVo> queryList(ComCurrencyBo bo);
+
+    /**
+     * 新增交易币别配置
+     *
+     * @param bo 交易币别配置
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(ComCurrencyBo bo);
+
+    /**
+     * 修改交易币别配置
+     *
+     * @param bo 交易币别配置
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(ComCurrencyBo bo);
+
+    /**
+     * 修改状态
+     */
+    int updateStatus(ComCurrencyBo bo);
+
+    /**
+     * 校验并批量删除交易币别配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 76 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/IComRevenueExpenseService.java

@@ -0,0 +1,76 @@
+package org.dromara.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.system.domain.ComRevenueExpense;
+import org.dromara.system.domain.bo.ComCurrencyBo;
+import org.dromara.system.domain.vo.ComRevenueExpenseVo;
+import org.dromara.system.domain.bo.ComRevenueExpenseBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 收入费用设定Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+public interface IComRevenueExpenseService extends IService<ComRevenueExpense> {
+
+    /**
+     * 查询收入费用设定
+     *
+     * @param id 主键
+     * @return 收入费用设定
+     */
+    ComRevenueExpenseVo queryById(Long id);
+
+    /**
+     * 分页查询收入费用设定列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 收入费用设定分页列表
+     */
+    TableDataInfo<ComRevenueExpenseVo> queryPageList(ComRevenueExpenseBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的收入费用设定列表
+     *
+     * @param bo 查询条件
+     * @return 收入费用设定列表
+     */
+    List<ComRevenueExpenseVo> queryList(ComRevenueExpenseBo bo);
+
+    /**
+     * 新增收入费用设定
+     *
+     * @param bo 收入费用设定
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(ComRevenueExpenseBo bo);
+
+    /**
+     * 修改收入费用设定
+     *
+     * @param bo 收入费用设定
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(ComRevenueExpenseBo bo);
+
+    /**
+     * 修改状态
+     */
+    int updateStatus(ComCurrencyBo bo);
+
+    /**
+     * 校验并批量删除收入费用设定信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 4 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDeptService.java

@@ -7,6 +7,8 @@ import org.dromara.system.domain.bo.SysDeptBo;
 import org.dromara.system.domain.vo.SysDeptVo;
 
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * 部门管理 服务层
@@ -152,4 +154,6 @@ public interface ISysDeptService {
      * @return 部门列表
      */
     List<SysDeptVo> selectDeptsSimple();
+
+    Map<Long, String> selectDeptNameByIds(Set<Long> ids);
 }

+ 40 - 8
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/ComCompanyServiceImpl.java

@@ -6,18 +6,24 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.constant.Constants;
+import org.dromara.common.core.enums.SysPlatformYesNo;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.redis.utils.SequenceUtils;
 import org.dromara.system.domain.ComCompany;
+import org.dromara.system.domain.SysDept;
 import org.dromara.system.domain.bo.ComCompanyBo;
+import org.dromara.system.domain.bo.SysDeptBo;
 import org.dromara.system.domain.vo.ComCompanyVo;
 import org.dromara.system.mapper.ComCompanyMapper;
 import org.dromara.system.mapper.SysDeptMapper;
 import org.dromara.system.service.IComCompanyService;
+import org.dromara.system.service.ISysDeptService;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.time.Duration;
 import java.util.*;
@@ -33,12 +39,17 @@ import java.util.*;
 @Service
 public class ComCompanyServiceImpl extends ServiceImpl<ComCompanyMapper, ComCompany> implements IComCompanyService {
 
+    private static final String DEPT_NO_KEY = "sys_dept:dept_no";
     private static final String COMPANY_CODE_KEY = "com_company:company_code";
 
     private final ComCompanyMapper baseMapper;
 
     private final SysDeptMapper deptMapper;
 
+    private final ISysDeptService sysDeptService;
+    ;
+
+
     /**
      * 查询公司信息
      *
@@ -115,17 +126,38 @@ public class ComCompanyServiceImpl extends ServiceImpl<ComCompanyMapper, ComComp
      * @param bo 公司信息
      * @return 是否新增成功
      */
+    @Transactional(rollbackFor = Exception.class)
     @Override
     public Boolean insertByBo(ComCompanyBo bo) {
-
-        bo.setCompanyCode(SequenceUtils.nextPaddedIdStr(COMPANY_CODE_KEY, Duration.ofDays(3650), 4));
-        ComCompany add = MapstructUtils.convert(bo, ComCompany.class);
-        validEntityBeforeSave(add);
-        boolean flag = baseMapper.insert(add) > 0;
-        if (flag) {
-            bo.setId(add.getId());
+        try {
+            // 1. 生成公司编码
+            bo.setCompanyCode(SequenceUtils.nextPaddedIdStr(COMPANY_CODE_KEY, Duration.ofDays(3650), 4));
+
+            // 2. 转换并校验
+            ComCompany company = MapstructUtils.convert(bo, ComCompany.class);
+            validEntityBeforeSave(company);
+            int insert = baseMapper.insert(company);
+            if (insert > 0) {
+                bo.setId(company.getId());
+                log.info("新增公司信息成功:{}", company);
+            }
+
+            // 4. 创建根部门(以公司名为部门名)
+            SysDeptBo deptBo = new SysDeptBo();
+            deptBo.setDeptNo(SequenceUtils.nextPaddedIdStr(DEPT_NO_KEY, Duration.ofDays(3650), 4));
+            deptBo.setCompanyId(company.getId());
+            deptBo.setDeptName(company.getCompanyName());
+            deptBo.setParentId(100L); // 通常为 顶级部门的id
+            deptBo.setIsCompanyFlag(SysPlatformYesNo.YES.getCode());
+
+            // 5. 插入部门
+            sysDeptService.insertDept(deptBo);
+
+            return true; // 表示公司及根部门创建成功
+        } catch (Exception e) {
+            log.error("新增公司信息失败:{}", e.getMessage(), e);
+            throw new RuntimeException(e);
         }
-        return flag;
     }
 
     /**

+ 158 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/ComCurrencyServiceImpl.java

@@ -0,0 +1,158 @@
+package org.dromara.system.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.redis.utils.SequenceUtils;
+import org.dromara.system.domain.OrderPaySet;
+import org.dromara.system.domain.bo.OrderPaySetBo;
+import org.springframework.stereotype.Service;
+import org.dromara.system.domain.bo.ComCurrencyBo;
+import org.dromara.system.domain.vo.ComCurrencyVo;
+import org.dromara.system.domain.ComCurrency;
+import org.dromara.system.mapper.ComCurrencyMapper;
+import org.dromara.system.service.IComCurrencyService;
+
+import java.time.Duration;
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 交易币别配置Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class ComCurrencyServiceImpl extends ServiceImpl<ComCurrencyMapper, ComCurrency> implements IComCurrencyService {
+
+    private static final String CURRENCY_CODE_KEY = "com_currency:currency_code";
+
+    private final ComCurrencyMapper baseMapper;
+
+    /**
+     * 查询交易币别配置
+     *
+     * @param id 主键
+     * @return 交易币别配置
+     */
+    @Override
+    public ComCurrencyVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询交易币别配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 交易币别配置分页列表
+     */
+    @Override
+    public TableDataInfo<ComCurrencyVo> queryPageList(ComCurrencyBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<ComCurrency> lqw = buildQueryWrapper(bo);
+        Page<ComCurrencyVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的交易币别配置列表
+     *
+     * @param bo 查询条件
+     * @return 交易币别配置列表
+     */
+    @Override
+    public List<ComCurrencyVo> queryList(ComCurrencyBo bo) {
+        LambdaQueryWrapper<ComCurrency> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<ComCurrency> buildQueryWrapper(ComCurrencyBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<ComCurrency> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(ComCurrency::getId);
+        lqw.eq(StringUtils.isNotBlank(bo.getCurrencyCode()), ComCurrency::getCurrencyCode, bo.getCurrencyCode());
+        lqw.like(StringUtils.isNotBlank(bo.getCurrencyName()), ComCurrency::getCurrencyName, bo.getCurrencyName());
+        lqw.eq(StringUtils.isNotBlank(bo.getIsShow()), ComCurrency::getIsShow, bo.getIsShow());
+        lqw.eq(StringUtils.isNotBlank(bo.getDataSource()), ComCurrency::getDataSource, bo.getDataSource());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), ComCurrency::getStatus, bo.getStatus());
+        return lqw;
+    }
+
+    /**
+     * 新增交易币别配置
+     *
+     * @param bo 交易币别配置
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(ComCurrencyBo bo) {
+        bo.setCurrencyCode(SequenceUtils.nextPaddedIdStr(CURRENCY_CODE_KEY, Duration.ofDays(3650), 4));
+        ComCurrency add = MapstructUtils.convert(bo, ComCurrency.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改状态
+     *
+     * @param bo 信息
+     * @return 结果
+     */
+    @Override
+    public int updateStatus(ComCurrencyBo bo) {
+        ComCurrency currency = new ComCurrency();
+        currency.setId(bo.getId());
+        currency.setIsShow(bo.getIsShow());
+        return baseMapper.updateById(currency);
+    }
+
+    /**
+     * 修改交易币别配置
+     *
+     * @param bo 交易币别配置
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(ComCurrencyBo bo) {
+        ComCurrency update = MapstructUtils.convert(bo, ComCurrency.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(ComCurrency entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除交易币别配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 160 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/ComRevenueExpenseServiceImpl.java

@@ -0,0 +1,160 @@
+package org.dromara.system.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.redis.utils.SequenceUtils;
+import org.dromara.system.domain.ComCurrency;
+import org.dromara.system.domain.bo.ComCurrencyBo;
+import org.springframework.stereotype.Service;
+import org.dromara.system.domain.bo.ComRevenueExpenseBo;
+import org.dromara.system.domain.vo.ComRevenueExpenseVo;
+import org.dromara.system.domain.ComRevenueExpense;
+import org.dromara.system.mapper.ComRevenueExpenseMapper;
+import org.dromara.system.service.IComRevenueExpenseService;
+
+import java.time.Duration;
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 收入费用设定Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-04
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class ComRevenueExpenseServiceImpl extends ServiceImpl<ComRevenueExpenseMapper, ComRevenueExpense> implements IComRevenueExpenseService {
+
+    private static final String REVENUE_CODE_KEY = "com_revenue_expense:revenue_code";
+
+    private final ComRevenueExpenseMapper baseMapper;
+
+    /**
+     * 查询收入费用设定
+     *
+     * @param id 主键
+     * @return 收入费用设定
+     */
+    @Override
+    public ComRevenueExpenseVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询收入费用设定列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 收入费用设定分页列表
+     */
+    @Override
+    public TableDataInfo<ComRevenueExpenseVo> queryPageList(ComRevenueExpenseBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<ComRevenueExpense> lqw = buildQueryWrapper(bo);
+        Page<ComRevenueExpenseVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的收入费用设定列表
+     *
+     * @param bo 查询条件
+     * @return 收入费用设定列表
+     */
+    @Override
+    public List<ComRevenueExpenseVo> queryList(ComRevenueExpenseBo bo) {
+        LambdaQueryWrapper<ComRevenueExpense> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<ComRevenueExpense> buildQueryWrapper(ComRevenueExpenseBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<ComRevenueExpense> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(ComRevenueExpense::getId);
+        lqw.eq(StringUtils.isNotBlank(bo.getRevenueCode()), ComRevenueExpense::getRevenueCode, bo.getRevenueCode());
+        lqw.like(StringUtils.isNotBlank(bo.getRevenueName()), ComRevenueExpense::getRevenueName, bo.getRevenueName());
+        lqw.eq(StringUtils.isNotBlank(bo.getExpenseFlag()), ComRevenueExpense::getExpenseFlag, bo.getExpenseFlag());
+        lqw.eq(StringUtils.isNotBlank(bo.getRevenueFlag()), ComRevenueExpense::getRevenueFlag, bo.getRevenueFlag());
+        lqw.eq(StringUtils.isNotBlank(bo.getIsShow()), ComRevenueExpense::getIsShow, bo.getIsShow());
+        lqw.eq(StringUtils.isNotBlank(bo.getDataSource()), ComRevenueExpense::getDataSource, bo.getDataSource());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), ComRevenueExpense::getStatus, bo.getStatus());
+        return lqw;
+    }
+
+    /**
+     * 新增收入费用设定
+     *
+     * @param bo 收入费用设定
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(ComRevenueExpenseBo bo) {
+        bo.setRevenueCode(SequenceUtils.nextPaddedIdStr(REVENUE_CODE_KEY, Duration.ofDays(3650), 4));
+        ComRevenueExpense add = MapstructUtils.convert(bo, ComRevenueExpense.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改收入费用设定
+     *
+     * @param bo 收入费用设定
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(ComRevenueExpenseBo bo) {
+        ComRevenueExpense update = MapstructUtils.convert(bo, ComRevenueExpense.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 修改状态
+     *
+     * @param bo 信息
+     * @return 结果
+     */
+    @Override
+    public int updateStatus(ComCurrencyBo bo) {
+        ComRevenueExpense revenueExpense = new ComRevenueExpense();
+        revenueExpense.setId(bo.getId());
+        revenueExpense.setIsShow(bo.getIsShow());
+        return baseMapper.updateById(revenueExpense);
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(ComRevenueExpense entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除收入费用设定信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

Некоторые файлы не были показаны из-за большого количества измененных файлов