# 包结构重构设计方案 ## 概述 将 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 { 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 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 |