1. 项目回顾
1.1 开发历程回顾
从零开始搭建智能打卡系统,历时一个多月的开发,现在终于可以坐下来回顾这段旅程。整个过程就像登山,有艰难的上坡,也有收获的喜悦。
时间线:
第1周:需求分析与技术选型
第2-3周:后端基础架构搭建
第4周:数据库设计与实现
第5周:前端界面开发
第6周:人脸识别集成
第7周:测试与优化
1.2 已完成功能
核心功能模块
✅ 用户认证模块
邮箱验证码注册
JWT 令牌认证
密码加密存储(BCrypt)
角色权限管理(ADMIN/MANAGER/EMPLOYEE)
✅ 考勤打卡模块
弹性工作制支持(08:00-10:00签到)
人脸识别打卡(阿里云集成)
迟到早退自动判定
工作时长自动计算
加班时长统计
✅ 请假管理模块
三种请假类型(事假、病假、年假)
部门经理审批流程
请假记录查询
状态管理(待审批/已批准/已拒绝)
✅ 补卡申请模块
签到/签退补卡申请
部门经理审批
申请记录管理
状态跟踪
✅ 数据统计模块
月度考勤统计
数据可视化图表(ECharts)
出勤率计算
加班分析
✅ 用户管理模块
个人信息管理
人脸照片上传(阿里云OSS)
密码修改
部门管理
2. 技术架构总结
2.1 后端技术栈
框架: Spring Boot 4.0.0
语言: Java 17
数据库: MySQL 8.0
ORM: Spring Data JPA (Jakarta Persistence)
安全: JWT + Spring Security Crypto
邮件: Spring Boot Mail (163邮箱)
人脸识别: 阿里云人脸识别 SDK
对象存储: 阿里云 OSS
构建工具: Maven
2.2 前端技术栈
框架: Vue.js 3.5.25
UI组件: Element Plus 2.12.0
构建工具: Vite 7.2.7
路由: Vue Router 4.x
图表: ECharts 6.0.0
日期处理: dayjs 1.11.19
HTTP客户端: Fetch API
2.3 数据库设计
核心表结构(6张表)
-- 1. 用户表 (users)
CREATE TABLE users (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(30) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
real_name VARCHAR(50),
department_id BIGINT,
role_id BIGINT DEFAULT 3,
status TINYINT DEFAULT 1,
face_image_url VARCHAR(500),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 2. 角色表 (roles)
CREATE TABLE roles (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL UNIQUE,
description VARCHAR(200)
);
-- 3. 部门表 (departments)
CREATE TABLE departments (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL UNIQUE,
description VARCHAR(200)
);
-- 4. 考勤记录表 (attendance_records)
CREATE TABLE attendance_records (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT NOT NULL,
attendance_date DATE NOT NULL,
check_in_time TIMESTAMP NULL,
check_out_time TIMESTAMP NULL,
expected_check_out_time TIMESTAMP NULL,
check_in_ip VARCHAR(50),
check_out_ip VARCHAR(50),
work_hours DECIMAL(5,1),
overtime_hours DECIMAL(5,1),
status TINYINT DEFAULT 1,
is_late BOOLEAN DEFAULT FALSE,
is_early_leave BOOLEAN DEFAULT FALSE,
late_minutes INT DEFAULT 0,
early_leave_minutes INT DEFAULT 0,
remark VARCHAR(500),
is_supplement BOOLEAN DEFAULT FALSE,
supplement_status TINYINT DEFAULT 0,
supplement_reason VARCHAR(500),
approver_id BIGINT,
approval_time TIMESTAMP NULL,
approval_remark VARCHAR(500),
check_in_image_url VARCHAR(500),
check_out_image_url VARCHAR(500),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (approver_id) REFERENCES users(id)
);
-- 5. 请假记录表 (leave_records)
CREATE TABLE leave_records (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT NOT NULL,
leave_type VARCHAR(20) NOT NULL,
start_date DATE NOT NULL,
end_date DATE NOT NULL,
leave_days DECIMAL(5,1) NOT NULL,
reason VARCHAR(500) NOT NULL,
status TINYINT DEFAULT 0,
approver_id BIGINT,
approval_time TIMESTAMP NULL,
approval_remark VARCHAR(500),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (approver_id) REFERENCES users(id)
);
-- 6. 补卡申请表 (supplement_records)
CREATE TABLE supplement_records (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT NOT NULL,
target_date DATE NOT NULL,
check_type TINYINT NOT NULL,
check_time TIME NOT NULL,
reason VARCHAR(500) NOT NULL,
status TINYINT DEFAULT 0,
approver_id BIGINT,
approval_time TIMESTAMP NULL,
approval_remark VARCHAR(500),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (approver_id) REFERENCES users(id)
);
3. 开发经验与教训
3.1 成功经验
技术选型的正确性
Spring Boot 4.0 + Vue.js 3.x 的组合非常合适:
前后端分离架构清晰
开发效率高
生态完善,问题容易找到解决方案
社区活跃,学习资源丰富
阿里云服务的集成体验良好:
文档详细,API设计合理
SDK 完善,集成简单
服务稳定,性能可靠
成本可控,适合中小项目
架构设计的合理性
分层架构让代码更清晰:
Controller 层:处理 HTTP 请求和响应
Service 层:业务逻辑实现
Repository 层:数据访问
Entity 层:数据模型定义
DTO 层:数据传输对象
统一的异常处理:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
public Map<String, Object> handleRuntimeException(RuntimeException e) {
return Map.of("ok", false, "code", 400, "message", e.getMessage());
}
}
统一的响应格式:
{
"ok": true,
"code": 200,
"data": {},
"message": "成功"
}
3.2 遇到的挑战与解决方案
跨域问题
问题: 前端开发服务器(localhost:3000)访问后端API(localhost:8080)时出现跨域错误。
解决方案:
@Configuration
public class WebConfig {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowCredentials(true);
corsConfiguration.setAllowedOrigins(Arrays.asList(
"http://127.0.0.1:5502",
"http://localhost:3000",
"http://localhost:8081"
));
corsConfiguration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
corsConfiguration.setAllowedHeaders(Arrays.asList("*"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
}
人脸识别性能问题
问题: 人脸识别调用耗时较长,影响用户体验。
解决方案:
异步处理人脸识别
添加加载状态提示
优化图片大小(限制为 2MB)
客户端图片预处理(压缩、格式转换)
前端状态管理
问题: 多个组件需要共享用户状态、考勤状态等。
解决方案:
使用 Vue 3 的组合式 API 创建可复用状态
合理使用 localStorage 存储 token 等持久化数据
通过事件总线(Event Bus)处理简单的跨组件通信
// 使用组合式函数管理用户状态
export function useUserStore() {
const userInfo = ref({})
const isLoggedIn = computed(() => !!localStorage.getItem('token'))
const loadUserInfo = async () => {
try {
const response = await api.getUserInfo()
userInfo.value = response.data
} catch (error) {
console.error('加载用户信息失败:', error)
}
}
const logout = () => {
localStorage.removeItem('token')
localStorage.removeItem('userRole')
userInfo.value = {}
}
return {
userInfo,
isLoggedIn,
loadUserInfo,
logout
}
}
4. 项目成果展示
4.1 系统界面截图
登录注册页面

简洁的登录注册界面,支持邮箱验证码注册
仪表板页面

功能丰富的仪表板,展示今日考勤状态、月度统计和最近记录
人脸识别打卡

人脸识别打卡界面,支持签到和签退
考勤记录页面

数据可视化图表,清晰展示考勤趋势和分布
请假审批页面

部门经理审批界面,支持批量操作
4.2 性能指标
响应时间
页面加载时间:< 2秒
API 平均响应时间:< 200ms
人脸识别耗时:< 3秒
图表渲染时间:< 1秒
并发能力
支持 100+ 用户同时在线
支持 50+ 用户同时打卡
数据库连接池:20个连接
可用性
服务可用性:99.9%
数据一致性:保证
错误率:< 0.1%
5. 项目价值与意义
5.1 技术价值
全栈开发实践: 完整的前后端分离项目开发经验
第三方服务集成: 阿里云人脸识别、OSS 存储集成经验
现代技术栈: Spring Boot 4.0、Vue.js 3.x、Vite 等现代技术应用
架构设计能力: 从零设计系统架构的能力
5.2 业务价值
解决实际问题: 企业考勤管理的数字化解决方案
提升效率: 人脸识别打卡比传统打卡方式效率提升 50%
数据分析: 为管理层提供数据支持,优化人力资源配置
移动办公: 支持远程打卡,适应现代办公模式
5.3 学习价值
完整项目经验: 从需求分析到部署上线的完整流程
问题解决能力: 在开发过程中解决各种技术问题的能力
代码规范: 遵循企业级代码规范和最佳实践
文档能力: 完整的项目文档和技术文档编写能力
6. 未来规划与改进
6.1 短期改进计划(1-3个月)
Redis 缓存集成
现状: 使用内存缓存,重启后数据丢失
改进: 集成 Redis,实现持久化缓存
收益: 提升性能,支持分布式部署
// 计划实现的 Redis 配置
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
}
Excel 报表导出
现状: 只能在线查看统计数据
改进: 支持 Excel 格式报表导出
收益: 方便数据分析和归档
// 计划实现的 Excel 导出功能
@GetMapping("/export-excel")
public void exportAttendanceExcel(
@RequestParam String month,
HttpServletResponse response) {
// 设置响应头
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition",
"attachment;filename=attendance_" + month + ".xlsx");
// 创建 Excel 文件
try (Workbook workbook = new XSSFWorkbook()) {
Sheet sheet = workbook.createSheet("考勤记录");
// 填充数据...
workbook.write(response.getOutputStream());
} catch (Exception e) {
throw new RuntimeException("导出Excel失败", e);
}
}
移动端适配
现状: 主要在桌面端使用
改进: 优化移动端体验,支持 PWA
收益: 方便手机端打卡和查询
/* 计划实现的移动端优化 */
@media (max-width: 768px) {
.attendance-buttons {
flex-direction: column;
}
.stat-cards {
grid-template-columns: repeat(2, 1fr);
}
.chart-container {
height: 250px;
}
}
6.2 中期规划(3-6个月)
微服务架构改造
现状: 单体应用,所有功能在一个服务中
改进: 拆分为微服务(用户服务、考勤服务、审批服务等)
收益: 更好的可扩展性和可维护性
# 计划的服务拆分
services:
- auth-service: 认证授权
- user-service: 用户管理
- attendance-service: 考勤管理
- leave-service: 请假管理
- notification-service: 通知服务
- gateway-service: API网关
实时通知系统
现状: 无实时通知功能
改进: 集成 WebSocket,实现实时通知
收益: 及时通知审批结果、打卡提醒等
// 计划实现的 WebSocket 配置
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").setAllowedOriginPatterns("*").withSockJS();
}
}
多租户支持
现状: 单企业使用
改进: 支持多租户(SaaS 模式)
收益: 支持多个企业使用同一套系统
// 计划实现的多租户架构
@Entity
@Table(name = "attendance_records")
@FilterDef(name = "tenantFilter", parameters = @ParamDef(name = "tenantId", type = Long.class))
@Filter(name = "tenantFilter", condition = "tenant_id = :tenantId")
public class AttendanceRecord {
@Column(name = "tenant_id")
private Long tenantId;
// 其他字段...
}
6.3 长期愿景(6-12个月)
AI 智能分析
现状: 基础的数据统计
改进: 集成机器学习,实现智能分析
收益: 预测员工离职风险、优化排班等
# 计划实现的 AI 分析(Python 服务)
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
def predict_attendance_trend(attendance_data):
"""预测考勤趋势"""
df = pd.DataFrame(attendance_data)
# 特征工程
# 模型训练
# 趋势预测
return prediction_results
生物识别扩展
现状: 仅支持人脸识别
改进: 支持指纹识别、声纹识别等
收益: 更安全、更多样的认证方式
国际化支持
现状: 仅支持中文
改进: 支持多语言(英语、日语等)
收益: 支持跨国企业使用
// 计划实现的国际化
import { createI18n } from 'vue-i18n'
const messages = {
en: {
login: 'Login',
register: 'Register',
dashboard: 'Dashboard'
},
zh: {
login: '登录',
register: '注册',
dashboard: '仪表板'
},
ja: {
login: 'ログイン',
register: '登録',
dashboard: 'ダッシュボード'
}
}
const i18n = createI18n({
locale: 'zh',
messages
})
7. 开源计划
7.1 开源准备
代码整理:
清理敏感信息(API密钥、数据库密码等)
完善代码注释
编写详细的 README
添加开源协议(MIT License)
文档编写:
安装部署文档
API 接口文档
开发指南
贡献指南
7.2 社区建设
计划开展:
在 GitHub 上开源项目
编写系列技术文章(已开始)
录制教学视频
建立用户交流群
接受社区贡献
8. 个人成长与感悟
8.1 技术成长
全栈能力提升: 从前端到后端,从数据库到部署的完整能力
架构设计能力: 从零设计一个完整系统的能力
问题解决能力: 在开发过程中解决各种技术问题的能力
新技术掌握: Spring Boot 4.0、Vue.js 3.x、阿里云服务等
8.2 软技能提升
项目管理能力: 从需求分析到项目上线的完整流程管理
时间管理能力: 合理安排开发时间,保证项目进度
沟通表达能力: 通过博客文章分享技术经验
学习能力: 快速学习新技术并应用到项目中
8.3 人生感悟
技术如登山: 过程艰辛,但登顶后的风景很美
持续学习: 技术更新很快,必须保持学习的心态
实践出真知: 只有动手实践,才能真正掌握技术
分享即成长: 通过分享,不仅帮助他人,也加深自己的理解
9. 给读者的建议
9.1 给初学者
不要害怕开始: 每个项目都是从第一行代码开始的
从简单做起: 先实现核心功能,再逐步完善
多动手实践: 看十遍不如做一遍
善用搜索引擎: 大部分问题都能在网上找到答案
加入社区: 和其他开发者交流,能学到很多
9.2 给有经验的开发者
保持好奇心: 对新技术的探索永不止步
注重代码质量: 写出可维护的代码比快速完成更重要
分享经验: 通过博客、演讲等方式分享你的经验
关注业务价值: 技术最终要为业务服务
平衡工作与生活: 健康的身心是持续发展的基础
10. 结语
智能打卡系统的开发之旅到此告一段落,但这只是一个新的开始。技术之路,永无止境。
从零开始搭建一个完整的项目,就像养育一个孩子。看着它从无到有,从简单到复杂,从粗糙到精致,这种成就感是难以言表的。
在这个过程中,我不仅学到了技术,更学到了坚持、耐心和解决问题的智慧。每一个 bug 的修复,每一个功能的完成,都是成长的一步。
感谢这个项目,让我有机会将所学知识付诸实践;
感谢遇到的每一个问题,让我在解决中成长;
感谢坚持下来的自己,没有在半途放弃。
技术如人生,都是在不断学习和改进中前进。希望我的经验能对正在阅读的你有所帮助,也希望你能在技术的道路上找到属于自己的风景。
系列文章目录:
项目地址: GitHub - 智能打卡系统(即将开源)
联系方式:
博客:https://www.sailtrack.cn
GitHub:https://github.com/yourusername
邮箱:tracksail@example.com
路漫漫其修远兮,吾将上下而求索。与所有在技术道路上奋斗的朋友共勉。
默认评论
Halo系统提供的评论