6.8 KiB
6.8 KiB
包结构重构设计方案
概述
将 SQLite 数据访问层融入现有领域包结构,统一代码组织方式。
背景
当前存在两种包组织方式:
- 现有代码:按领域组织(attendance/bo/dao/po)
- SQLite 模块:按层组织(sqlite/entity/repository/service)
需要统一为按领域组织的结构。
设计决策
| 项目 | 决策 |
|---|---|
| 包结构 | 融入现有领域包(Package by Feature) |
| 数据源 | SQLite 为主,Excel 为导入源 |
| 旧代码 | DAO/BO/PO 标记 @Deprecated,逐步废弃 |
| Importer 职责 | 仅负责去重导入,不做业务校验 |
| 业务冲突 | 使用数据时处理,非导入时 |
目标结构
info.panli.junbo/
│
├── organization/ # 组织架构领域
│ ├── entity/ # JPA 实体
│ │ ├── EmployeeEntity.java
│ │ ├── EmployeeAliasEntity.java
│ │ ├── DepartmentEntity.java
│ │ ├── DepartmentRelationEntity.java
│ │ └── EmployeeDepartmentEntity.java
│ ├── repository/ # Spring Data 仓库
│ ├── service/ # 业务服务
│ └── importer/ # YAML 导入
│
├── attendance/ # 考勤领域
│ ├── entity/
│ │ ├── SignRecordEntity.java
│ │ ├── LeaveRecordEntity.java
│ │ └── WorkCalendarEntity.java
│ ├── repository/
│ ├── service/
│ ├── importer/ # Excel 导入
│ ├── bo/ @Deprecated
│ ├── dao/ @Deprecated
│ └── po/ @Deprecated
│
├── scrum/ # 敏捷迭代领域
│ ├── entity/
│ │ ├── SprintEntity.java
│ │ ├── StoryEntity.java
│ │ └── StoryMemberEntity.java
│ ├── repository/
│ ├── service/
│ ├── bo/ @Deprecated
│ ├── dao/ @Deprecated
│ └── po/ @Deprecated
│
├── kpa/ # 绩效考核领域
│ ├── entity/
│ │ ├── KpaRecordEntity.java
│ │ └── KpaEmployeeScoreEntity.java
│ ├── repository/
│ ├── service/
│ ├── bo/ @Deprecated
│ ├── dao/ @Deprecated
│ └── po/ @Deprecated
│
├── incentive/ # 激励领域
│ ├── entity/
│ │ └── IncentiveRecordEntity.java
│ ├── repository/
│ ├── service/
│ ├── bo/ @Deprecated
│ ├── dao/ @Deprecated
│ └── po/ @Deprecated
│
├── infrastructure/ # 基础设施(跨领域)
│ ├── config/
│ │ ├── JpaConfig.java
│ │ ├── WebConfig.java
│ │ └── DataInitializer.java
│ └── importer/
│ ├── DataImporter.java # 通用接口
│ └── ImportResult.java
│
└── api/ # REST API 层
├── OrganizationController.java
├── AttendanceController.java
├── SprintController.java
├── KpaController.java
├── IncentiveController.java
├── CalendarController.java
└── SyncController.java
Importer 设计
通用接口
// infrastructure/importer/DataImporter.java
public interface DataImporter<T> {
ImportResult importFrom(String filePath);
ImportResult importFromDefault();
}
@Data
@Builder
public class ImportResult {
private boolean success;
private int totalCount; // 总行数
private int insertedCount; // 新增数
private int skippedCount; // 重复跳过数
private List<String> errors; // 解析错误
}
职责边界
Importer 只做两件事:
- 读取外部数据(Excel/YAML)
- 去重后写入 SQLite
不做:
- 业务逻辑校验
- 冲突检测
- 数据合并
重复判断
完全重复 = 所有业务字段都相同,静默跳过。
业务冲突(如请假时间重叠)在使用数据时处理,非导入时。
文件迁移映射
Entity
| 原位置 | 新位置 |
|---|---|
| sqlite/entity/EmployeeEntity.java | organization/entity/ |
| sqlite/entity/EmployeeAliasEntity.java | organization/entity/ |
| sqlite/entity/DepartmentEntity.java | organization/entity/ |
| sqlite/entity/EmployeeDepartmentEntity.java | organization/entity/ |
| sqlite/entity/DepartmentRelationEntity.java | organization/entity/ |
| sqlite/entity/SignRecordEntity.java | attendance/entity/ |
| sqlite/entity/LeaveRecordEntity.java | attendance/entity/ |
| sqlite/entity/WorkCalendarEntity.java | attendance/entity/ |
| sqlite/entity/SprintEntity.java | scrum/entity/ |
| sqlite/entity/StoryEntity.java | scrum/entity/ |
| sqlite/entity/StoryMemberEntity.java | scrum/entity/ |
| sqlite/entity/KpaRecordEntity.java | kpa/entity/ |
| sqlite/entity/KpaEmployeeScoreEntity.java | kpa/entity/ |
| sqlite/entity/IncentiveRecordEntity.java | incentive/entity/ |
Repository
同 Entity 映射规则,跟随对应 Entity 移动。
Service/Importer
| 原位置 | 新位置 |
|---|---|
| sqlite/service/OrganizationImportService.java | organization/importer/ |
| sqlite/service/CalendarImportService.java | attendance/importer/ |
| sqlite/service/SignRecordImportService.java | attendance/importer/ |
| sqlite/service/LeaveRecordImportService.java | attendance/importer/ |
| sqlite/service/SprintStoryService.java | scrum/service/ |
| sqlite/service/KpaService.java | kpa/service/ |
| sqlite/service/IncentiveService.java | incentive/service/ |
Config 和 Controller
| 原位置 | 新位置 |
|---|---|
| sqlite/config/*.java | infrastructure/config/ |
| sqlite/controller/*.java | api/ |
实施步骤
阶段一:准备基础设施
- 创建
infrastructure/config/目录 - 创建
infrastructure/importer/目录 - 创建
api/目录 - 移动配置类和通用接口
阶段二:按领域迁移
迁移顺序:organization → attendance → scrum → kpa → incentive
每个领域:
- 创建 entity/repository/service/importer 目录
- 移动文件,更新 package 声明
- 标记旧 bo/dao/po 为 @Deprecated
阶段三:清理
- 删除空的 sqlite/ 目录
- 更新组件扫描配置(如需要)
- 运行全量测试
预计改动
| 类型 | 数量 |
|---|---|
| Entity 移动 | 14 |
| Repository 移动 | 14 |
| Service/Importer 移动 | 7 |
| Controller 移动 | 7 |
| Config 移动 | 2 |
| 旧代码标记废弃 | ~20 |