Procházet zdrojové kódy

feat(customer): 新增客户部门信息管理功能

- 添加客户部门实体类 CustomerDept 及相关业务对象
- 实现客户部门的增删改查控制器 CustomerDeptController
- 创建客户部门 Mapper 接口及 XML 配置文件
- 在客户信息服务中集成部门初始化逻辑
- 调整文件分类与文件信息实体继承结构
- 扩展部门服务支持平台编码查询与插入操作
- 优化部门数据范围拦截器忽略表配置
- 增强部门实体预算与绑定相关字段
- 完善远程部门服务接口定义与实现
hurx před 3 dny
rodič
revize
6a853ae1ea
56 změnil soubory, kde provedl 2837 přidání a 29 odebrání
  1. 4 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDeptService.java
  2. 5 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/vo/RemoteDeptVo.java
  3. 4 2
      ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java
  4. 4 1
      ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/PlatformTenantLineHandler.java
  5. 100 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/CustomerDeptController.java
  6. 106 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/GroupCustomerController.java
  7. 138 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/CustomerDept.java
  8. 7 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/CustomerInfo.java
  9. 2 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/CustomerSalesInfo.java
  10. 62 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/GroupCustomer.java
  11. 135 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/CustomerDeptBo.java
  12. 7 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/CustomerInfoBo.java
  13. 1 2
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/CustomerSalesInfoBo.java
  14. 54 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/GroupCustomerBo.java
  15. 160 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerDeptVo.java
  16. 7 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerInfoVo.java
  17. 2 2
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerSalesInfoVo.java
  18. 88 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/GroupCustomerVo.java
  19. 15 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerDeptMapper.java
  20. 15 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/GroupCustomerMapper.java
  21. 60 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerDeptService.java
  22. 70 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/IGroupCustomerService.java
  23. 148 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerDeptServiceImpl.java
  24. 31 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerInfoServiceImpl.java
  25. 4 5
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerSalesInfoServiceImpl.java
  26. 243 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/GroupCustomerServiceImpl.java
  27. 7 0
      ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/CustomerDeptMapper.xml
  28. 7 0
      ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/GroupCustomerMapper.xml
  29. 2 1
      ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/FileCategory.java
  30. 2 1
      ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/FileInfo.java
  31. 5 4
      ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/bo/FileCategoryBo.java
  32. 5 4
      ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/bo/FileInfoBo.java
  33. 105 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/InvoiceTypeController.java
  34. 105 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysCompanyController.java
  35. 62 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/InvoiceType.java
  36. 107 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysCompany.java
  37. 29 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDept.java
  38. 55 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/InvoiceTypeBo.java
  39. 103 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysCompanyBo.java
  40. 30 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDeptBo.java
  41. 69 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/InvoiceTypeVo.java
  42. 122 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysCompanyVo.java
  43. 28 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysDeptVo.java
  44. 16 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java
  45. 15 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/InvoiceTypeMapper.java
  46. 15 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysCompanyMapper.java
  47. 11 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java
  48. 70 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/IInvoiceTypeService.java
  49. 70 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysCompanyService.java
  50. 2 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDeptService.java
  51. 137 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/InvoiceTypeServiceImpl.java
  52. 144 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysCompanyServiceImpl.java
  53. 16 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java
  54. 7 0
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/InvoiceTypeMapper.xml
  55. 7 0
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysCompanyMapper.xml
  56. 12 6
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml

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

@@ -34,4 +34,8 @@ public interface RemoteDeptService {
      */
     List<RemoteDeptVo> selectDeptsByList();
 
+    RemoteDeptVo selectParentDeptByPlatformCode(String platformCode);
+
+    RemoteDeptVo insertDept(RemoteDeptVo vo);
+
 }

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

@@ -34,4 +34,9 @@ public class RemoteDeptVo implements Serializable {
      */
     private String deptName;
 
+    private Long customerId;
+
+
+    private String platformCode;
+
 }

+ 4 - 2
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java

@@ -42,7 +42,6 @@ public class PlatformDataScopeInterceptor implements Interceptor {
         "sys_user_post",
         "sys_config",
         "sys_dict",
-        "sys_dict_data",
         "sys_dict_type",
         "sys_dict_data",
         "sys_oss",
@@ -53,7 +52,10 @@ public class PlatformDataScopeInterceptor implements Interceptor {
         "maintenance_server_item",
         "maintenance_server_time",
         "maintenance_type",
-        "customer_info_tag"
+        "customer_info_tag",
+        "invoice_type",
+        "sys_file_category",
+        "sys_company"
         // 注意:前缀匹配需特殊处理(如 qrtz_),见 isIgnoreTable 方法
     ));
 

+ 4 - 1
ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/PlatformTenantLineHandler.java

@@ -38,7 +38,10 @@ public class PlatformTenantLineHandler implements TenantLineHandler {
         "qrtz_",
         "maintenance_server_item",
         "maintenance_server_time",
-        "maintenance_type"
+        "maintenance_type",
+        "invoice_type",
+        "sys_file_category",
+        "sys_company"
 
         // 注意:前缀匹配(如 qrtz_)在 ignoreTable 中单独处理
     ));

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

