# 员工实体关系信息维护功能设计文档 ## 一、功能概述 ### 1.1 功能描述 员工实体关系信息维护功能用于管理员工与企业之间的关联关系,记录员工(或员工家庭关联人)在不同企业中担任的职务信息。该功能支持增删改查、批量导入导出等操作,完全参照采购交易管理和招聘信息功能的业务逻辑和UI交互。 ### 1.2 参照标准 - 后端业务逻辑:完全参照 `CcdiPurchaseTransaction`(采购交易管理) - 前端UI交互:完全参照 `ccdiPurchaseTransaction/index.vue` - 异步导入机制:完全参照采购交易的异步导入流程 ## 二、数据库设计 ### 2.1 表结构 基于 `ccdi_staff_enterprise_relation.csv` 定义: | 序号 | 字段名 | 类型 | 默认值 | 是否可为空 | 是否主键 | 注释 | |------|--------|------|--------|------------|----------|------| | 1 | id | BIGINT | 自增 | 否 | 是 | 主键,唯一标识 | | 2 | person_id | VARCHAR | - | 否 | 否 | 身份证号,关联员工表的外键 | | 3 | relation_person_post | VARCHAR | - | 是 | 否 | 关联人在企业的职务:股东、法人、高管、实际控制人等 | | 4 | social_credit_code | VARCHAR | - | 否 | 否 | 统一社会信用代码,关联企业主体信息表的外键 | | 5 | enterprise_name | VARCHAR | - | 是 | 否 | 企业名称(冗余存储,便于快速查询) | | 6 | status | INT | 1 | 否 | 否 | 关系是否有效:0 - 无效、1 - 有效(默认有效) | | 7 | remark | TEXT | - | 是 | 否 | 补充说明 | | 8 | data_source | VARCHAR(50) | - | 是 | 否 | 数据来源 | | 9 | is_employee | TINYINT(1) | 0 | 否 | 否 | 是否是员工:0-否 1-是 | | 10 | is_emp_family | TINYINT(1) | 1 | 否 | 否 | 是否是员工家庭关联人:0-否 1-是 | | 11 | is_customer | TINYINT(1) | 0 | 否 | 否 | 是否是信贷客户:0-否 1-是 | | 12 | is_cust_family | TINYINT(1) | 0 | 否 | 否 | 是否是信贷客户关联人:0-否 1-是 | | 13 | created_by | VARCHAR | - | 否 | 否 | 记录创建人 | | 14 | updated_by | VARCHAR | - | 是 | 否 | 记录更新人 | | 15 | create_time | DATETIME | - | 否 | 否 | 记录创建时间 | | 16 | update_time | DATETIME | - | 否 | 否 | 记录更新时间 | ### 2.2 唯一性约束 - 业务唯一性:`person_id + social_credit_code` 组合必须唯一 - 包含所有status值(0和1)的记录 - 新增和导入时需要校验唯一性 ## 三、后端设计 ### 3.1 模块结构 ``` com.ruoyi.ccdi ├── controller │ └── CcdiStaffEnterpriseRelationController.java ├── service │ ├── ICcdiStaffEnterpriseRelationService.java │ ├── ICcdiStaffEnterpriseRelationImportService.java │ └── impl │ ├── CcdiStaffEnterpriseRelationServiceImpl.java │ └── CcdiStaffEnterpriseRelationImportServiceImpl.java ├── mapper │ └── CcdiStaffEnterpriseRelationMapper.java └── domain ├── CcdiStaffEnterpriseRelation.java (实体类) ├── vo │ ├── CcdiStaffEnterpriseRelationVO.java (查询返回) │ ├── ImportResultVO.java (导入结果) │ ├── ImportStatusVO.java (导入状态) │ └── StaffEnterpriseRelationImportFailureVO.java (导入失败记录) ├── dto │ ├── CcdiStaffEnterpriseRelationAddDTO.java (新增) │ ├── CcdiStaffEnterpriseRelationEditDTO.java (编辑) │ └── CcdiStaffEnterpriseRelationQueryDTO.java (查询) └── excel └── CcdiStaffEnterpriseRelationExcel.java (导入导出) ``` ### 3.2 Controller接口定义 **基础路径:** `/ccdi/staffEnterpriseRelation` | 方法 | 路径 | 说明 | 权限 | |------|------|------|------| | GET | /list | 分页查询列表 | ccdi:staffEnterpriseRelation:list | | POST | /export | 导出 | ccdi:staffEnterpriseRelation:export | | GET | /{id} | 获取详情 | ccdi:staffEnterpriseRelation:query | | POST | / | 新增 | ccdi:staffEnterpriseRelation:add | | PUT | / | 修改 | ccdi:staffEnterpriseRelation:edit | | DELETE | /{ids} | 删除 | ccdi:staffEnterpriseRelation:remove | | POST | /importTemplate | 下载导入模板 | - | | POST | /importData | 异步导入 | ccdi:staffEnterpriseRelation:import | | GET | /importStatus/{taskId} | 查询导入状态 | ccdi:staffEnterpriseRelation:import | | GET | /importFailures/{taskId} | 查询导入失败记录 | ccdi:staffEnterpriseRelation:import | ### 3.3 核心业务逻辑 #### 3.3.1 唯一性校验 ```java // 新增时校验 if (mapper.existsByPersonIdAndSocialCreditCode(personId, socialCreditCode)) { throw new RuntimeException("该员工与企业的关系已存在"); } ``` #### 3.3.2 默认值设置 ```java entity.setStatus(1); // 有效 entity.setIsEmployee(0); entity.setIsEmpFamily(1); entity.setIsCustomer(0); entity.setIsCustFamily(0); entity.setDataSource("MANUAL"); // 或 "IMPORT" ``` #### 3.3.3 异步导入流程 1. 接收文件 → 解析Excel → 生成UUID任务ID → 立即返回 2. @Async异步方法: - 批量查询已存在的 person_id + social_credit_code 组合 - 遍历校验,分类成功/失败 - 批量插入成功数据(500条/批) - 失败记录存Redis(7天过期) - 更新导入状态到Redis 3. 前端轮询查询状态(2秒/次,最多150次) #### 3.3.4 Redis存储结构 ``` import:staffEnterpriseRelation:{taskId} // 导入状态(Hash) import:staffEnterpriseRelation:{taskId}:failures // 失败记录(List,JSON序列化) ``` ## 四、前端设计 ### 4.1 文件结构 ``` ruoyi-ui/src/ ├── views │ └── ccdiStaffEnterpriseRelation │ └── index.vue └── api └── ccdiStaffEnterpriseRelation.js ``` ### 4.2 列表页设计 #### 4.2.1 查询表单 - 身份证号(模糊查询) - 统一社会信用代码(模糊查询) - 企业名称(模糊查询) - 状态下拉选择(有效/无效) - 搜索、重置按钮 #### 4.2.2 操作按钮 - 新增 - 导入 - 导出 - 查看导入失败记录(条件显示) - 右侧工具栏(显示搜索、刷新) #### 4.2.3 表格列 | 列名 | 字段 | 说明 | |------|------|------| | 选择框 | - | 多选 | | 身份证号 | personId | show-overflow-tooltip | | 企业名称 | enterpriseName | show-overflow-tooltip | | 关联人在企业的职务 | relationPersonPost | - | | 状态 | status | 字典翻译 | | 数据来源 | dataSource | 字典翻译 | | 创建时间 | createTime | 格式化 | | 操作 | - | 详情、编辑、删除 | ### 4.3 新增/编辑对话框 **宽度:** 800px **表单字段:** - 身份证号:可搜索下拉(el-select + remote + filterable) - 统一社会信用代码:输入框 + 18位格式校验 - 企业名称:输入框 + 必填 - 关联人在企业的职务:输入框 + 可选 - 状态:下拉选择 + 默认值1(有效) - 补充说明:textarea + 可选 **不显示字段:** - data_source(后端自动设置) - is_employee、is_emp_family、is_customer、is_cust_family(后端自动设置) ### 4.4 导入功能 #### 4.4.1 导入对话框 - 拖拽上传区域 - 模板下载链接 - 仅允许 .xlsx / .xls 格式 #### 4.4.2 导入流程 1. 文件上传成功 → 显示通知"导入任务已提交" 2. 每2秒轮询查询导入状态 3. 完成后显示结果通知: - SUCCESS:全部成功!共导入N条数据 - PARTIAL_SUCCESS:成功N条,失败M条 4. 如果有失败记录,显示"查看导入失败记录"按钮 #### 4.4.3 查看失败记录 - 点击按钮弹窗显示失败列表 - 失败记录包含:personId、socialCreditCode、enterpriseName、errorMessage - 支持分页 - 支持清除历史记录 ## 五、数据字典配置 ### 5.1 关系状态字典 **字典类型:** `ccdi_relation_status` | 字典值 | 字典标签 | 排序 | |--------|----------|------| | 0 | 无效 | 2 | | 1 | 有效 | 1 | ### 5.2 数据来源字典 **字典类型:** `ccdi_data_source` | 字典值 | 字典标签 | 排序 | |--------|----------|------| | MANUAL | 手动录入 | 1 | | SYSTEM | 系统同步 | 2 | | IMPORT | 批量导入 | 3 | | API | 接口获取 | 4 | ## 六、Excel导入模板 ### 6.1 模板列定义 | 列名 | 字段名 | 是否必填 | 校验规则 | 说明 | |------|--------|----------|----------|------| | 身份证号 | personId | 是 | 18位身份证格式 | 关联员工表 | | 统一社会信用代码 | socialCreditCode | 是 | 18位统一信用代码格式 | 关联企业表 | | 企业名称 | enterpriseName | 是 | 最大长度200 | 冗余存储 | | 关联人在企业的职务 | relationPersonPost | 否 | 最大长度100 | 如:股东、法人、高管等 | | 补充说明 | remark | 否 | TEXT类型 | 可选填写 | ### 6.2 后端自动设置 - status = 1(有效) - data_source = "IMPORT" - is_employee = 0 - is_emp_family = 1 - is_customer = 0 - is_cust_family = 0 ### 6.3 导入校验规则 1. 唯一性校验:person_id + social_credit_code 组合重复则失败 2. 格式校验:身份证号18位、统一社会信用代码18位 3. 必填校验:personId、socialCreditCode、enterpriseName 4. 失败记录:记录到Redis,返回详细信息 ## 七、菜单权限配置 ### 7.1 菜单信息 - **菜单名称:** 员工实体关系 - **路由地址:** ccdiStaffEnterpriseRelation - **组件路径:** ccdiStaffEnterpriseRelation/index - **上级菜单:** 待定(根据实际菜单结构配置) ### 7.2 权限标识 ``` ccdi:staffEnterpriseRelation:list # 查询列表 ccdi:staffEnterpriseRelation:query # 查询详情 ccdi:staffEnterpriseRelation:add # 新增 ccdi:staffEnterpriseRelation:edit # 修改 ccdi:staffEnterpriseRelation:remove # 删除 ccdi:staffEnterpriseRelation:export # 导出 ccdi:staffEnterpriseRelation:import # 导入 ``` ## 八、一致性校验清单 ### 8.1 后端一致性 - [ ] Controller接口定义完全一致(路径、参数、返回值) - [ ] Service层方法命名和逻辑结构一致 - [ ] 异步导入实现方式一致(@Async、Redis存储、轮询机制) - [ ] 批量插入分批大小一致(500条/批) - [ ] 唯一性校验逻辑一致(先批量查询,再逐条校验) - [ ] 失败记录存储方式一致(Redis JSON序列化,7天过期) - [ ] 导入状态更新逻辑一致(SUCCESS/PARTIAL_SUCCESS) - [ ] Swagger注解格式一致 - [ ] 权限注解格式一致 ### 8.2 前端一致性 - [ ] 列表页布局结构一致(查询表单、按钮栏、表格、分页) - [ ] 新增/编辑对话框布局一致 - [ ] 详情对话框使用 el-descriptions 展示 - [ ] 导入对话框一致(拖拽上传、模板下载链接) - [ ] 导入轮询机制一致(2秒间隔、150次上限) - [ ] 导入结果通知方式一致($notify、不同类型) - [ ] localStorage存储任务ID方式一致 - [ ] 查看失败记录弹窗一致 - [ ] API调用方式一致(async/await、错误处理) ## 九、技术要点 ### 9.1 关键技术 - **MyBatis Plus 3.5.10**:CRUD操作和分页 - **EasyExcel**:Excel导入导出 - **@Async**:异步导入 - **Redis**:导入状态和失败记录存储 - **Swagger 3**:API文档 ### 9.2 性能优化 - 批量插入:500条/批 - 批量查询已存在数据:减少数据库查询次数 - Redis缓存:减少重复查询 ### 9.3 安全考虑 - 权限注解:@PreAuthorize - SQL注入防护:使用MyBatis Plus参数绑定 - XSS防护:前端输入校验 ## 十、测试要点 ### 10.1 功能测试 - [ ] 新增功能:唯一性校验 - [ ] 编辑功能:修改各个字段 - [ ] 删除功能:单个删除、批量删除 - [ ] 导入功能:正常数据、重复数据、格式错误数据 - [ ] 导出功能:查询条件导出 - [ ] 查询功能:模糊查询、状态筛选 ### 10.2 性能测试 - [ ] 导入1000条数据的响应时间 - [ ] 查询10万条数据的分页性能 - [ ] 并发导入的处理能力 ### 10.3 兼容性测试 - [ ] 不同浏览器兼容性 - [ ] Excel 2003/2007/2010格式兼容性 ## 十一、附录 ### 11.1 参照文件 - **后端参照:** - `CcdiPurchaseTransactionController.java` - `CcdiPurchaseTransactionServiceImpl.java` - `CcdiPurchaseTransactionImportServiceImpl.java` - **前端参照:** - `ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue` - `ruoyi-ui/src/api/ccdiPurchaseTransaction.js` ### 11.2 数据库CSV文件 - `doc/database-docs/ccdi_staff_enterprise_relation.csv`