## Context 员工信息维护是纪检初核系统的核心基础功能。系统需要管理银行内部员工的基础信息及其亲属关系,以便在进行纪检初核工作时能够快速查询相关人员信息。 **约束条件:** - 必须遵循若依框架的代码规范 - 必须使用项目已定义的命名规范(模块前缀 `ccdi_`) - 必须支持 Excel 导入导出功能 - 亲属信息需要与员工信息关联管理 **相关方:** - 纪检人员:查询员工及亲属信息 - 系统管理员:批量导入员工数据 - 人事部门:维护员工基础信息 ## Goals / Non-Goals ### Goals 1. 提供完整的员工信息 CRUD 接口 2. 支持员工亲属信息的关联管理(一对多关系) 3. 支持 Excel 批量导入导出,导入时可同时导入亲属信息 4. 遵循现有代码模式(参考 `ccdi_intermediary_blacklist` 模块) ### Non-Goals - 不涉及前端页面的实现(本次仅实现后端接口) - 不涉及员工组织架构的复杂层级管理 - 不涉及员工权限、角色管理(使用若依现有系统) - 不涉及亲属关系的高级查询功能 ## Decisions ### 1. 数据模型设计 **决策:使用两张表存储员工和亲属信息** ``` ccdi_employee (员工主表) ├── employee_id (主键) ├── name (姓名) ├── teller_no (柜员号, UNIQUE) ├── org_no (所属机构号) ├── id_card (身份证号, UNIQUE) ├── phone (电话) ├── hire_date (入职时间) ├── status (状态: 0=在职, 1=离职) └── 审计字段 (create_by, create_time, update_by, update_time) ccdi_employee_relative (员工亲属表) ├── relative_id (主键) ├── employee_id (外键 → ccdi_employee.employee_id) ├── relative_name (亲属姓名) ├── relative_id_card (亲属身份证号) ├── relative_phone (亲属手机号) ├── relationship (与员工关系) └── 审计字段 ``` **理由:** - 符合数据库范式设计,避免数据冗余 - 支持一对多关系(一个员工可以有多个亲属) - 便于查询和维护 **替代方案考虑:** - 方案2:将亲属信息存储为 JSON 字段 - 优点:单表存储,查询简单 - 缺点:无法对亲属信息建索引,不支持复杂查询 - **拒绝原因**:未来可能需要按亲属信息查询 ### 2. 亲属信息维护方式 **决策:在员工的新增/编辑接口中同时支持亲属信息** ``` POST /dpc/employee { "name": "张三", "tellerNo": "001", "orgNo": "1001", "idCard": "110101199001011234", "phone": "13800138000", "hireDate": "2020-01-01", "relatives": [ { "relativeName": "李四", "relativeIdCard": "110101199001011235", "relativePhone": "13800138001", "relationship": "配偶" } ] } ``` **理由:** - 减少接口数量,简化前端调用 - 保证员工与亲属信息的原子性操作 - 符合业务场景(新增员工时同时录入亲属信息) ### 3. Excel 导入格式 **决策:使用多 Sheet 导入方式** ``` Sheet1: 员工信息 | 姓名 | 柜员号 | 所属机构号 | 身份证号 | 电话 | 入职时间 | |------|--------|------------|----------|------|----------| | 张三 | 001 | 1001 | ... | ... | 2020-01-01 | Sheet2: 亲属信息 (可选) | 员工身份证号 | 亲属姓名 | 亲属身份证号 | 亲属手机号 | 与员工关系 | |--------------|----------|--------------|------------|------------| | 110101... | 李四 | 110101... | 138... | 配偶 | ``` **理由:** - 清晰分离员工和亲属数据 - 支持仅导入员工信息(亲属信息为可选) - 通过员工身份证号关联两张表 **替代方案考虑:** - 方案2:单 Sheet 导入,亲属信息嵌套在员工行中 - 缺点:格式复杂,Excel 难以编辑 - **拒绝原因**:用户体验差 ### 4. 字典数据 **决策:使用字典管理"与员工关系"字段和"员工状态"字段** ``` 字典类型: ccdi_relative_relationship 字典数据: 配偶、父亲、母亲、子女、兄弟姐妹、其他 字典类型: ccdi_employee_status 字典数据: 在职(0)、离职(1) ``` **理由:** - 符合若依框架设计模式 - 便于后续扩展关系类型 - 统一管理枚举值 ### 5. 数据库约束 **决策:柜员号和身份证号添加唯一约束** ```sql UNIQUE KEY `uk_teller_no` (`teller_no`), UNIQUE KEY `uk_id_card` (`id_card`) ``` **理由:** - 柜员号是员工的唯一标识,不允许重复 - 身份证号具有唯一性,不允许重复 - 防止数据重复和业务逻辑错误 ### 6. 命名规范 **决策:遵循项目规范** - 表名: `ccdi_employee`, `ccdi_employee_relative` - 实体类: `CcdiEmployee`, `CcdiEmployeeRelative` - Controller: `CcdiEmployeeController` - 权限标识: `dpc:employee:*` - **所有实体类、DTO、VO 类统一使用 @Data 注解** **理由:** - 与现有 `ccdi_intermediary_blacklist` 模块保持一致 - 符合项目编码规范 - @Data 注解自动生成 getter/setter,代码简洁 ### 7. MyBatis Plus 使用策略 **决策:区分简单 CRUD 和复杂查询的实现方式** **简单 CRUD 操作(使用 MyBatis Plus 方法):** - BaseMapper 提供的方法:`insert`, `deleteById`, `deleteByIds`, `updateById`, `selectById`, `selectList`, `selectCount` - 条件构造器:`QueryWrapper`, `LambdaQueryWrapper` 用于简单条件查询 - 适用场景:单表增删改查、简单条件筛选 **复杂查询操作(使用 XML 映射):** - 多表关联查询(员工 + 亲属信息) - 复杂条件组合查询 - 需要自定义结果映射的查询 - 适用场景:关联查询、复杂业务查询 **示例:** ```java // 简单查询 - 使用 MyBatis Plus employeeMapper.selectById(id); employeeMapper.selectList(new LambdaQueryWrapper() .eq(CcdiEmployee::getTellerNo, tellerNo)); // 复杂查询 - 使用 XML EmployeeWithRelativesVO selectEmployeeWithRelatives(Long id); ``` **理由:** - 简单 CRUD 使用 MyBatis Plus 减少代码量,提高开发效率 - 复杂查询使用 XML 保持 SQL 可读性和可维护性 - 符合项目技术规范(MyBatis Plus 3.5.10,Spring Boot 3 适配版) ## Risks / Trade-offs ### 风险1: Excel 导入时亲属数据关联失败 **风险描述**: 导入员工和亲属信息时,若员工身份证号填写错误,亲属信息无法关联。 **缓解措施**: - 导入时进行数据校验 - 提供详细的导入错误报告 - 支持"仅导入员工"模式,亲属信息可后续补录 ### 风险2: 亲属信息数据量过大 **风险描述**: 某些员工可能有大量亲属记录,影响查询性能。 **缓解措施**: - 建立适当的数据库索引 - 列表查询时默认不返回亲属详情 - 提供单独的亲属查询接口 ### 权衡: 简化 vs 完整性 - **当前方案**: 使用两表设计,支持完整的一对多关系 - **简化方案**: 将亲属信息存储为 JSON - **选择**: 当前方案,因为纪检场景可能需要按亲属信息查询 ## Migration Plan ### 后端部署步骤 1. 执行数据库脚本,创建表和字典数据 2. 部署后端代码 3. (前端开发阶段)配置菜单和权限数据 ### 回滚计划 1. 从数据库中删除新增的表和字典数据 2. 移除后端代码部署 ### 前端开发注意事项 - 开发前端页面时需同步在 `sys_menu` 表中插入菜单及权限数据 - 菜单路径:信息维护 → 员工信息管理 - 权限标识:`dpc:employee:list`, `dpc:employee:query`, `dpc:employee:add`, `dpc:employee:edit`, `dpc:employee:remove`, `dpc:employee:export`, `dpc:employee:import` ## Open Questions 1. **亲属关系是否需要支持多层级?** (如:亲属的亲属) - **当前决策**: 否,仅支持员工的直接亲属 2. **导入时是否需要支持"更新已有员工"模式?** - **当前决策**: 是,通过柜员号或身份证号判断 3. ~~**员工离职后如何处理?**~~ - **已确认**: 增加状态字段(0=在职, 1=离职) 4. ~~**身份证号和柜员号是否需要唯一性约束?**~~ - **已确认**: 两者都需要唯一约束