# 员工招聘信息管理功能设计文档

**文档版本:** 1.0
**创建日期:** 2025-02-05
**模块名称:** ccdi-staff-recruitment
**作者:** Claude

---

## 1. 概述

### 1.1 功能简介

员工招聘信息管理模块提供招聘信息的记录、查询、导入导出等基础维护功能,支持单条和批量操作。

### 1.2 业务场景

- 简单的招聘信息记录,作为数据存档使用
- 支持招聘信息的增删改查操作
- 支持Excel批量导入和导出

### 1.3 技术选型

- **后端框架:** Spring Boot 3.5.8 + MyBatis Plus 3.5.10
- **数据库:** MySQL 8.2.0
- **前端框架:** Vue 2.6.12 + Element UI 2.15.14
- **数据校验:** javax.validation + 自定义校验注解

---

## 2. 数据库设计

### 2.1 表结构

**表名:** `ccdi_staff_recruitment`

```sql
CREATE TABLE `ccdi_staff_recruitment` (
  `recruit_id` varchar(32) NOT NULL COMMENT '招聘项目编号',
  `recruit_name` varchar(100) NOT NULL COMMENT '招聘项目名称',
  `pos_name` varchar(100) NOT NULL COMMENT '职位名称',
  `pos_category` varchar(50) NOT NULL COMMENT '职位类别',
  `pos_desc` text NOT NULL COMMENT '职位描述',
  `cand_name` varchar(20) NOT NULL COMMENT '应聘人员姓名',
  `cand_edu` varchar(20) NOT NULL COMMENT '应聘人员学历',
  `cand_id` varchar(18) NOT NULL COMMENT '应聘人员证件号码',
  `cand_school` varchar(50) NOT NULL COMMENT '应聘人员毕业院校',
  `cand_major` varchar(30) NOT NULL COMMENT '应聘人员专业',
  `cand_grad` varchar(6) NOT NULL COMMENT '应聘人员毕业年月',
  `admit_status` varchar(10) NOT NULL COMMENT '录用情况:录用、未录用、放弃',
  `interviewer_name1` varchar(20) DEFAULT NULL COMMENT '面试官1姓名',
  `interviewer_id1` varchar(10) DEFAULT NULL COMMENT '面试官1工号',
  `interviewer_name2` varchar(20) DEFAULT NULL COMMENT '面试官2姓名',
  `interviewer_id2` varchar(10) DEFAULT NULL COMMENT '面试官2工号',
  `created_by` varchar(20) NOT NULL COMMENT '记录创建人',
  `updated_by` varchar(20) DEFAULT NULL COMMENT '记录更新人',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`recruit_id`),
  KEY `idx_cand_id` (`cand_id`),
  KEY `idx_admit_status` (`admit_status`),
  KEY `idx_interviewer_id1` (`interviewer_id1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='员工招聘信息表';
```

### 2.2 索引设计

- **主键索引:** `recruit_id`
- **业务索引:** `cand_id`, `admit_status`, `interviewer_id1`

### 2.3 枚举值设计

**录用状态 (admit_status):**
| 枚举值 | 说明 |
|--------|------|
| 录用 | 已录用该候选人 |
| 未录用 | 未录用该候选人 |
| 放弃 | 候选人放弃 |

---

## 3. 后端设计

### 3.1 模块结构

```
ruoyi-info-collection/
├── domain/
│   ├── CcdiStaffRecruitment.java                    # 实体类
│   ├── dto/
│   │   ├── CcdiStaffRecruitmentQueryDTO.java        # 查询DTO
│   │   ├── CcdiStaffRecruitmentAddDTO.java          # 新增DTO
│   │   └── CcdiStaffRecruitmentEditDTO.java         # 修改DTO
│   ├── vo/
│   │   └── CcdiStaffRecruitmentVO.java              # 返回VO
│   └── excel/
│       └── CcdiStaffRecruitmentExcel.java           # Excel导入导出类
├── mapper/
│   ├── CcdiStaffRecruitmentMapper.java              # MyBatis Mapper接口
│   └── xml/
│       └── CcdiStaffRecruitmentMapper.xml           # MyBatis XML映射
├── service/
│   ├── ICcdiStaffRecruitmentService.java            # 服务接口
│   └── impl/
│       └── CcdiStaffRecruitmentServiceImpl.java     # 服务实现
└── controller/
    └── CcdiStaffRecruitmentController.java          # 控制器
```

### 3.2 API接口设计

**基础路径:** `/ccdi/staffRecruitment`

| 接口功能   | HTTP方法 | 路径                | 权限标识                         |
|--------|--------|-------------------|------------------------------|
| 分页查询   | GET    | `/list`           | ccdi:staffRecruitment:list   |
| 详情查询   | GET    | `/{recruitId}`    | ccdi:staffRecruitment:query  |
| 新增     | POST   | `/`               | ccdi:staffRecruitment:add    |
| 修改     | PUT    | `/`               | ccdi:staffRecruitment:edit   |
| 删除     | DELETE | `/{recruitIds}`   | ccdi:staffRecruitment:remove |
| 导入模板下载 | GET    | `/importTemplate` | ccdi:staffRecruitment:import |
| 批量导入   | POST   | `/importData`     | ccdi:staffRecruitment:import |
| 导出     | POST   | `/export`         | ccdi:staffRecruitment:export |

### 3.3 查询参数设计

**CcdiStaffRecruitmentQueryDTO:**

```java
// 查询条件
private String recruitName;      // 招聘项目名称(模糊查询)
private String posName;          // 职位名称(模糊查询)
private String candName;         // 候选人姓名(模糊查询)
private String candId;           // 证件号码(精确查询)
private String admitStatus;      // 录用状态(精确查询)
private String interviewerName;  // 面试官姓名(模糊查询,查询面试官1或2)
private String interviewerId;    // 面试官工号(精确查询,查询面试官1或2)

