ThinkPHP人员管理系统:别急着写代码,管理先想清楚你要管什么
去年帮一家做外贸的系统小公司重构内部人员系统,老板拍板用ThinkPHP,管理理由是系统“网上教程多,招人好招”。管理这话没错,系统但真正上手才发现——框架只是管理工具,麻烦全在业务逻辑里。系统他们的管理旧系统用Excel加微信群管理,离职员工能翻到三年前的系统聊天记录找考勤,这哪是管理系统,分明是系统考古现场。
ThinkPHP的管理MVC分层确实清爽,Model层写员工表关联部门表,系统Controller层处理登录验证,管理View层用模板引擎渲染列表。但你要是真按官方文档那样把增删改查堆上去,三天就能跑通,然后呢?人事部要看的不是“张三,部门ID=3”,而是“张三,市场部,入职两年,调岗三次,今年年假剩五天”。
所以建表之前,我拉着人事经理聊了两个下午。她说最头疼的是“人走了,权限没走”——销售总监离职后,他的子账号还能登录后台看客户报价。这个问题在ThinkPHP里不难解决,写个中间件,每次请求检查用户状态和角色有效期,超过离职日期直接踢回登录页。但前提是你得在用户表里加一个`resign_date`字段,而不是只存`status`等于1还是0。
还有一次,技术部反馈说绩效评分页面加载慢。查了日志,发现是关联查询太狠——每行员工数据都要join三张表算KPI,数据量到两千人就不行了。后来改成ThinkPHP的`with`预加载,只查一次数据库,再用`map`在内存里分组。页面从4秒降到0.3秒,同事问我是不是加了Redis,我说没有,就是少查了几百次数据库。框架给的`query`类很灵活,但别迷信ORM,有时候手写一条`join`比链式调用更直接。
实际开发中最坑的反而不是技术,是需求变来变去。今天说考勤要按自然月算,明天说按发薪周期算,后天又说试用期员工单独规则。ThinkPHP的模型事件能帮上忙——在`Model::init()`里挂`beforeSave`,自动判断员工类型填充默认值。但别把所有逻辑都塞进模型,我见过有人把导出Excel的代码写在`User`模型里,那文件比《战争与和平》还长。该拆服务层就拆,比如`AttendanceService`管规则,`ExportService`管文件生成,Controller只做参数校验和调用。
安全方面,ThinkPHP自带`validate`和`filter`,但真正让人放心的是把权限做成表驱动。菜单表存URL规则,角色表绑定菜单ID,用户表再绑角色。每次请求在公共控制器里检查当前URL是否在权限列表内。这套东西写起来不复杂,但能挡住90%的“我直接改URL绕过按钮”的操作。记得给所有输出加`htmlspecialchars`,别偷懒用`{ $data|htmlspecialchars}`模板标签,XSS攻击往往从内部测试账号开始。
最后说个细节:日志。ThinkPHP默认日志写在`runtime/log`,但生产环境最好按天分文件,并且只保留30天。我见过客户服务器硬盘被日志塞爆,原因是某接口被爬虫刷了十万次,每次错误都记录完整堆栈。框架的`Log::write()`没问题,问题是你得在入口文件或中间件里限制日志级别,`error`和`warning`写入文件,`info`直接丢弃。
系统上线三个月后,人事经理跟我说,现在查员工轨迹点两下就行,不用再翻聊天记录。我没提ThinkPHP多厉害,只问她觉得哪里还能改。她说:“能不能加个生日提醒?”——瞧,业务永远在长,框架永远只是骨架。你真正要管理的,是那些不断冒出来的“生日提醒”。
