1. 项目背景与核心需求
人力资源管理系统(HRM)作为企业数字化转型的核心组件,正在从传统C/S架构向B/S架构快速演进。这个基于Java SSM框架+Vue.js的前后端分离项目,正是针对中小型企业人事管理痛点设计的轻量级解决方案。我在实际开发中发现,市面上多数开源HR系统存在两个共性问题:要么功能过于庞杂导致学习成本高,要么扩展性差难以二次开发。
这个系统主要解决以下核心场景:
- 员工档案的电子化集中管理(替代Excel表格)
- 考勤数据的自动化统计(对接钉钉/企业微信API)
- 薪资计算的公式化处理(支持自定义计算规则)
- 招聘流程的线上化跟踪(从简历入库到offer发放)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 后端技术栈选型
采用经典的SSM(Spring+SpringMVC+MyBatis)组合而非Spring Boot,主要基于三点考虑:
- 毕业论文需要体现传统框架的掌握程度
- MyBatis的SQL可控性更适合复杂报表查询
- 学校实验环境通常已配置Tomcat服务器
数据库设计时特别注意了这几个关键点:
sql复制-- 员工表增加departure_flag标记而非直接删除记录
ALTER TABLE employee ADD COLUMN departure_flag TINYINT DEFAULT 0;
-- 建立薪资项关联表实现可配置化
CREATE TABLE salary_item (
item_id INT PRIMARY KEY AUTO_INCREMENT,
item_name VARCHAR(50) NOT NULL,
is_deduction BOOLEAN DEFAULT FALSE,
is_taxable BOOLEAN DEFAULT TRUE
);
2.2 前端技术方案
Vue 2.x版本的选择经过实际对比测试:
- 相比React更低的学习曲线(适合毕业论文周期)
- Element UI组件库完美匹配管理系统需求
- 与SSM后端配合时axios拦截器处理更简洁
路由设计采用动态加载方案:
javascript复制// 根据用户角色过滤路由表
function filterRoutes(routes, roles) {
return routes.filter(route => {
if (route.meta && route.meta.roles) {
return roles.some(role => route.meta.roles.includes(role))
}
return true
})
}
3. 核心功能实现细节
3.1 考勤异常检测算法
传统考勤系统往往只做简单打卡记录,我们实现了基于规则引擎的智能检测:
java复制// 使用Drools规则引擎检测异常考勤
public class AttendanceCheckRule {
public static final int LATE_THRESHOLD = 30; // 迟到阈值(分钟)
@Rule
public void checkLate(AttendanceRecord record) {
if (record.getClockIn() == null) return;
LocalTime standardTime = LocalTime.of(9, 0);
long diff = ChronoUnit.MINUTES.between(
standardTime,
record.getClockIn().toLocalTime()
);
if (diff > LATE_THRESHOLD) {
record.setStatus("late");
update(record);
}
}
}
3.2 薪资计算引擎
支持自定义公式的薪资模块是最大亮点:
- 采用逆波兰表达式解析计算式
- 内置20+常用函数(社保计算、个税累进等)
- 历史版本快照功能
java复制// 薪资项计算公式解析示例
public class SalaryCalculator {
private static final Map<String, Function<Double, Double>> FUNCTIONS =
Map.of(
"TAX", this::calculateTax,
"INSURANCE", this::calculateInsurance
);
public BigDecimal calculate(String formula, Map<String, BigDecimal> variables) {
// 使用Shunting-yard算法处理运算符优先级
// ...
}
}
4. 开发中的典型问题与解决方案
4.1 MyBatis一对多查询性能优化
初期采用嵌套结果映射导致查询超时:
xml复制<!-- 错误示范:N+1查询问题 -->
<resultMap id="deptWithEmployees" type="Department">
<collection property="employees" ofType="Employee" select="selectEmployeesByDept"/>
</resultMap>
优化方案:
- 使用join查询+结果集映射
- 启用二级缓存
- 大数据量时分页查询
xml复制<!-- 优化方案 -->
<resultMap id="deptWithEmployees" type="Department">
<id property="id" column="dept_id"/>
<collection property="employees" ofType="Employee">
<id property="id" column="emp_id"/>
<result property="name" column="emp_name"/>
</collection>
</resultMap>
4.2 Vue组件数据更新问题
当遇到Element UI表格数据更新不及时的情况:
javascript复制// 错误做法:直接索引修改数组
this.employeeList[index] = newData;
// 正确方案:使用Vue.set或数组替换
Vue.set(this.employeeList, index, newData);
// 或
this.employeeList = [...this.employeeList];
5. 毕业论文撰写建议
根据指导老师反馈的常见问题,特别提醒:
- 系统架构图建议使用PlantUML绘制(非截图)
- 性能测试部分需包含JMeter压测报告
- 代码展示遵循以下原则:
- 核心算法展示完整
- 工具类方法只需说明作用
- 前端组件展示props定义即可
数据库设计文档应包含:
- E-R图(标注主外键关系)
- 索引设计说明(特别是组合索引)
- 事务处理方案(如薪资计算中的事务边界)
6. 部署与扩展建议
实际部署时遇到的坑:
- Nginx配置需要特别注意:
nginx复制location /api {
proxy_pass http://localhost:8080;
proxy_set_header X-Real-IP $remote_addr;
# 必须设置以下两项解决跨域
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods *;
}
- 扩展性设计建议:
- 预留WebHook接口用于对接第三方系统
- 重要业务操作添加审计日志
- 使用Redis缓存热点数据(如部门树形结构)
这个项目最值得深入的两个方向:
- 集成Activiti实现审批流引擎
- 增加BI看板(推荐使用ECharts)