// 分页参数
private Integer pageNum = 1;
private Integer pageSize = 10;
```

### 3.4 数据校验规则

| 字段          | 校验规则                        | 错误提示                 |
|-------------|-----------------------------|----------------------|
| recruitName | @NotBlank, @Size(max=100)   | 招聘项目名称不能为空/长度不能超过100 |
| posName     | @NotBlank, @Size(max=100)   | 职位名称不能为空/长度不能超过100   |
| candName    | @NotBlank, @Size(max=20)    | 应聘人员姓名不能为空/长度不能超过20  |
| candId      | @NotBlank, @Pattern(身份证正则)  | 证件号码不能为空/格式不正确       |
| candGrad    | @NotBlank, @Pattern(YYYYMM) | 毕业年月不能为空/格式不正确       |
| admitStatus | @NotBlank, @EnumValid       | 录用情况不能为空/状态值不合法      |

### 3.5 批量导入功能设计

**核心优化点:**

1. **批量查询已存在记录:** 使用 `selectBatchIds` 一次性查询
2. **批量插入:** 使用 `saveBatch()` 方法
3. **批量更新:** 使用 `updateBatchById()` 方法
4. **错误信息:** 只返回错误的数据行,成功数据不展示

**性能提升:**

- 原方案: ~3000次数据库操作 (导入1000条)
- 优化后: ~3次数据库操作 (导入1000条)
- 性能提升: ~1000倍

**导入逻辑:**

```
1. 收集所有recruit_id
2. 批量查询已存在的记录
3. 遍历Excel数据:
   - 数据转换和校验
   - 分类为: 待新增列表、待更新列表
   - 记录校验失败的数据
4. 批量插入待新增数据
5. 批量更新待更新数据
6. 只返回错误信息
```

---

## 4. 前端设计

### 4.1 页面结构

```
ruoyi-ui/src/views/ccdiStaffRecruitment/
├── index.vue           # 列表页面(主页面)
└── components/
    ├── RecruitmentForm.vue    # 新增/修改表单组件
    └── ImportDialog.vue       # 导入对话框组件
```

### 4.2 功能列表

**列表页面 (index.vue):**

- 顶部查询表单
    - 招聘项目名称(模糊查询)
    - 职位名称(模糊查询)
    - 候选人姓名(模糊查询)
    - 证件号码(精确查询)
    - 录用状态(下拉选择)
    - 面试官姓名(模糊查询)
    - 面试官工号(精确查询)
- 数据表格
    - 展示所有字段信息
    - 支持排序
- 操作按钮
    - 新增
    - 批量导入
    - 导出
    - 批量删除
- 行操作
    - 修改
    - 删除

**表单组件 (RecruitmentForm.vue):**

- 所有必填字段添加 `required: true`
- 证件号码正则校验
- 毕业年月格式校验(YYYYMM)
- 录用状态下拉选择(枚举值)

---

## 5. 异常处理

### 5.1 异常分类

| 异常类型                  | HTTP状态码 | 使用场景   |
|-----------------------|---------|--------|
| ServiceException      | 500     | 业务逻辑异常 |
| ValidationException   | 400     | 参数校验失败 |
| DuplicateKeyException | 409     | 主键冲突   |
| FileNotFoundException | 404     | 文件不存在  |

### 5.2 统一异常处理

使用 `@RestControllerAdvice` 全局异常处理器捕获和处理异常。

---

## 6. 测试策略

### 6.1 单元测试

**测试范围:**

- 实体类校验注解测试
- 数据转换工具方法测试
- 业务逻辑核心方法测试

**关键测试用例:**

1. 正常数据导入测试
2. 身份证格式校验测试
3. 批量插入性能测试

### 6.2 集成测试

**测试流程:**

1. 登录获取Token
2. 分页查询测试
3. 单条新增测试
4. 单条修改测试
5. 批量导入测试
6. 导出测试
7. 批量删除测试

### 6.3 性能指标

| 测试场景        | 预期性能    |
|-------------|---------|
| 分页查询(1000条) | < 200ms |
| 单条新增        | < 100ms |
| 批量导入(1000条) | < 5s    |
| 批量删除(100条)  | < 500ms |
| 导出(1000条)   | < 2s    |

---

## 7. 实施步骤

### 第一步:数据库准备

1. 执行建表SQL
2. 在菜单表中添加菜单和权限配置

### 第二步:后端开发

1. 创建枚举类
2. 创建实体类、DTO、VO、Excel类
3. 创建Mapper接口和XML
4. 创建Service接口和实现
5. 创建Controller
6. 编写单元测试
7. Swagger-UI测试

### 第三步:前端开发

1. 创建API接口定义
2. 开发表格查询页面
3. 开发表单组件
4. 开发导入对话框
5. 配置路由
6. 配置菜单

### 第四步:集成测试

1. 准备测试数据
2. 执行集成测试
3. 验证功能
4. 生成测试报告

### 第五步:文档编写

1. 生成API文档
2. 编写使用说明

---

## 8. 附录

### 8.1 Excel导入模板字段顺序

按CSV字段顺序设计:

1. 招聘项目编号
2. 招聘项目名称
3. 职位名称
4. 职位类别
5. 职位描述
6. 应聘人员姓名
7. 应聘人员学历
8. 应聘人员证件号码
9. 应聘人员毕业院校
10. 应聘人员专业
11. 应聘人员毕业年月
12. 录用情况
13. 面试官1姓名
14. 面试官1工号
15. 面试官2姓名
16. 面试官2工号

### 8.2 MyBatis Plus配置

确保项目中已配置MyBatis Plus分页插件:

```java
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
    return interceptor;
}
```

---

**文档结束**
