- Maven 模块从 ruoyi-ccdi 重命名为 ruoyi-info-collection - Java 包名从 com.ruoyi.ccdi 改为 com.ruoyi.info.collection - MyBatis XML 命名空间同步更新 - 保留数据库表名、API URL、权限标识中的 ccdi 前缀 - 更新项目文档中的模块引用
10 KiB
10 KiB
员工招聘信息管理功能设计文档
文档版本: 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
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:
// 查询条件
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 批量导入功能设计
核心优化点:
- 批量查询已存在记录: 使用
selectBatchIds一次性查询 - 批量插入: 使用
saveBatch()方法 - 批量更新: 使用
updateBatchById()方法 - 错误信息: 只返回错误的数据行,成功数据不展示
性能提升:
- 原方案: ~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 单元测试
测试范围:
- 实体类校验注解测试
- 数据转换工具方法测试
- 业务逻辑核心方法测试
关键测试用例:
- 正常数据导入测试
- 身份证格式校验测试
- 批量插入性能测试
6.2 集成测试
测试流程:
- 登录获取Token
- 分页查询测试
- 单条新增测试
- 单条修改测试
- 批量导入测试
- 导出测试
- 批量删除测试
6.3 性能指标
| 测试场景 | 预期性能 |
|---|---|
| 分页查询(1000条) | < 200ms |
| 单条新增 | < 100ms |
| 批量导入(1000条) | < 5s |
| 批量删除(100条) | < 500ms |
| 导出(1000条) | < 2s |
7. 实施步骤
第一步:数据库准备
- 执行建表SQL
- 在菜单表中添加菜单和权限配置
第二步:后端开发
- 创建枚举类
- 创建实体类、DTO、VO、Excel类
- 创建Mapper接口和XML
- 创建Service接口和实现
- 创建Controller
- 编写单元测试
- Swagger-UI测试
第三步:前端开发
- 创建API接口定义
- 开发表格查询页面
- 开发表单组件
- 开发导入对话框
- 配置路由
- 配置菜单
第四步:集成测试
- 准备测试数据
- 执行集成测试
- 验证功能
- 生成测试报告
第五步:文档编写
- 生成API文档
- 编写使用说明
8. 附录
8.1 Excel导入模板字段顺序
按CSV字段顺序设计:
- 招聘项目编号
- 招聘项目名称
- 职位名称
- 职位类别
- 职位描述
- 应聘人员姓名
- 应聘人员学历
- 应聘人员证件号码
- 应聘人员毕业院校
- 应聘人员专业
- 应聘人员毕业年月
- 录用情况
- 面试官1姓名
- 面试官1工号
- 面试官2姓名
- 面试官2工号
8.2 MyBatis Plus配置
确保项目中已配置MyBatis Plus分页插件:
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
文档结束