You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

17 KiB

部门管理

**本文引用的文件** - [SysDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysDept.java) - [SysDeptMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysDeptMapper.java) - [ISysDeptService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysDeptService.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java) - [DataInitializer.java](file://crm-auth/src/main/java/com/crm/auth/config/DataInitializer.java) - [application.yml](file://crm-auth/src/main/resources/application.yml) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) - [TreeUtils.java](file://crm-base/src/main/java/com/crm/base/utils/TreeUtils.java) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) - [SysDeptServiceImplTest.java](file://crm-auth/src/test/java/com/crm/auth/service/impl/SysDeptServiceImplTest.java)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考虑
  8. 故障排查指南
  9. 结论
  10. 附录:API接口与使用案例

简介

本技术文档聚焦于“部门管理”模块,围绕部门树形结构的设计与实现、CRUD操作、层级关系管理、缓存机制、数据初始化与同步、异常处理等进行系统化阐述。该模块基于 MyBatis-Plus 进行数据访问,通过 Redis 缓存提升部门树查询性能,并在服务层提供统一的树构建与层级维护能力,为权限控制、数据范围等上层功能提供基础支撑。

项目结构

部门管理相关代码主要分布在 crm-auth 模块中,实体定义在 domain.entity,数据访问在 mapper,业务逻辑在 service.impl,缓存与配置在 service 和 config 包下;通用基类与工具位于 crm-base 模块。

graph TB
subgraph "crm-auth"
A["entity: SysDept"] --> B["mapper: SysDeptMapper"]
B --> C["service: ISysDeptService"]
C --> D["service.impl: SysDeptServiceImpl"]
D --> E["service: DeptTreeCache"]
F["config: DataInitializer"] --> D
G["resources: application.yml"] --> E
end
subgraph "crm-base"
H["domain.entity: BaseEntity"] --> A
I["domain.entity: OwnedEntity"] --> A
J["utils: TreeUtils"] --> D
K["config: RedisConfig"] --> E
end

图表来源

  • SysDept.java
  • SysDeptMapper.java
  • ISysDeptService.java
  • SysDeptServiceImpl.java
  • DeptTreeCache.java
  • DataInitializer.java
  • application.yml
  • BaseEntity.java
  • OwnedEntity.java
  • TreeUtils.java
  • RedisConfig.java

章节来源

  • SysDept.java
  • SysDeptMapper.java
  • ISysDeptService.java
  • SysDeptServiceImpl.java
  • DeptTreeCache.java
  • DataInitializer.java
  • application.yml
  • BaseEntity.java
  • OwnedEntity.java
  • TreeUtils.java
  • RedisConfig.java

核心组件

  • 实体模型:部门实体继承通用基类,包含父部门、排序、状态等字段,用于表达层级关系与生命周期。
  • 数据访问:MyBatis-Plus Mapper 提供基础 CRUD 与条件查询能力。
  • 服务层:统一封装部门增删改查、树构建、层级校验、缓存刷新等操作。
  • 缓存层:基于 Redis 的部门树缓存,支持按维度(如租户或全局)存储与失效策略。
  • 初始化器:应用启动时按需初始化默认部门数据,保证系统可用。
  • 工具类:树构建工具提供将扁平列表组装为树结构的通用方法。

章节来源

  • SysDept.java
  • SysDeptMapper.java
  • ISysDeptService.java
  • SysDeptServiceImpl.java
  • DeptTreeCache.java
  • DataInitializer.java
  • TreeUtils.java

架构总览

部门管理采用分层架构:Controller(如有)调用 Service,Service 组合 Mapper 与 Cache,Cache 基于 Redis 持久化树结构。数据初始化由独立任务在启动阶段执行,确保基础数据就绪。

sequenceDiagram
participant Client as "客户端"
participant Service as "ISysDeptService"
participant Impl as "SysDeptServiceImpl"
participant Mapper as "SysDeptMapper"
participant Cache as "DeptTreeCache"
participant Redis as "Redis"
Client->>Service : "获取部门树"
Service->>Impl : "getDeptTree()"
Impl->>Cache : "getTree(key)"
alt "缓存命中"
Cache-->>Impl : "返回树结构"
else "缓存未命中"
Impl->>Mapper : "selectList(全部/条件)"
Mapper-->>Impl : "扁平列表"
Impl->>Impl : "构建父子关系树"
Impl->>Cache : "putTree(key, tree)"
Cache->>Redis : "序列化并存储"
Redis-->>Cache : "OK"
end
Impl-->>Service : "树结果"
Service-->>Client : "返回树"

图表来源

  • ISysDeptService.java
  • SysDeptServiceImpl.java
  • SysDeptMapper.java
  • DeptTreeCache.java
  • RedisConfig.java

详细组件分析

实体模型设计

  • 继承体系:部门实体继承 BaseEntity(通用审计字段)与 OwnedEntity(数据归属),便于统一时间戳、创建人、更新人及数据可见性控制。
  • 层级字段:包含父部门标识、排序号、状态等,支撑树形结构与展示顺序。
  • 约束与校验:建议在新增/修改时校验父部门存在性与循环引用,避免形成环状结构。
classDiagram
class BaseEntity {
+id
+createTime
+updateTime
+createBy
+updateBy
}
class OwnedEntity {
+ownerId
+dataScope
}
class SysDept {
+parentId
+sort
+status
+name
+code
+level
+path
}
BaseEntity <|-- SysDept
OwnedEntity <|-- SysDept

图表来源

  • BaseEntity.java
  • OwnedEntity.java
  • SysDept.java

章节来源

  • SysDept.java
  • BaseEntity.java
  • OwnedEntity.java

数据访问层(Mapper)

  • 职责:提供基础的增删改查与条件查询能力,配合 MyBatis-Plus 简化 SQL 编写。
  • 典型操作:根据父ID查询子节点、按状态过滤、批量更新排序等。
  • 扩展点:可结合分页插件与自定义 SQL 注入器增强查询能力。

章节来源

  • SysDeptMapper.java

服务层(Service)

  • 接口定义:ISysDeptService 声明部门树构建、CRUD、层级校验、缓存刷新等能力。
  • 实现要点:
    • 树构建:从数据库拉取扁平列表,利用 TreeUtils 组装为树结构。
    • 层级校验:防止自引用与循环引用,维护 level/path 等辅助字段。
    • 事务控制:对多步写操作加事务,保证一致性。
    • 缓存联动:写操作后主动失效或重建对应维度的树缓存。
flowchart TD
Start(["开始"]) --> CheckParent["校验父部门是否存在"]
CheckParent --> ParentExists{"父部门有效?"}
ParentExists --> |否| ThrowError["抛出参数异常"]
ParentExists --> |是| BuildPath["计算层级与路径"]
BuildPath --> SaveDB["保存/更新到数据库"]
SaveDB --> InvalidateCache["失效/重建缓存"]
InvalidateCache --> End(["结束"])
ThrowError --> End

图表来源

  • ISysDeptService.java
  • SysDeptServiceImpl.java
  • TreeUtils.java

章节来源

  • ISysDeptService.java
  • SysDeptServiceImpl.java
  • TreeUtils.java

缓存层(DeptTreeCache)

  • 设计目标:降低高频树查询对数据库的压力,提升响应速度。
  • 存储键策略:按维度(如租户ID或全局)作为 key,避免跨租户污染。
  • 数据结构:序列化后的树对象,支持快速反序列化为前端可用的嵌套结构。
  • 失效策略:
    • 写操作后主动失效对应 key。
    • 可选定时全量重建,保障极端场景下的数据一致性。
  • 并发安全:读写分离与本地锁(如适用)避免缓存击穿。
classDiagram
class DeptTreeCache {
+getTree(key) Object
+putTree(key, tree) void
+invalidate(key) void
-serialize(obj) byte[]
-deserialize(bytes) Object
}
class RedisTemplate {
+opsForValue() ValueOperations
+expire(key, ttl) boolean
}
DeptTreeCache --> RedisTemplate : "存取与过期"

图表来源

  • DeptTreeCache.java
  • RedisConfig.java

章节来源

  • DeptTreeCache.java
  • RedisConfig.java

数据初始化(DataInitializer)

  • 触发时机:应用启动阶段,检查是否已存在基础部门数据。
  • 初始化内容:创建根部门、默认一级部门等,确保权限与数据范围可用。
  • 幂等性:通过唯一编码或名称判断,避免重复初始化。
  • 失败处理:记录日志并允许后续重试,不影响主流程启动。

章节来源

  • DataInitializer.java

配置(application.yml)

  • 关键项:Redis 连接信息、缓存 TTL、初始化开关等。
  • 建议:生产环境开启连接池与超时配置,合理设置缓存过期时间。

章节来源

  • application.yml

依赖关系分析

  • 低耦合:Service 通过接口与 Mapper/Cache 解耦,便于替换实现与测试。
  • 内聚性:树构建与层级校验集中在 Service 层,避免分散逻辑。
  • 外部依赖:Redis 作为缓存后端,需保证高可用与容量规划。
graph LR
ISysDeptService --> SysDeptServiceImpl
SysDeptServiceImpl --> SysDeptMapper
SysDeptServiceImpl --> DeptTreeCache
DeptTreeCache --> RedisConfig
DataInitializer --> SysDeptServiceImpl

图表来源

  • ISysDeptService.java
  • SysDeptServiceImpl.java
  • SysDeptMapper.java
  • DeptTreeCache.java
  • RedisConfig.java
  • DataInitializer.java

章节来源

  • ISysDeptService.java
  • SysDeptServiceImpl.java
  • SysDeptMapper.java
  • DeptTreeCache.java
  • RedisConfig.java
  • DataInitializer.java

性能考虑

  • 缓存命中率:热点部门树应优先命中缓存,减少 DB 压力。
  • 序列化开销:树结构较大时,注意序列化格式与压缩策略。
  • 失效粒度:按维度失效,避免全量重建带来的抖动。
  • 查询优化:仅加载必要字段,必要时分页或懒加载子节点。
  • 连接池:Redis 连接池大小与超时配置需匹配峰值 QPS。

[本节为通用指导,不直接分析具体文件]

故障排查指南

  • 缓存不一致:检查写操作后是否及时失效 key,确认 TTL 与重建策略。
  • 循环引用:校验父部门与子节点关系,避免形成环。
  • 初始化失败:查看启动日志,确认唯一性判断与数据完整性。
  • 性能问题:监控 Redis 延迟与内存占用,评估序列化体积与缓存大小。

章节来源

  • SysDeptServiceImplTest.java

结论

部门管理模块以清晰的层次划分与完善的缓存机制为核心,提供了稳定高效的树形结构管理与 CRUD 能力。通过严格的层级校验与幂等初始化,保障了数据的正确性与可用性。在生产环境中,建议重点关注缓存一致性与性能指标,持续优化查询与写入路径。

[本节为总结性内容,不直接分析具体文件]

附录:API接口与使用案例

说明:以下为面向使用者的接口概览与调用示例,实际 Controller 层若存在,请结合项目中的控制器文件进一步查阅。

  • 接口清单

    • 获取部门树
      • 方法:GET
      • 路径:/api/dept/tree
      • 请求参数:key(维度键,如租户ID)
      • 返回:树形结构数组
    • 新增部门
      • 方法:POST
      • 路径:/api/dept
      • 请求体:{ name, code, parentId, sort, status }
      • 返回:Result 包装
    • 更新部门
      • 方法:PUT
      • 路径:/api/dept/{id}
      • 请求体:{ name, code, parentId, sort, status }
      • 返回:Result 包装
    • 删除部门
      • 方法:DELETE
      • 路径:/api/dept/{id}
      • 返回:Result 包装
    • 批量移动/调整排序
      • 方法:PATCH
      • 路径:/api/dept/batch/update
      • 请求体:[{ id, parentId, sort }]
      • 返回:Result 包装
  • 使用案例

    • 初始化后首次获取树:调用 /api/dept/tree?key=tenant_001,命中缓存则直接返回,否则从 DB 构建并回填缓存。
    • 新增子部门:先校验父部门存在,再插入并失效对应 key,下次读取自动重建。
    • 调整排序:批量更新 sort,保持父子关系不变,失效缓存后重新构建。

[本节为概念性接口说明,不直接映射具体源码文件]