376 lines
14 KiB
Markdown
376 lines
14 KiB
Markdown
# 员工实体关系信息维护功能设计文档
|
||
|
||
## 一、功能概述
|
||
|
||
### 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`
|