thinkphp 5.1虽停止维护,仍适用于中小团队oa开发,关键在于业务闭环、状态可控与权限隔离;考勤用时间/ip校验自动判迟到/早退/缺卡,审批采用四步状态机,权限通过auth condition动态控制,前端用layui保障体验。

ThinkPHP 5.1 虽已停止官方维护,但因其轻量、文档清晰、扩展成熟,仍被不少中小团队用于快速搭建内部 OA 系统。开发员工考勤与审批流程,关键不在框架多新,而在业务逻辑是否闭环、数据状态是否可控、权限是否隔离。以下为真实项目中提炼出的实操要点,聚焦可落地的代码结构与设计决策。
考勤模块:打卡记录 + 状态自动判定
不依赖第三方定位 SDK,用基础 Web 表单 + 时间戳 + IP 校验实现最小可行打卡。核心是“一次打卡生成一条记录,并自动标记是否迟到/早退/缺卡”:
- 数据库表 attendance_log 包含字段:
user_id、check_date(Y-m-d)、check_time(H:i:s)、ip、status(0=正常,1=迟到,2=早退,3=缺卡) - 打卡接口(
AttendanceController@submit)中,先查当日是否已打卡:AttendanceLog::where(['user_id' => $uid, 'check_date' => date('Y-m-d')])->count(),避免重复提交 - 状态判定逻辑写在模型的
setCheckTimeAttr或服务层:
• 规定上班时间 08:30,晚于 08:45 记为迟到;
• 下班时间 17:30,早于 17:15 记为早退;
• 若当天无打卡记录且当前时间 > 17:30,则夜间定时任务补标「缺卡」
审批流程:四步驱动的状态机设计
避免用“审批中/已通过/已拒绝”简单枚举,而是按流转阶段建模,让每一步操作有明确前置条件和后置动作:
- 审批主表 approval_apply 存申请摘要(申请人、类型、标题、附件路径、当前节点)
- 审批节点表 approval_node 存每一步处理人、处理时间、意见、操作(同意/驳回/转交),支持会签或或签
- 关键约束:
• 用户只能操作「自己是当前处理人」且「状态为待处理」的单据;
• 同意后,自动查出下一节点处理人(可配置为角色、部门负责人或指定用户);
• 驳回直接结束流程,状态设为「已驳回」,不可再提交 - 在
ApprovalService中封装handle($applyId, $userId, $action, $remark)方法,统一校验+更新+通知,控制器只做参数接收
权限与数据隔离:基于 RBAC 的最小集控制
OA 不需要复杂权限系统,但必须守住两条线:谁能看到自己的考勤?谁有权审批哪类单据?
- 不重造 Auth 类,复用 ThinkPHP 自带的
Auth门面,但规则表 auth_rule 中的condition字段要活用:
• “查看本人考勤” → condition =user_id = {uid};
• “审批本部门请假单” → condition =dept_id = (SELECT dept_id FROM user WHERE id = {uid}) AND type = 'leave' - 在控制器基类
BaseController的initialize()中调用Auth::check('attendance/read', $this->uid),失败则抛出 403 - 列表接口一律加数据过滤,如考勤统计页:
AttendanceLog::where('user_id', $this->uid)->where('check_date', '>=', $start)->select(),绝不裸查全表
前端交互:用 Layui + Ajax 保体验不降级
ThinkPHP 5.1 默认视图层足够支撑 OA 前端,无需强耦合 Vue/React。重点是把异步操作做稳:
- 打卡按钮点击后立即禁用 + 加载态,防止重复提交;成功后用
layer.msg('打卡成功')提示,3 秒后跳转到今日记录页 - 审批详情页用
laytpl渲染节点流,每个节点显示头像、姓名、时间、意见;操作按钮根据当前用户身份和单据状态动态显示(如“我已处理过”则灰掉,“非当前处理人”则隐藏按钮) - 所有 Ajax 请求统一拦截响应码:
• code=200 → 正常处理;
• code=403 → 弹窗提示“无权限”,并 reload 页面;
• code=500 → 打印 message 到 console,便于排查 SQL 错误或空指针
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











