219 lines
6.8 KiB
Markdown
219 lines
6.8 KiB
Markdown
# 包结构重构设计方案
|
||
|
||
## 概述
|
||
|
||
将 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 设计
|
||
|
||
### 通用接口
|
||
|
||
```java
|
||
// 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 只做两件事:
|
||
1. 读取外部数据(Excel/YAML)
|
||
2. 去重后写入 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/ |
|
||
|
||
## 实施步骤
|
||
|
||
### 阶段一:准备基础设施
|
||
|
||
1. 创建 `infrastructure/config/` 目录
|
||
2. 创建 `infrastructure/importer/` 目录
|
||
3. 创建 `api/` 目录
|
||
4. 移动配置类和通用接口
|
||
|
||
### 阶段二:按领域迁移
|
||
|
||
迁移顺序:organization → attendance → scrum → kpa → incentive
|
||
|
||
每个领域:
|
||
1. 创建 entity/repository/service/importer 目录
|
||
2. 移动文件,更新 package 声明
|
||
3. 标记旧 bo/dao/po 为 @Deprecated
|
||
|
||
### 阶段三:清理
|
||
|
||
1. 删除空的 sqlite/ 目录
|
||
2. 更新组件扫描配置(如需要)
|
||
3. 运行全量测试
|
||
|
||
## 预计改动
|
||
|
||
| 类型 | 数量 |
|
||
|------|------|
|
||
| Entity 移动 | 14 |
|
||
| Repository 移动 | 14 |
|
||
| Service/Importer 移动 | 7 |
|
||
| Controller 移动 | 7 |
|
||
| Config 移动 | 2 |
|
||
| 旧代码标记废弃 | ~20 |
|