@@ -0,0 +1,100 @@
+package org.dromara.customer.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.customer.domain.vo.CustomerDeptVo;
+import org.dromara.customer.domain.bo.CustomerDeptBo;
+import org.dromara.customer.service.ICustomerDeptService;
+
+/**
+ * 客户部门信息
+ * 前端访问路由地址为:/customer/customerDept
+ *
+ * @author LionLi
+ * @date 2025-12-18
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/customerDept")
+public class CustomerDeptController extends BaseController {
+
+    private final ICustomerDeptService customerDeptService;
+
+    /**
+     * 查询客户部门信息列表
+     */
+    @GetMapping("/list")
+    public R<List<CustomerDeptVo>> list(CustomerDeptBo bo) {
+        List<CustomerDeptVo> list = customerDeptService.queryList(bo);
+        return R.ok(list);
+    }
+
+    /**
+     * 导出客户部门信息列表
+     */
+    @Log(title = "客户部门信息", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(CustomerDeptBo bo, HttpServletResponse response) {
+        List<CustomerDeptVo> list = customerDeptService.queryList(bo);
+        ExcelUtil.exportExcel(list, "客户部门信息", CustomerDeptVo.class, response);
+    }
+
+    /**
+     * 获取客户部门信息详细信息
+     *
+     * @param id 主键
+     */
+    @GetMapping("/{id}")
+    public R<CustomerDeptVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(customerDeptService.queryById(id));
+    }
+
+    /**
+     * 新增客户部门信息
+     */
+    @Log(title = "客户部门信息", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody CustomerDeptBo bo) {
+        return toAjax(customerDeptService.insertByBo(bo));
+    }
+
+    /**
+     * 修改客户部门信息
+     */
+    @Log(title = "客户部门信息", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody CustomerDeptBo bo) {
+        return toAjax(customerDeptService.updateByBo(bo));
+    }
+
+    /**
+     * 删除客户部门信息
+     *
+     * @param ids 主键串
+     */
+    @Log(title = "客户部门信息", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(customerDeptService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 106 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/GroupCustomerController.java

@@ -0,0 +1,106 @@
+package org.dromara.customer.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.customer.domain.vo.GroupCustomerVo;
+import org.dromara.customer.domain.bo.GroupCustomerBo;
+import org.dromara.customer.service.IGroupCustomerService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 集团客户关系
+ * 前端访问路由地址为:/customer/groupCustomer
+ *
+ * @author LionLi
+ * @date 2025-12-17
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/groupCustomer")
+public class GroupCustomerController extends BaseController {
+
+    private final IGroupCustomerService groupCustomerService;
+
+    /**
+     * 查询集团客户关系列表
+     */
+    @SaCheckPermission("customer:groupCustomer:list")
+    @GetMapping("/list")
+    public TableDataInfo<GroupCustomerVo> list(GroupCustomerBo bo, PageQuery pageQuery) {
+        return groupCustomerService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出集团客户关系列表
+     */
+    @SaCheckPermission("customer:groupCustomer:export")
+    @Log(title = "集团客户关系", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(GroupCustomerBo bo, HttpServletResponse response) {
+        List<GroupCustomerVo> list = groupCustomerService.queryList(bo);
+        ExcelUtil.exportExcel(list, "集团客户关系", GroupCustomerVo.class, response);
+    }
+
+    /**
+     * 获取集团客户关系详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("customer:groupCustomer:query")
+    @GetMapping("/{id}")
+    public R<GroupCustomerVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(groupCustomerService.queryById(id));
+    }
+
+    /**
+     * 新增集团客户关系
+     */
+    @SaCheckPermission("customer:groupCustomer:add")
+    @Log(title = "集团客户关系", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody GroupCustomerBo bo) {
+        return toAjax(groupCustomerService.insertByBo(bo));
+    }
+
+    /**
+     * 修改集团客户关系
+     */
+    @SaCheckPermission("customer:groupCustomer:edit")
+    @Log(title = "集团客户关系", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody GroupCustomerBo bo) {
+        return toAjax(groupCustomerService.updateByBo(bo));
+    }
+
+    /**
+     * 删除集团客户关系
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("customer:groupCustomer:remove")
+    @Log(title = "集团客户关系", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(groupCustomerService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 138 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/CustomerDept.java

@@ -0,0 +1,138 @@
+package org.dromara.customer.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+import java.math.BigDecimal;
+
+/**
+ * 客户部门信息对象 customer_dept
+ *
+ * @author LionLi
+ * @date 2025-12-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("customer_dept")
+public class CustomerDept extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 部门编号
+     */
+    private String deptNo;
+
+    /**
+     * 部门名称
+     */
+    private String deptName;
+
+    /**
+     * 父部门id
+     */
+    private Long parentId;
+
+    /**
+     * 祖级列表
+     */
+    private String ancestors;
+
+    /**
+     * 客户编号
+     */
+    private Long customerId;
+
+    /**
+     * 部门层级(如1级、2级等)
+     */
+    private Long departmentLevel;
+
+    /**
+     * 年度预算
+     */
+    private BigDecimal yearlyBudget;
+
+    /**
+     * 已使用预算
+     */
+    private BigDecimal usedBudget;
+
+    /**
+     * 月度限额
+     */
+    private BigDecimal monthLimit;
+
+    /**
+     * 月度已用预算
+     */
+    private BigDecimal monthUsedBudget;
+
+    /**
+     * 绑定状态
+     */
+    private String bindStatus;
+
+    /**
+     * 绑定地址
+     */
+    private String bindAddress;
+
+    /**
+     * 部门负责人
+     */
+    private String deptManage;
+
+    /**
+     * 是否限制预算
+     */
+    private String isLimit;
+
+    /**
+     * 所选年份
+     */
+    private String selectYear;
+
+    /**
+     * 费用类型
+     */
+    private String expenseType;
+
+    /**
+     * 年度剩余预算
+     */
+    private Long residueYearlyBudget;
+
+    /**
+     * 充值金额
+     */
+    private Long recharge;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 7 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/CustomerInfo.java

@@ -54,6 +54,8 @@ public class CustomerInfo extends TenantEntity {
      */
     private String businessCustomerName;
 
+    private Long belongDeptId;
+
     /**
      * 企业简称
      */
@@ -119,6 +121,11 @@ public class CustomerInfo extends TenantEntity {
      */
     private String invoiceTop;
 
+    /**
+     * 是否集团客户 0=是 1=否
+     */
+    private String isGroup;
+
     /**
      * 详细地址(注册地址)
      */

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

@@ -4,6 +4,7 @@ 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;
@@ -51,7 +52,7 @@ public class CustomerSalesInfo extends TenantEntity {
     /**
      * 账期(如:30天)
      */
-    private String accountPeriod;
+    private Integer accountPeriod;
 
     /**
      * 账单日(每月几号)

+ 62 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/GroupCustomer.java

@@ -0,0 +1,62 @@
+package org.dromara.customer.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 集团客户关系对象 group_customer
+ *
+ * @author LionLi
+ * @date 2025-12-17
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("group_customer")
+public class GroupCustomer extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 集团客户id
+     */
+    private Long groupCustomerId;
+
+    /**
+     * 客户id
+     */
+    private Long customerId;
+
+    /**
+     * 客户等级
+     */
+    private String customerLevel;
+
+    /**
+     * 顶级客户id
+     */
+    private Long topCustomerId;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 135 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/CustomerDeptBo.java

@@ -0,0 +1,135 @@
+package org.dromara.customer.domain.bo;
+
+import org.dromara.customer.domain.CustomerDept;
+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;
+
+/**
+ * 客户部门信息业务对象 customer_dept
+ *
+ * @author LionLi
+ * @date 2025-12-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = CustomerDept.class, reverseConvertGenerate = false)
+public class CustomerDeptBo extends BaseEntity {
+
+    /**
+     * ID
+     */
+    private Long id;
+
+    /**
+     * 部门编号
+     */
+    private String deptNo;
+
+    /**
+     * 部门名称
+     */
+    @NotBlank(message = "部门名称不能为空", groups = {AddGroup.class, EditGroup.class})
+    private String deptName;
+
+    /**
+     * 父部门id
+     */
+    private Long parentId;
+
+    /**
+     * 祖级列表
+     */
+    private String ancestors;
+
+    /**
+     * 客户编号
+     */
+    private Long customerId;
+
+    /**
+     * 部门层级(如1级、2级等)
+     */
+    private Long departmentLevel;
+
+    /**
+     * 年度预算
+     */
+    @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;
+
+    /**
+     * 月度已用预算
+     */
+    private BigDecimal monthUsedBudget;
+
+    /**
+     * 绑定状态
+     */
+    private String bindStatus;
+
+    /**
+     * 绑定地址
+     */
+    private String bindAddress;
+
+    /**
+     * 部门负责人
+     */
+    private String deptManage;
+
+    /**
+     * 是否限制预算
+     */
+    private String isLimit;
+
+    /**
+     * 所选年份
+     */
+    private String selectYear;
+
+    /**
+     * 费用类型
+     */
+    private String expenseType;
+
+    /**
+     * 年度剩余预算
+     */
+    private Long residueYearlyBudget;
+
+    /**
+     * 充值金额
+     */
+    private Long recharge;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 7 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/CustomerInfoBo.java

@@ -42,6 +42,8 @@ public class CustomerInfoBo extends BaseEntity {
     @NotNull(message = "所属公司不能为空", groups = {AddGroup.class, EditGroup.class})
     private Long belongCompanyId;
 
+    private Long belongDeptId;
+
     /**
      * 公司名称
      */
@@ -127,6 +129,11 @@ public class CustomerInfoBo extends BaseEntity {
      */
     private String invoiceTop;
 
+    /**
+     * 是否集团客户 0=是 1=否
+     */
+    private String isGroup;
+
     /**
      * 详细地址(注册地址)
      */

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

@@ -52,8 +52,7 @@ public class CustomerSalesInfoBo extends BaseEntity {
     /**
      * 账期(如:30天)
      */
-    @NotBlank(message = "账期(如:30天)不能为空", groups = {AddGroup.class, EditGroup.class})
-    private String accountPeriod;
+    private Integer accountPeriod;
 
     /**
      * 账单日(每月几号)

+ 54 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/GroupCustomerBo.java

@@ -0,0 +1,54 @@
+package org.dromara.customer.domain.bo;
+
+import org.dromara.customer.domain.GroupCustomer;
+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.*;
+
+/**
+ * 集团客户关系业务对象 group_customer
+ *
+ * @author LionLi
+ * @date 2025-12-17
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = GroupCustomer.class, reverseConvertGenerate = false)
+public class GroupCustomerBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 集团客户id
+     */
+    private Long groupCustomerId;
+
+    /**
+     * 客户id
+     */
+    private Long customerId;
+
+    /**
+     * 客户等级
+     */
+    private String customerLevel;
+
+    /**
+     * 顶级客户id
+     */
+    private Long topCustomerId;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 160 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerDeptVo.java

@@ -0,0 +1,160 @@
+package org.dromara.customer.domain.vo;
+
+import org.dromara.customer.domain.CustomerDept;
+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;
+
+
+/**
+ * 客户部门信息视图对象 customer_dept
+ *
+ * @author LionLi
+ * @date 2025-12-18
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = CustomerDept.class)
+public class CustomerDeptVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @ExcelProperty(value = "ID")
+    private Long id;
+
+    /**
+     * 部门编号
+     */
+    @ExcelProperty(value = "部门编号")
+    private String deptNo;
+
+    /**
+     * 部门名称
+     */
+    @ExcelProperty(value = "部门名称")
+    private String deptName;
+
+    /**
+     * 父部门id
+     */
+    @ExcelProperty(value = "父部门id")
+    private Long parentId;
+
+    /**
+     * 祖级列表
+     */
+    @ExcelProperty(value = "祖级列表")
+    private String ancestors;
+
+    /**
+     * 客户编号
+     */
+    @ExcelProperty(value = "客户编号")
+    private Long customerId;
+
+    /**
+     * 部门层级(如1级、2级等)
+     */
+    @ExcelProperty(value = "部门层级", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "如=1级、2级等")
+    private BigDecimal departmentLevel;
+
+    /**
+     * 年度预算
+     */
+    @ExcelProperty(value = "年度预算")
+    private BigDecimal yearlyBudget;
+
+    /**
+     * 已使用预算
+     */
+    @ExcelProperty(value = "已使用预算")
+    private BigDecimal usedBudget;
+
+    /**
+     * 月度限额
+     */
+    @ExcelProperty(value = "月度限额")
+    private BigDecimal monthLimit;
+
+    /**
+     * 月度已用预算
+     */
+    @ExcelProperty(value = "月度已用预算")
+    private BigDecimal monthUsedBudget;
+
+    /**
+     * 绑定状态
+     */
+    @ExcelProperty(value = "绑定状态")
+    private String bindStatus;
+
+    /**
+     * 绑定地址
+     */
+    @ExcelProperty(value = "绑定地址")
+    private String bindAddress;
+
+    /**
+     * 部门负责人
+     */
+    @ExcelProperty(value = "部门负责人")
+    private String deptManage;
+
+    /**
+     * 是否限制预算
+     */
+    @ExcelProperty(value = "是否限制预算")
+    private String isLimit;
+
+    /**
+     * 所选年份
+     */
+    @ExcelProperty(value = "所选年份")
+    private String selectYear;
+
+    /**
+     * 费用类型
+     */
+    @ExcelProperty(value = "费用类型")
+    private String expenseType;
+
+    /**
+     * 年度剩余预算
+     */
+    @ExcelProperty(value = "年度剩余预算")
+    private Long residueYearlyBudget;
+
+    /**
+     * 充值金额
+     */
+    @ExcelProperty(value = "充值金额")
+    private Long recharge;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_normal_disable")
+    private String status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 7 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerInfoVo.java

@@ -70,6 +70,8 @@ public class CustomerInfoVo implements Serializable {
     @ExcelProperty(value = "工商名称")
     private String businessCustomerName;
 
+    private Long belongDeptId;
+
     /**
      * 企业简称
      */
@@ -148,6 +150,11 @@ public class CustomerInfoVo implements Serializable {
     @ExcelProperty(value = "发票抬头")
     private String invoiceTop;
 
+    /**
+     * 是否集团客户 0=是 1=否
+     */
+    private String isGroup;
+
     /**
      * 详细地址(注册地址)
      */

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

@@ -1,6 +1,7 @@
 package org.dromara.customer.domain.vo;
 
 import java.math.BigDecimal;
+
 import org.dromara.customer.domain.CustomerSalesInfo;
 import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
 import cn.idev.excel.annotation.ExcelProperty;
@@ -14,7 +15,6 @@ import java.io.Serializable;
 import java.util.Date;
 
 
-
 /**
  * 客户销售信息视图对象 customer_sales_info
  *
@@ -64,7 +64,7 @@ public class CustomerSalesInfoVo implements Serializable {
      */
     @ExcelProperty(value = "账期", converter = ExcelDictConvert.class)
     @ExcelDictFormat(readConverterExp = "如=:30天")
-    private String accountPeriod;
+    private Integer accountPeriod;
 
     /**
      * 账单日(每月几号)

+ 88 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/GroupCustomerVo.java

@@ -0,0 +1,88 @@
+package org.dromara.customer.domain.vo;
+
+import org.dromara.customer.domain.GroupCustomer;
+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;
+
+
+/**
+ * 集团客户关系视图对象 group_customer
+ *
+ * @author LionLi
+ * @date 2025-12-17
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = GroupCustomer.class)
+public class GroupCustomerVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 集团客户id
+     */
+    @ExcelProperty(value = "集团客户id")
+    private Long groupCustomerId;
+
+    private String groupCustomerName;
+
+    /**
+     * 客户id
+     */
+    @ExcelProperty(value = "客户id")
+    private Long customerId;
+
+    private String customerName;
+
+    /**
+     * 客户等级
+     */
+    @ExcelProperty(value = "客户等级")
+    private String customerLevel;
+
+    /**
+     * 顶级客户id
+     */
+    @ExcelProperty(value = "顶级客户id")
+    private Long topCustomerId;
+
+    private String topCustomerName;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+    private String topCustomerNo;
+
+    private String industryCategory;
+
+    //信用额
+    private BigDecimal creditAmount;
+
+    //剩余额度
+    private BigDecimal remainingQuota;
+
+    //应收账款
+    private BigDecimal accountsReceivable;
+
+    //到账
+    private Integer accountPeriod;
+}

+ 15 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerDeptMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.customer.mapper;
+
+import org.dromara.customer.domain.CustomerDept;
+import org.dromara.customer.domain.vo.CustomerDeptVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 客户部门信息Mapper接口
+ *
+ * @author LionLi
+ * @date 2025-12-18
+ */
+public interface CustomerDeptMapper extends BaseMapperPlus<CustomerDept, CustomerDeptVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/GroupCustomerMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.customer.mapper;
+
+import org.dromara.customer.domain.GroupCustomer;
+import org.dromara.customer.domain.vo.GroupCustomerVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 集团客户关系Mapper接口
+ *
+ * @author LionLi
+ * @date 2025-12-17
+ */
+public interface GroupCustomerMapper extends BaseMapperPlus<GroupCustomer, GroupCustomerVo> {
+
+}

+ 60 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerDeptService.java

@@ -0,0 +1,60 @@
+package org.dromara.customer.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.customer.domain.CustomerDept;
+import org.dromara.customer.domain.vo.CustomerDeptVo;
+import org.dromara.customer.domain.bo.CustomerDeptBo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 客户部门信息Service接口
+ *
+ * @author LionLi
+ * @date 2025-12-18
+ */
+public interface ICustomerDeptService extends IService<CustomerDept>{
+
+    /**
+     * 查询客户部门信息
+     *
+     * @param id 主键
+     * @return 客户部门信息
+     */
+    CustomerDeptVo queryById(Long id);
+
+
+    /**
+     * 查询符合条件的客户部门信息列表
+     *
+     * @param bo 查询条件
+     * @return 客户部门信息列表
+     */
+    List<CustomerDeptVo> queryList(CustomerDeptBo bo);
+
+    /**
+     * 新增客户部门信息
+     *
+     * @param bo 客户部门信息
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(CustomerDeptBo bo);
+
+    /**
+     * 修改客户部门信息
+     *
+     * @param bo 客户部门信息
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(CustomerDeptBo bo);
+
+    /**
+     * 校验并批量删除客户部门信息信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 70 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/IGroupCustomerService.java

@@ -0,0 +1,70 @@
+package org.dromara.customer.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.customer.domain.GroupCustomer;
+import org.dromara.customer.domain.vo.GroupCustomerVo;
+import org.dromara.customer.domain.bo.GroupCustomerBo;
+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 2025-12-17
+ */
+public interface IGroupCustomerService extends IService<GroupCustomer>{
+
+    /**
+     * 查询集团客户关系
+     *
+     * @param id 主键
+     * @return 集团客户关系
+     */
+    GroupCustomerVo queryById(Long id);
+
+    /**
+     * 分页查询集团客户关系列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 集团客户关系分页列表
+     */
+    TableDataInfo<GroupCustomerVo> queryPageList(GroupCustomerBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的集团客户关系列表
+     *
+     * @param bo 查询条件
+     * @return 集团客户关系列表
+     */
+    List<GroupCustomerVo> queryList(GroupCustomerBo bo);
+
+    /**
+     * 新增集团客户关系
+     *
+     * @param bo 集团客户关系
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(GroupCustomerBo bo);
+
+    /**
+     * 修改集团客户关系
+     *
+     * @param bo 集团客户关系
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(GroupCustomerBo bo);
+
+    /**
+     * 校验并批量删除集团客户关系信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 148 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerDeptServiceImpl.java

@@ -0,0 +1,148 @@
+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 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.customer.domain.bo.CustomerDeptBo;
+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 java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 客户部门信息Service业务层处理
+ *
+ * @author LionLi
+ * @date 2025-12-18
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class CustomerDeptServiceImpl extends ServiceImpl<CustomerDeptMapper, CustomerDept> implements ICustomerDeptService {
+
+    private final CustomerDeptMapper baseMapper;
+
+    /**
+     * 查询客户部门信息
+     *
+     * @param id 主键
+     * @return 客户部门信息
+     */
+    @Override
+    public CustomerDeptVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+
+    /**
+     * 查询符合条件的客户部门信息列表
+     *
+     * @param bo 查询条件
+     * @return 客户部门信息列表
+     */
+    @Override
+    public List<CustomerDeptVo> queryList(CustomerDeptBo bo) {
+        LambdaQueryWrapper<CustomerDept> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    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.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());
+        lqw.eq(bo.getMonthUsedBudget() != null, CustomerDept::getMonthUsedBudget, bo.getMonthUsedBudget());
+        lqw.eq(StringUtils.isNotBlank(bo.getBindStatus()), CustomerDept::getBindStatus, bo.getBindStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getBindAddress()), CustomerDept::getBindAddress, bo.getBindAddress());
+        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
+    public Boolean insertByBo(CustomerDeptBo bo) {
+        CustomerDept info = baseMapper.selectById(bo.getParentId());
+        // 如果父节点不为正常状态,则不允许新增子节点
+        if (!SystemConstants.NORMAL.equals(info.getStatus())) {
+            throw new ServiceException("部门停用,不允许新增");
+        }
+
+        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());
+        }
+        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;
+    }
+
+    /**
+     * 校验并批量删除客户部门信息信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 31 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerInfoServiceImpl.java

@@ -8,7 +8,10 @@ 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.context.PlatformContext;
+import org.dromara.common.core.enums.IsDefault;
+import org.dromara.common.core.enums.SysPlatformCode;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
@@ -18,6 +21,8 @@ import org.dromara.customer.domain.bo.*;
 import org.dromara.customer.domain.vo.*;
 import org.dromara.customer.mapper.*;
 import org.dromara.customer.service.ICustomerInfoService;
+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;
 
@@ -45,6 +50,10 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
     private final EnterpriseScaleMapper enterpriseScaleMapper;
     private final CustomerInfoTagMapper customerInfoTagMapper;
     private final CustomerContractMapper customerContractMapper;
+    private final CustomerDeptMapper customerDeptMapper;
+
+    @DubboReference
+    private RemoteDeptService remoteDeptService;
 
 
     /**
@@ -315,6 +324,8 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
         if (bo == null) {
             return false;
         }
+        String platform = PlatformContext.getPlatform();
+        RemoteDeptVo deptVo = remoteDeptService.selectParentDeptByPlatformCode(platform);
 
         boolean isNew = bo.getId() == null || bo.getId() <= 0;
 
@@ -338,6 +349,26 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
 
         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();

+ 4 - 5
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerSalesInfoServiceImpl.java

@@ -30,7 +30,7 @@ import java.util.Collection;
 @Slf4j
 @RequiredArgsConstructor
 @Service
-public class CustomerSalesInfoServiceImpl  extends ServiceImpl<CustomerSalesInfoMapper, CustomerSalesInfo> implements ICustomerSalesInfoService {
+public class CustomerSalesInfoServiceImpl extends ServiceImpl<CustomerSalesInfoMapper, CustomerSalesInfo> implements ICustomerSalesInfoService {
 
     private final CustomerSalesInfoMapper baseMapper;
 
@@ -41,7 +41,7 @@ public class CustomerSalesInfoServiceImpl  extends ServiceImpl<CustomerSalesInfo
      * @return 客户销售信息
      */
     @Override
-    public CustomerSalesInfoVo queryById(Long id){
+    public CustomerSalesInfoVo queryById(Long id) {
         return baseMapper.selectVoById(id);
     }
 
@@ -79,7 +79,6 @@ public class CustomerSalesInfoServiceImpl  extends ServiceImpl<CustomerSalesInfo
         lqw.eq(bo.getCreditAmount() != null, CustomerSalesInfo::getCreditAmount, bo.getCreditAmount());
         lqw.eq(bo.getRemainingQuota() != null, CustomerSalesInfo::getRemainingQuota, bo.getRemainingQuota());
         lqw.eq(bo.getTemporaryQuota() != null, CustomerSalesInfo::getTemporaryQuota, bo.getTemporaryQuota());
-        lqw.eq(StringUtils.isNotBlank(bo.getAccountPeriod()), CustomerSalesInfo::getAccountPeriod, bo.getAccountPeriod());
         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());
@@ -128,7 +127,7 @@ public class CustomerSalesInfoServiceImpl  extends ServiceImpl<CustomerSalesInfo
     /**
      * 保存前的数据校验
      */
-    private void validEntityBeforeSave(CustomerSalesInfo entity){
+    private void validEntityBeforeSave(CustomerSalesInfo entity) {
         //TODO 做一些数据校验,如唯一约束
     }
 
@@ -141,7 +140,7 @@ public class CustomerSalesInfoServiceImpl  extends ServiceImpl<CustomerSalesInfo
      */
     @Override
     public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if(isValid){
+        if (isValid) {
             //TODO 做一些业务上的校验,判断是否需要校验
         }
         return baseMapper.deleteByIds(ids) > 0;

+ 243 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/GroupCustomerServiceImpl.java

@@ -0,0 +1,243 @@
+package org.dromara.customer.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+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.customer.domain.CustomerSalesInfo;
+import org.dromara.customer.domain.IndustryCategory;
+import org.dromara.customer.domain.vo.CustomerInfoVo;
+import org.dromara.customer.domain.vo.CustomerSalesInfoVo;
+import org.dromara.customer.domain.vo.IndustryCategoryVo;
+import org.dromara.customer.mapper.CustomerInfoMapper;
+import org.dromara.customer.mapper.CustomerSalesInfoMapper;
+import org.dromara.customer.mapper.IndustryCategoryMapper;
+import org.springframework.stereotype.Service;
+import org.dromara.customer.domain.bo.GroupCustomerBo;
+import org.dromara.customer.domain.vo.GroupCustomerVo;
+import org.dromara.customer.domain.GroupCustomer;
+import org.dromara.customer.mapper.GroupCustomerMapper;
+import org.dromara.customer.service.IGroupCustomerService;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * 集团客户关系Service业务层处理
+ *
+ * @author LionLi
+ * @date 2025-12-17
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class GroupCustomerServiceImpl extends ServiceImpl<GroupCustomerMapper, GroupCustomer> implements IGroupCustomerService {
+
+    private final GroupCustomerMapper baseMapper;
+
+    private final CustomerInfoMapper customerInfoMapper;
+
+    private final CustomerSalesInfoMapper customerSalesInfoMapper;
+
+    private final IndustryCategoryMapper industryCategoryMapper;
+
+    /**
+     * 查询集团客户关系
+     *
+     * @param id 主键
+     * @return 集团客户关系
+     */
+    @Override
+    public GroupCustomerVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询集团客户关系列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 集团客户关系分页列表
+     */
+    @Override
+    public TableDataInfo<GroupCustomerVo> queryPageList(GroupCustomerBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<GroupCustomer> lqw = buildQueryWrapper(bo);
+        Page<GroupCustomerVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        List<GroupCustomerVo> records = result.getRecords();
+        if (CollUtil.isNotEmpty(records)) {
+            // 1. 收集所有客户ID(普通、顶级、集团)
+            Set<Long> allCustomerIds = records.stream()
+                .flatMap(vo -> Stream.of(
+                    vo.getCustomerId(),
+                    vo.getTopCustomerId(),
+                    vo.getGroupCustomerId()
+                ))
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+
+            // 2.  用 customerInfoMapper 查询所有客户基本信息
+            List<CustomerInfoVo> customerInfoList = customerInfoMapper.selectVoByIds(allCustomerIds);
+            Map<Long, CustomerInfoVo> customerInfoMap = customerInfoList.stream()
+                .collect(Collectors.toMap(CustomerInfoVo::getId, Function.identity()));
+
+            // 3. 回填所有客户名称和编号
+            records.forEach(vo -> {
+                // 当前客户
+                CustomerInfoVo customer = customerInfoMap.get(vo.getCustomerId());
+                if (customer != null) {
+                    vo.setCustomerName(customer.getCustomerName());
+                }
+
+                // 上级客户
+                CustomerInfoVo topCustomer = customerInfoMap.get(vo.getTopCustomerId());
+                if (topCustomer != null) {
+                    vo.setTopCustomerName(topCustomer.getCustomerName());
+                    vo.setTopCustomerNo(topCustomer.getCustomerNo()); // ✅ 来源统一
+                }
+
+                // 集团客户
+                CustomerInfoVo groupCustomer = customerInfoMap.get(vo.getGroupCustomerId());
+                if (groupCustomer != null) {
+                    vo.setGroupCustomerName(groupCustomer.getCustomerName());
+                }
+            });
+
+            // 4. 提取顶级客户ID(用于销售信息)
+            Set<Long> topCustomerIds = records.stream()
+                .map(GroupCustomerVo::getTopCustomerId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+
+            // 5. 查询销售信息
+            List<CustomerSalesInfoVo> salesInfoList = customerSalesInfoMapper.selectVoList(new LambdaQueryWrapper<CustomerSalesInfo>().in(CustomerSalesInfo::getCustomerId, topCustomerIds));
+            Map<Long, CustomerSalesInfoVo> salesInfoMap = salesInfoList.stream()
+                .collect(Collectors.toMap(CustomerSalesInfoVo::getCustomerId, Function.identity()));
+
+            // 6. 查询行业分类
+            Set<Long> industryCategoryIds = customerInfoList.stream()
+                .map(CustomerInfoVo::getIndustryCategoryId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+
+            final Map<Long, IndustryCategoryVo> categoryMap =
+                industryCategoryIds.isEmpty()
+                    ? Collections.emptyMap()
+                    : industryCategoryMapper.selectVoByIds(industryCategoryIds)
+                    .stream()
+                    .collect(Collectors.toMap(IndustryCategoryVo::getId, Function.identity()));
+
+            // 7. 回填销售信息 + 行业分类
+            records.forEach(vo -> {
+                Long topCustomerId = vo.getTopCustomerId();
+
+                // 销售信息
+                CustomerSalesInfoVo salesInfo = salesInfoMap.get(topCustomerId);
+                if (salesInfo != null) {
+                    vo.setAccountPeriod(salesInfo.getAccountPeriod());
+                    vo.setCreditAmount(salesInfo.getCreditAmount());
+                    vo.setRemainingQuota(salesInfo.getRemainingQuota());
+                }
+
+                // 行业分类:从 customerInfoMap 获取 category ID,再查 name
+                CustomerInfoVo topCustomer = customerInfoMap.get(topCustomerId);
+                if (topCustomer != null && topCustomer.getIndustryCategoryId() != null) {
+                    IndustryCategoryVo category = categoryMap.get(topCustomer.getIndustryCategoryId());
+                    if (category != null) {
+                        vo.setIndustryCategory(category.getIndustryCategoryName());
+                    }
+                }
+            });
+        }
+        return TableDataInfo.build(result);
+    }
+
+    private <T, R> R safeGet(Map<Long, T> map, Long id, Function<T, R> mapper) {
+        T value = map.get(id);
+        return value != null ? mapper.apply(value) : null;
+    }
+
+    /**
+     * 查询符合条件的集团客户关系列表
+     *
+     * @param bo 查询条件
+     * @return 集团客户关系列表
+     */
+    @Override
+    public List<GroupCustomerVo> queryList(GroupCustomerBo bo) {
+        LambdaQueryWrapper<GroupCustomer> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<GroupCustomer> buildQueryWrapper(GroupCustomerBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<GroupCustomer> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(GroupCustomer::getId);
+        lqw.eq(bo.getGroupCustomerId() != null, GroupCustomer::getGroupCustomerId, bo.getGroupCustomerId());
+        lqw.eq(bo.getCustomerId() != null, GroupCustomer::getCustomerId, bo.getCustomerId());
+        lqw.eq(StringUtils.isNotBlank(bo.getCustomerLevel()), GroupCustomer::getCustomerLevel, bo.getCustomerLevel());
+        lqw.eq(bo.getTopCustomerId() != null, GroupCustomer::getTopCustomerId, bo.getTopCustomerId());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), GroupCustomer::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增集团客户关系
+     *
+     * @param bo 集团客户关系
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(GroupCustomerBo bo) {
+        GroupCustomer add = MapstructUtils.convert(bo, GroupCustomer.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改集团客户关系
+     *
+     * @param bo 集团客户关系
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(GroupCustomerBo bo) {
+        GroupCustomer update = MapstructUtils.convert(bo, GroupCustomer.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(GroupCustomer 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-customer/src/main/resources/mapper/customer/CustomerDeptMapper.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.customer.mapper.CustomerDeptMapper">
+
+</mapper>

+ 7 - 0
ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/GroupCustomerMapper.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.customer.mapper.GroupCustomerMapper">
+
+</mapper>

+ 2 - 1
ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/FileCategory.java

@@ -8,6 +8,7 @@ import io.github.linpeilie.annotations.AutoMapper;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.dromara.common.tenant.core.TenantEntity;
+import org.dromara.common.tenant.core.TenantEntityWithoutPlatformCode;
 import org.dromara.resource.domain.vo.FileCategoryVo;
 
 import java.io.Serial;
@@ -22,7 +23,7 @@ import java.io.Serial;
 @EqualsAndHashCode(callSuper = true)
 @TableName("sys_file_category")
 @AutoMapper(target = FileCategoryVo.class)
-public class FileCategory extends TenantEntity {
+public class FileCategory extends TenantEntityWithoutPlatformCode {
 
     @Serial
     private static final long serialVersionUID = 1L;

+ 2 - 1
ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/FileInfo.java

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.dromara.common.tenant.core.TenantEntity;
+import org.dromara.common.tenant.core.TenantEntityWithoutPlatformCode;
 
 import java.io.Serial;
 
@@ -19,7 +20,7 @@ import java.io.Serial;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @TableName("sys_file_info")
-public class FileInfo extends TenantEntity {
+public class FileInfo extends TenantEntityWithoutPlatformCode {
 
     @Serial
     private static final long serialVersionUID = 1L;

+ 5 - 4
ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/bo/FileCategoryBo.java

@@ -8,6 +8,7 @@ import lombok.EqualsAndHashCode;
 import org.dromara.common.core.validate.AddGroup;
 import org.dromara.common.core.validate.EditGroup;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.mybatis.core.domain.BaseEntityWithoutPlatform;
 import org.dromara.resource.domain.FileCategory;
 
 /**
@@ -19,7 +20,7 @@ import org.dromara.resource.domain.FileCategory;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @AutoMapper(target = FileCategory.class, reverseConvertGenerate = false)
-public class FileCategoryBo extends BaseEntity {
+public class FileCategoryBo extends BaseEntityWithoutPlatform {
 
     /**
      * 分类ID
@@ -29,13 +30,13 @@ public class FileCategoryBo extends BaseEntity {
     /**
      * 分类名称
      */
-    @NotBlank(message = "分类名称不能为空", groups = { AddGroup.class, EditGroup.class })
+    @NotBlank(message = "分类名称不能为空", groups = {AddGroup.class, EditGroup.class})
     private String name;
 
     /**
      * 分类编码
      */
-    @NotBlank(message = "分类编码不能为空", groups = { AddGroup.class, EditGroup.class })
+    @NotBlank(message = "分类编码不能为空", groups = {AddGroup.class, EditGroup.class})
     private String code;
 
     /**
@@ -46,7 +47,7 @@ public class FileCategoryBo extends BaseEntity {
     /**
      * 分类类型(1图片 2视频 3音频 4文档 5其他)
      */
-    @NotNull(message = "分类类型不能为空", groups = { AddGroup.class, EditGroup.class })
+    @NotNull(message = "分类类型不能为空", groups = {AddGroup.class, EditGroup.class})
     private Integer type;
 
     /**

+ 5 - 4
ruoyi-modules/ruoyi-resource/src/main/java/org/dromara/resource/domain/bo/FileInfoBo.java

@@ -7,6 +7,7 @@ import lombok.EqualsAndHashCode;
 import org.dromara.common.core.validate.AddGroup;
 import org.dromara.common.core.validate.EditGroup;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.mybatis.core.domain.BaseEntityWithoutPlatform;
 import org.dromara.resource.domain.FileInfo;
 
 /**
@@ -18,7 +19,7 @@ import org.dromara.resource.domain.FileInfo;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @AutoMapper(target = FileInfo.class)
-public class FileInfoBo extends BaseEntity {
+public class FileInfoBo extends BaseEntityWithoutPlatform {
 
     /**
      * 文件ID
@@ -28,19 +29,19 @@ public class FileInfoBo extends BaseEntity {
     /**
      * 文件名称
      */
-    @NotBlank(message = "文件名称不能为空", groups = { AddGroup.class, EditGroup.class })
+    @NotBlank(message = "文件名称不能为空", groups = {AddGroup.class, EditGroup.class})
     private String name;
 
     /**
      * 原始文件名
      */
-    @NotBlank(message = "原始文件名不能为空", groups = { AddGroup.class, EditGroup.class })
+    @NotBlank(message = "原始文件名不能为空", groups = {AddGroup.class, EditGroup.class})
     private String originalName;
 
     /**
      * 文件路径(OSS路径)
      */
-    @NotBlank(message = "文件路径不能为空", groups = { AddGroup.class, EditGroup.class })
+    @NotBlank(message = "文件路径不能为空", groups = {AddGroup.class, EditGroup.class})
     private String path;
 
     /**

+ 105 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/InvoiceTypeController.java

@@ -0,0 +1,105 @@
+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.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.InvoiceTypeVo;
+import org.dromara.system.domain.bo.InvoiceTypeBo;
+import org.dromara.system.service.IInvoiceTypeService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 发票类型
+ * 前端访问路由地址为:/system/invoiceType
+ *
+ * @author LionLi
+ * @date 2025-12-19
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/invoiceType")
+public class InvoiceTypeController extends BaseController {
+
+    private final IInvoiceTypeService invoiceTypeService;
+
+    /**
+     * 查询发票类型列表
+     */
+    @GetMapping("/list")
+    public TableDataInfo<InvoiceTypeVo> list(InvoiceTypeBo bo, PageQuery pageQuery) {
+        return invoiceTypeService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出发票类型列表
+     */
+    @SaCheckPermission("system:invoiceType:export")
+    @Log(title = "发票类型", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(InvoiceTypeBo bo, HttpServletResponse response) {
+        List<InvoiceTypeVo> list = invoiceTypeService.queryList(bo);
+        ExcelUtil.exportExcel(list, "发票类型", InvoiceTypeVo.class, response);
+    }
+
+    /**
+     * 获取发票类型详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("system:invoiceType:query")
+    @GetMapping("/{id}")
+    public R<InvoiceTypeVo> getInfo(@NotNull(message = "主键不能为空")
+                                    @PathVariable("id") Long id) {
+        return R.ok(invoiceTypeService.queryById(id));
+    }
+
+    /**
+     * 新增发票类型
+     */
+    @SaCheckPermission("system:invoiceType:add")
+    @Log(title = "发票类型", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody InvoiceTypeBo bo) {
+        return toAjax(invoiceTypeService.insertByBo(bo));
+    }
+
+    /**
+     * 修改发票类型
+     */
+    @SaCheckPermission("system:invoiceType:edit")
+    @Log(title = "发票类型", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody InvoiceTypeBo bo) {
+        return toAjax(invoiceTypeService.updateByBo(bo));
+    }
+
+    /**
+     * 删除发票类型
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("system:invoiceType:remove")
+    @Log(title = "发票类型", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(invoiceTypeService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 105 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysCompanyController.java

@@ -0,0 +1,105 @@
+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.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.SysCompanyVo;
+import org.dromara.system.domain.bo.SysCompanyBo;
+import org.dromara.system.service.ISysCompanyService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 公司信息
+ * 前端访问路由地址为:/system/sysCompany
+ *
+ * @author LionLi
+ * @date 2025-12-19
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/sysCompany")
+public class SysCompanyController extends BaseController {
+
+    private final ISysCompanyService sysCompanyService;
+
+    /**
+     * 查询公司信息列表
+     */
+    @GetMapping("/list")
+    public TableDataInfo<SysCompanyVo> list(SysCompanyBo bo, PageQuery pageQuery) {
+        return sysCompanyService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出公司信息列表
+     */
+    @SaCheckPermission("system:sysCompany:export")
+    @Log(title = "公司信息", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(SysCompanyBo bo, HttpServletResponse response) {
+        List<SysCompanyVo> list = sysCompanyService.queryList(bo);
+        ExcelUtil.exportExcel(list, "公司信息", SysCompanyVo.class, response);
+    }
+
+    /**
+     * 获取公司信息详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("system:sysCompany:query")
+    @GetMapping("/{id}")
+    public R<SysCompanyVo> getInfo(@NotNull(message = "主键不能为空")
+                                   @PathVariable("id") Long id) {
+        return R.ok(sysCompanyService.queryById(id));
+    }
+
+    /**
+     * 新增公司信息
+     */
+    @SaCheckPermission("system:sysCompany:add")
+    @Log(title = "公司信息", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody SysCompanyBo bo) {
+        return toAjax(sysCompanyService.insertByBo(bo));
+    }
+
+    /**
+     * 修改公司信息
+     */
+    @SaCheckPermission("system:sysCompany:edit")
+    @Log(title = "公司信息", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysCompanyBo bo) {
+        return toAjax(sysCompanyService.updateByBo(bo));
+    }
+
+    /**
+     * 删除公司信息
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("system:sysCompany:remove")
+    @Log(title = "公司信息", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(sysCompanyService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 62 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/InvoiceType.java

@@ -0,0 +1,62 @@
+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;
+
+/**
+ * 发票类型对象 invoice_type
+ *
+ * @author LionLi
+ * @date 2025-12-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("invoice_type")
+public class InvoiceType extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 发票类型编号
+     */
+    private String invoiceTypeNo;
+
+    /**
+     * 发票类型名称
+     */
+    private String invoiceTypeName;
+
+    /**
+     * 是否显示:0-显示,1-隐藏
+     */
+    private String isShow;
+
+    /**
+     * 数据来源
+     */
+    private String dataSource;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 107 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysCompany.java

@@ -0,0 +1,107 @@
+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.math.BigDecimal;
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serial;
+
+/**
+ * 公司信息对象 sys_company
+ *
+ * @author LionLi
+ * @date 2025-12-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("sys_company")
+public class SysCompany extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 税务登记号/统一社会信用代码
+     */
+    private String taxNumber;
+
+    /**
+     * 公司编码
+     */
+    private String companyCode;
+
+    /**
+     * 公司名称
+     */
+    private String companyName;
+
+    /**
+     * 生效日期
+     */
+    private Date beginDate;
+
+    /**
+     * 注册资本
+     */
+    private BigDecimal registeredCapital;
+
+    /**
+     * 公司全称
+     */
+    private String companyFullName;
+
+    /**
+     * 电子邮箱
+     */
+    private String email;
+
+    /**
+     * 失效日期
+     */
+    private Date endDate;
+
+    /**
+     * 成立日期
+     */
+    private Date foundedDate;
+
+    /**
+     * 注册日期(格式:YYYYMMDD)
+     */
+    private Date registrationDate;
+
+    /**
+     * 是否显示
+     */
+    private String isShow;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 29 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDept.java

@@ -9,6 +9,7 @@ import lombok.EqualsAndHashCode;
 import org.dromara.common.tenant.core.TenantEntity;
 
 import java.io.Serial;
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -84,6 +85,34 @@ public class SysDept extends TenantEntity {
      */
     private String ancestors;
 
+    /**
+     * 年度预算
+     */
+    private BigDecimal annualBudget;
+
+    /**
+     * 已用预算
+     */
+    private BigDecimal budgetUsed;
+
+    /**
+     * 月采限额
+     */
+    private BigDecimal monthlyQuota;
+
+    /**
+     * 是否绑定
+     */
+    private String isBound;
+
+    /**
+     * 地址ID
+     */
+    private Long shopAddressId;
+
+    private Long customerId;
+
+
     /**
      * 子菜单
      */

+ 55 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/InvoiceTypeBo.java

@@ -0,0 +1,55 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.system.domain.InvoiceType;
+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.*;
+
+/**
+ * 发票类型业务对象 invoice_type
+ *
+ * @author LionLi
+ * @date 2025-12-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = InvoiceType.class, reverseConvertGenerate = false)
+public class InvoiceTypeBo extends BaseEntity {
+
+    /**
+     * ID
+     */
+    private Long id;
+
+    /**
+     * 发票类型编号
+     */
+    private String invoiceTypeNo;
+
+    /**
+     * 发票类型名称
+     */
+    @NotBlank(message = "发票类型名称不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String invoiceTypeName;
+
+    /**
+     * 是否显示:0-显示,1-隐藏
+     */
+    private String isShow;
+
+    /**
+     * 数据来源
+     */
+    private String dataSource;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 103 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysCompanyBo.java

@@ -0,0 +1,103 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.system.domain.SysCompany;
+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 com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 公司信息业务对象 sys_company
+ *
+ * @author LionLi
+ * @date 2025-12-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SysCompany.class, reverseConvertGenerate = false)
+public class SysCompanyBo extends BaseEntity {
+
+    /**
+     * ID
+     */
+    private Long id;
+
+    /**
+     * 税务登记号/统一社会信用代码
+     */
+    private String taxNumber;
+
+    /**
+     * 公司编码
+     */
+    private String companyCode;
+
+    /**
+     * 公司名称
+     */
+    @NotBlank(message = "公司名称不能为空", groups = {AddGroup.class, EditGroup.class})
+    private String companyName;
+
+    /**
+     * 生效日期
+     */
+    @NotNull(message = "生效日期不能为空", groups = {AddGroup.class, EditGroup.class})
+    private Date beginDate;
+
+    /**
+     * 注册资本
+     */
+    @NotBlank(message = "注册资本不能为空", groups = {AddGroup.class, EditGroup.class})
+    private BigDecimal registeredCapital;
+
+    /**
+     * 公司全称
+     */
+    @NotBlank(message = "公司全称不能为空", groups = {AddGroup.class, EditGroup.class})
+    private String companyFullName;
+
+    /**
+     * 电子邮箱
+     */
+    private String email;
+
+    /**
+     * 失效日期
+     */
+    private Date endDate;
+
+    /**
+     * 成立日期
+     */
+    private Date foundedDate;
+
+    /**
+     * 注册日期(格式:YYYYMMDD)
+     */
+    private Date registrationDate;
+
+    /**
+     * 是否显示
+     */
+    private String isShow;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 30 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysDeptBo.java

@@ -10,6 +10,8 @@ import lombok.EqualsAndHashCode;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
 import org.dromara.system.domain.SysDept;
 
+import java.math.BigDecimal;
+
 /**
  * 部门业务对象 sys_dept
  *
@@ -31,6 +33,7 @@ public class SysDeptBo extends BaseEntity {
      */
     private Long parentId;
 
+
     /**
      * 部门名称
      */
@@ -78,4 +81,31 @@ public class SysDeptBo extends BaseEntity {
      */
     private Long belongDeptId;
 
+    /**
+     * 年度预算
+     */
+    private BigDecimal annualBudget;
+
+    /**
+     * 已用预算
+     */
+    private BigDecimal budgetUsed;
+
+    /**
+     * 月采限额
+     */
+    private BigDecimal monthlyQuota;
+
+    /**
+     * 是否绑定
+     */
+    private String isBound;
+
+    /**
+     * 地址ID
+     */
+    private Long shopAddressId;
+
+    private Long customerId;
+
 }

+ 69 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/InvoiceTypeVo.java

@@ -0,0 +1,69 @@
+package org.dromara.system.domain.vo;
+
+import org.dromara.system.domain.InvoiceType;
+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;
+
+
+
+/**
+ * 发票类型视图对象 invoice_type
+ *
+ * @author LionLi
+ * @date 2025-12-19
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = InvoiceType.class)
+public class InvoiceTypeVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @ExcelProperty(value = "ID")
+    private Long id;
+
+    /**
+     * 发票类型编号
+     */
+    @ExcelProperty(value = "发票类型编号")
+    private String invoiceTypeNo;
+
+    /**
+     * 发票类型名称
+     */
+    @ExcelProperty(value = "发票类型名称")
+    private String invoiceTypeName;
+
+    /**
+     * 是否显示:0-显示,1-隐藏
+     */
+    @ExcelProperty(value = "是否显示:0-显示,1-隐藏", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_platform_yes_no")
+    private String isShow;
+
+    /**
+     * 数据来源
+     */
+    @ExcelProperty(value = "数据来源")
+    private String dataSource;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 122 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysCompanyVo.java

@@ -0,0 +1,122 @@
+package org.dromara.system.domain.vo;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.dromara.system.domain.SysCompany;
+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;
+
+
+/**
+ * 公司信息视图对象 sys_company
+ *
+ * @author LionLi
+ * @date 2025-12-19
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SysCompany.class)
+public class SysCompanyVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @ExcelProperty(value = "ID")
+    private Long id;
+
+    /**
+     * 税务登记号/统一社会信用代码
+     */
+    @ExcelProperty(value = "税务登记号/统一社会信用代码")
+    private String taxNumber;
+
+    /**
+     * 公司编码
+     */
+    @ExcelProperty(value = "公司编码")
+    private String companyCode;
+
+    /**
+     * 公司名称
+     */
+    @ExcelProperty(value = "公司名称")
+    private String companyName;
+
+    /**
+     * 生效日期
+     */
+    @ExcelProperty(value = "生效日期")
+    private Date beginDate;
+
+    /**
+     * 注册资本
+     */
+    @ExcelProperty(value = "注册资本")
+    private BigDecimal registeredCapital;
+
+    /**
+     * 公司全称
+     */
+    @ExcelProperty(value = "公司全称")
+    private String companyFullName;
+
+    /**
+     * 电子邮箱
+     */
+    @ExcelProperty(value = "电子邮箱")
+    private String email;
+
+    /**
+     * 失效日期
+     */
+    @ExcelProperty(value = "失效日期")
+    private Date endDate;
+
+    /**
+     * 成立日期
+     */
+    @ExcelProperty(value = "成立日期")
+    private Date foundedDate;
+
+    /**
+     * 注册日期(格式:YYYYMMDD)
+     */
+    @ExcelProperty(value = "注册日期", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "格=式:YYYYMMDD")
+    private Date registrationDate;
+
+    /**
+     * 是否显示
+     */
+    @ExcelProperty(value = "是否显示", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_platform_yes_no")
+    private String isShow;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
+    private String status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 28 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysDeptVo.java

@@ -10,6 +10,7 @@ import org.dromara.system.domain.SysDept;
 
 import java.io.Serial;
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -104,6 +105,33 @@ public class SysDeptVo implements Serializable {
     /*平台标识*/
     private String platformCode;
 
+    /**
+     * 年度预算
+     */
+    private BigDecimal annualBudget;
+
+    /**
+     * 已用预算
+     */
+    private BigDecimal budgetUsed;
+
+    /**
+     * 月采限额
+     */
+    private BigDecimal monthlyQuota;
+
+    /**
+     * 是否绑定
+     */
+    private String isBound;
+
+    /**
+     * 地址ID
+     */
+    private Long shopAddressId;
+
+    private Long customerId;
+
     /**
      * 子菜单
      */

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

@@ -5,6 +5,7 @@ import lombok.RequiredArgsConstructor;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.dromara.system.api.RemoteDeptService;
 import org.dromara.system.api.domain.vo.RemoteDeptVo;
+import org.dromara.system.domain.bo.SysDeptBo;
 import org.dromara.system.domain.vo.SysDeptVo;
 import org.dromara.system.service.ISysDeptService;
 import org.springframework.stereotype.Service;
@@ -57,4 +58,19 @@ public class RemoteDeptServiceImpl implements RemoteDeptService {
         return BeanUtil.copyToList(list, RemoteDeptVo.class);
     }
 
+    /**
+     * 查询部门
+     */
+    @Override
+    public RemoteDeptVo selectParentDeptByPlatformCode(String platformCode) {
+        SysDeptVo sysDeptVo = sysDeptService.selectParentDeptByPlatformCode(platformCode);
+        return BeanUtil.copyProperties(sysDeptVo, RemoteDeptVo.class);
+    }
+
+    @Override
+    public RemoteDeptVo insertDept(RemoteDeptVo vo) {
+        SysDeptBo dept = BeanUtil.copyProperties(vo, SysDeptBo.class);
+        sysDeptService.insertDept(dept);
+        return BeanUtil.copyProperties(dept, RemoteDeptVo.class);
+    }
 }

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

@@ -0,0 +1,15 @@
+package org.dromara.system.mapper;
+
+import org.dromara.system.domain.InvoiceType;
+import org.dromara.system.domain.vo.InvoiceTypeVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 发票类型Mapper接口
+ *
+ * @author LionLi
+ * @date 2025-12-19
+ */
+public interface InvoiceTypeMapper extends BaseMapperPlus<InvoiceType, InvoiceTypeVo> {
+
+}

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

@@ -0,0 +1,15 @@
+package org.dromara.system.mapper;
+
+import org.dromara.system.domain.SysCompany;
+import org.dromara.system.domain.vo.SysCompanyVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 公司信息Mapper接口
+ *
+ * @author LionLi
+ * @date 2025-12-19
+ */
+public interface SysCompanyMapper extends BaseMapperPlus<SysCompany, SysCompanyVo> {
+
+}

+ 11 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysDeptMapper.java

@@ -32,6 +32,7 @@ public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
     default List<SysDeptVo> selectDeptList(Wrapper<SysDept> queryWrapper) {
         return this.selectVoList(queryWrapper);
     }
+
     /**
      * 分页查询部门管理数据
      *
@@ -45,6 +46,7 @@ public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
     default Page<SysDeptVo> selectPageDeptList(Page<SysDept> page, Wrapper<SysDept> queryWrapper) {
         return this.selectVoPage(page, queryWrapper);
     }
+
     /**
      * 统计指定部门ID的部门数量
      *
@@ -57,6 +59,7 @@ public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
     default long countDeptById(Long deptId) {
         return this.selectCount(new LambdaQueryWrapper<SysDept>().eq(SysDept::getDeptId, deptId));
     }
+
     /**
      * 根据父部门ID查询其所有子部门的列表
      *
@@ -78,4 +81,12 @@ public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
      */
     List<Long> selectDeptListByRoleId(@Param("roleId") Long roleId, @Param("deptCheckStrictly") boolean deptCheckStrictly);
 
+    /**
+     * 根据父ID查询同级节点的最大 orderNum
+     *
+     * @param parentId 父节点ID,null 表示顶级节点
+     * @return 最大 orderNum,若无记录则返回 0
+     */
+    Integer selectMaxOrderNumByParentId(@Param("parentId") Long parentId);
+
 }

+ 70 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/IInvoiceTypeService.java

@@ -0,0 +1,70 @@
+package org.dromara.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.system.domain.InvoiceType;
+import org.dromara.system.domain.vo.InvoiceTypeVo;
+import org.dromara.system.domain.bo.InvoiceTypeBo;
+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 2025-12-19
+ */
+public interface IInvoiceTypeService extends IService<InvoiceType>{
+
+    /**
+     * 查询发票类型
+     *
+     * @param id 主键
+     * @return 发票类型
+     */
+    InvoiceTypeVo queryById(Long id);
+
+    /**
+     * 分页查询发票类型列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 发票类型分页列表
+     */
+    TableDataInfo<InvoiceTypeVo> queryPageList(InvoiceTypeBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的发票类型列表
+     *
+     * @param bo 查询条件
+     * @return 发票类型列表
+     */
+    List<InvoiceTypeVo> queryList(InvoiceTypeBo bo);
+
+    /**
+     * 新增发票类型
+     *
+     * @param bo 发票类型
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(InvoiceTypeBo bo);
+
+    /**
+     * 修改发票类型
+     *
+     * @param bo 发票类型
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(InvoiceTypeBo bo);
+
+    /**
+     * 校验并批量删除发票类型信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 70 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysCompanyService.java

@@ -0,0 +1,70 @@
+package org.dromara.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.system.domain.SysCompany;
+import org.dromara.system.domain.vo.SysCompanyVo;
+import org.dromara.system.domain.bo.SysCompanyBo;
+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 2025-12-19
+ */
+public interface ISysCompanyService extends IService<SysCompany>{
+
+    /**
+     * 查询公司信息
+     *
+     * @param id 主键
+     * @return 公司信息
+     */
+    SysCompanyVo queryById(Long id);
+
+    /**
+     * 分页查询公司信息列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 公司信息分页列表
+     */
+    TableDataInfo<SysCompanyVo> queryPageList(SysCompanyBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的公司信息列表
+     *
+     * @param bo 查询条件
+     * @return 公司信息列表
+     */
+    List<SysCompanyVo> queryList(SysCompanyBo bo);
+
+    /**
+     * 新增公司信息
+     *
+     * @param bo 公司信息
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(SysCompanyBo bo);
+
+    /**
+     * 修改公司信息
+     *
+     * @param bo 公司信息
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(SysCompanyBo bo);
+
+    /**
+     * 校验并批量删除公司信息信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

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

@@ -128,6 +128,8 @@ public interface ISysDeptService {
      */
     int insertDept(SysDeptBo bo);
 
+    SysDeptVo selectParentDeptByPlatformCode(String platform);
+
     /**
      * 修改保存部门信息
      *

+ 137 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/InvoiceTypeServiceImpl.java

@@ -0,0 +1,137 @@
+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.springframework.stereotype.Service;
+import org.dromara.system.domain.bo.InvoiceTypeBo;
+import org.dromara.system.domain.vo.InvoiceTypeVo;
+import org.dromara.system.domain.InvoiceType;
+import org.dromara.system.mapper.InvoiceTypeMapper;
+import org.dromara.system.service.IInvoiceTypeService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 发票类型Service业务层处理
+ *
+ * @author LionLi
+ * @date 2025-12-19
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class InvoiceTypeServiceImpl  extends ServiceImpl<InvoiceTypeMapper, InvoiceType> implements IInvoiceTypeService {
+
+    private final InvoiceTypeMapper baseMapper;
+
+    /**
+     * 查询发票类型
+     *
+     * @param id 主键
+     * @return 发票类型
+     */
+    @Override
+    public InvoiceTypeVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询发票类型列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 发票类型分页列表
+     */
+    @Override
+    public TableDataInfo<InvoiceTypeVo> queryPageList(InvoiceTypeBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<InvoiceType> lqw = buildQueryWrapper(bo);
+        Page<InvoiceTypeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的发票类型列表
+     *
+     * @param bo 查询条件
+     * @return 发票类型列表
+     */
+    @Override
+    public List<InvoiceTypeVo> queryList(InvoiceTypeBo bo) {
+        LambdaQueryWrapper<InvoiceType> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<InvoiceType> buildQueryWrapper(InvoiceTypeBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<InvoiceType> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(InvoiceType::getId);
+        lqw.eq(StringUtils.isNotBlank(bo.getInvoiceTypeNo()), InvoiceType::getInvoiceTypeNo, bo.getInvoiceTypeNo());
+        lqw.like(StringUtils.isNotBlank(bo.getInvoiceTypeName()), InvoiceType::getInvoiceTypeName, bo.getInvoiceTypeName());
+        lqw.eq(StringUtils.isNotBlank(bo.getIsShow()), InvoiceType::getIsShow, bo.getIsShow());
+        lqw.eq(StringUtils.isNotBlank(bo.getDataSource()), InvoiceType::getDataSource, bo.getDataSource());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), InvoiceType::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增发票类型
+     *
+     * @param bo 发票类型
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(InvoiceTypeBo bo) {
+        InvoiceType add = MapstructUtils.convert(bo, InvoiceType.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改发票类型
+     *
+     * @param bo 发票类型
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(InvoiceTypeBo bo) {
+        InvoiceType update = MapstructUtils.convert(bo, InvoiceType.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(InvoiceType entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除发票类型信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 144 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysCompanyServiceImpl.java

@@ -0,0 +1,144 @@
+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.springframework.stereotype.Service;
+import org.dromara.system.domain.bo.SysCompanyBo;
+import org.dromara.system.domain.vo.SysCompanyVo;
+import org.dromara.system.domain.SysCompany;
+import org.dromara.system.mapper.SysCompanyMapper;
+import org.dromara.system.service.ISysCompanyService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 公司信息Service业务层处理
+ *
+ * @author LionLi
+ * @date 2025-12-19
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class SysCompanyServiceImpl extends ServiceImpl<SysCompanyMapper, SysCompany> implements ISysCompanyService {
+
+    private final SysCompanyMapper baseMapper;
+
+    /**
+     * 查询公司信息
+     *
+     * @param id 主键
+     * @return 公司信息
+     */
+    @Override
+    public SysCompanyVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询公司信息列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 公司信息分页列表
+     */
+    @Override
+    public TableDataInfo<SysCompanyVo> queryPageList(SysCompanyBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<SysCompany> lqw = buildQueryWrapper(bo);
+        Page<SysCompanyVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的公司信息列表
+     *
+     * @param bo 查询条件
+     * @return 公司信息列表
+     */
+    @Override
+    public List<SysCompanyVo> queryList(SysCompanyBo bo) {
+        LambdaQueryWrapper<SysCompany> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<SysCompany> buildQueryWrapper(SysCompanyBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<SysCompany> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(SysCompany::getId);
+        lqw.eq(StringUtils.isNotBlank(bo.getTaxNumber()), SysCompany::getTaxNumber, bo.getTaxNumber());
+        lqw.eq(StringUtils.isNotBlank(bo.getCompanyCode()), SysCompany::getCompanyCode, bo.getCompanyCode());
+        lqw.like(StringUtils.isNotBlank(bo.getCompanyName()), SysCompany::getCompanyName, bo.getCompanyName());
+        lqw.eq(bo.getBeginDate() != null, SysCompany::getBeginDate, bo.getBeginDate());
+        lqw.like(StringUtils.isNotBlank(bo.getCompanyFullName()), SysCompany::getCompanyFullName, bo.getCompanyFullName());
+        lqw.eq(StringUtils.isNotBlank(bo.getEmail()), SysCompany::getEmail, bo.getEmail());
+        lqw.eq(bo.getEndDate() != null, SysCompany::getEndDate, bo.getEndDate());
+        lqw.eq(bo.getFoundedDate() != null, SysCompany::getFoundedDate, bo.getFoundedDate());
+        lqw.eq(bo.getRegistrationDate() != null, SysCompany::getRegistrationDate, bo.getRegistrationDate());
+        lqw.eq(StringUtils.isNotBlank(bo.getIsShow()), SysCompany::getIsShow, bo.getIsShow());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysCompany::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), SysCompany::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增公司信息
+     *
+     * @param bo 公司信息
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(SysCompanyBo bo) {
+        SysCompany add = MapstructUtils.convert(bo, SysCompany.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改公司信息
+     *
+     * @param bo 公司信息
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(SysCompanyBo bo) {
+        SysCompany update = MapstructUtils.convert(bo, SysCompany.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(SysCompany entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除公司信息信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 16 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java

@@ -15,6 +15,7 @@ import org.dromara.common.core.context.PlatformContext;
 import org.dromara.common.core.enums.SysPlatformCode;
 import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.utils.*;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.helper.DataBaseHelper;
@@ -97,6 +98,7 @@ public class SysDeptServiceImpl implements ISysDeptService {
         lqw.eq(SysDept::getDelFlag, SystemConstants.NORMAL);
         lqw.eq(ObjectUtil.isNotNull(bo.getDeptId()), SysDept::getDeptId, bo.getDeptId());
         lqw.eq(ObjectUtil.isNotNull(bo.getParentId()), SysDept::getParentId, bo.getParentId());
+        lqw.eq(ObjectUtil.isNotNull(bo.getCustomerId()), SysDept::getCustomerId, bo.getCustomerId());
         lqw.like(StringUtils.isNotBlank(bo.getDeptName()), SysDept::getDeptName, bo.getDeptName());
         lqw.like(StringUtils.isNotBlank(bo.getDeptCategory()), SysDept::getDeptCategory, bo.getDeptCategory());
         lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDept::getStatus, bo.getStatus());
@@ -277,6 +279,14 @@ public class SysDeptServiceImpl implements ISysDeptService {
         }
     }
 
+    @Override
+    public SysDeptVo selectParentDeptByPlatformCode(String platform) {
+        return baseMapper.selectVoOne(
+            new LambdaQueryWrapper<SysDept>().eq(SysDept::getPlatformCode, platform)
+                .orderByAsc(SysDept::getCreateTime)
+                .last("LIMIT 1"));
+    }
+
     /**
      * 新增保存部门信息
      *
@@ -291,10 +301,16 @@ public class SysDeptServiceImpl implements ISysDeptService {
         if (!SystemConstants.NORMAL.equals(info.getStatus())) {
             throw new ServiceException("部门停用,不允许新增");
         }
+        if (bo.getOrderNum() == null || bo.getOrderNum() < 0) {
+            bo.setOrderNum(baseMapper.selectMaxOrderNumByParentId(bo.getParentId()));
+        }
         SysDept dept = MapstructUtils.convert(bo, SysDept.class);
         dept.setAncestors(info.getAncestors() + StringUtils.SEPARATOR + dept.getParentId());
         // 1. 校验当前是否为总控平台(main),否则不能指定 platformCode
         String currentPlatform = PlatformContext.getPlatform();
+        if (StringUtils.isEmpty(currentPlatform)) {
+            currentPlatform = bo.getPlatformCode();
+        }
         String targetPlatform = currentPlatform;
         if (SysPlatformCode.MAIN.getCode().equals(currentPlatform)) {
             targetPlatform = dept.getPlatformCode();

+ 7 - 0
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/InvoiceTypeMapper.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.system.mapper.InvoiceTypeMapper">
+
+</mapper>

+ 7 - 0
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysCompanyMapper.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.system.mapper.SysCompanyMapper">
+
+</mapper>

+ 12 - 6
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml

@@ -1,7 +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">
+    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="org.dromara.system.mapper.SysDeptMapper">
 
     <resultMap type="org.dromara.system.domain.vo.SysDeptVo" id="SysDeptResult">
@@ -10,12 +10,18 @@
     <select id="selectDeptListByRoleId" resultType="Long">
         select d.dept_id
         from sys_dept d
-            left join sys_role_dept rd on d.dept_id = rd.dept_id
+        left join sys_role_dept rd on d.dept_id = rd.dept_id
         where rd.role_id = #{roleId}
-            <if test="deptCheckStrictly">
-                and d.dept_id not in (select d.parent_id from sys_dept d inner join sys_role_dept rd on d.dept_id = rd.dept_id and rd.role_id = #{roleId})
-            </if>
+        <if test="deptCheckStrictly">
+            and d.dept_id not in (select d.parent_id from sys_dept d inner join sys_role_dept rd on d.dept_id =
+            rd.dept_id and rd.role_id = #{roleId})
+        </if>
         order by d.parent_id, d.order_num
     </select>
 
+    <select id="selectMaxOrderNumByParentId" resultType="java.lang.Integer">
+        SELECT IFNULL(MAX(order_num), 0) + 1
+        FROM sys_dept
+        WHERE parent_id = #{parentId}
+    </select>
 </mapper>