我是做PHP开发接外包的,前前后后做了不少管理系统,但家政公司订单管理系统算是比较有代表性的一类。上半年一个开家政公司的朋友找上我,说想搞一套系统,要求不高:能录订单、能派单、月底能把阿姨工资算明白。我一开始觉得这种小系统一星期就能搞定,真上手才发现,业务逻辑比代码复杂得多。
今天把这套“家政公司订单管理系统”的源码和设计思路完整分享出来,适合三类人看:一是中小家政公司的老板或运营负责人,想低成本搭建自己的业务系统;二是刚入行的PHP开发者,想找一个业务完整、能二次开发的练手项目;三是接外包的自由职业者,可以拿这套系统的架构当模板,快速改造成其他“预约+派单+结算”类项目。整套源码基于PHP+MySQL原生开发,部署到宝塔面板就能直接跑,核心功能包括订单全流程管理、客户沉淀、阿姨排班派单、工资自动结算和数据看板,完全覆盖中小家政公司日常运营的刚需。
1. 项目概述与核心痛点
1.1 为什么中小家政公司最需要一套订单管理系统
做这套系统之前,我专门陪朋友跑了两天一线业务。他在一个二线城市开了家政公司,也就是俗称的“中介+自营”模式,旗下不到20个阿姨,每天订单量在30到60单之间。当时他用的工具是Excel加微信群:客服把订单抄在表格里,群里喊一嗓子让阿姨认领,临时改时间就靠着打电话反复沟通,月底算工资要熬两个通宵。这种模式在订单量50单以内还能勉强撑住,一旦过了这个数字,问题就集中爆发。
我梳理了一下他遇到的痛点,其实非常有代表性:
- 订单状态完全靠脑袋记。客户约了明天下午三点擦玻璃,阿姨到底接没接、有没有迟到、做完没有,客服要挨个打电话问,问完再手动改Excel。
- 客户资料散落在各人微信里。哪个客户做过几次保洁、家里有没有宠物、门禁密码是多少、对哪个阿姨不满意,全部凭客服个人记忆,人一离职,客户也跟着流失。
- 排单没有章法。阿姨的技能不一样,有的专做深度保洁,有的只会擦玻璃,但派单基本靠“谁离得近谁去”,经常出现阿姨跑大半个城市服务一单、另一单在隔壁小区却没人接的情况。
- 工资结算靠手工。保洁按单算提成,月嫂按月薪算,临时工按时薪算,三种计薪方式混在一起,月底算错一次就要跟阿姨解释半天。
这些痛点单独看都不大,但叠在一起,几乎每天都要消耗管理者的精力。市面上的SaaS家政软件功能确实全,但一年授权费少则几千、多则上万,很多中小老板接受不了。免费的开源方案又普遍年久失修,界面老旧,字段跟实际业务对不上。我当时的判断是:与其买一套“大而全”的软件回来还要员工适应它的流程,不如做一套贴合自己业务的小系统。
1.2 技术选型:为什么是PHP+MySQL而不是Java或Python
技术选型是所有做系统的人最纠结的一步。我给这个项目定方案时,几乎没有犹豫就选了PHP+MySQL,理由也很实在:
- 部署门槛必须低。家政公司老板绝大多数不是技术出身,最多能按教程在宝塔面板上点几下。PHP的LNMP环境一键就能搭起来,虚拟主机也能跑,几乎不存在环境障碍。如果选Java或Python,光是装JDK、配环境变量、装依赖就能劝退一半用户。
- 开发效率足够快。这套系统从立项到能用的版本,我写了大概十天。PHP不需要编译,改完代码刷新就能生效,配合原生SQL写业务逻辑非常直接。对于一个日订单量几十上百的项目,完全不需要引入复杂的微服务架构。
- 持有成本几乎为零。全套技术栈都是开源的,PHP、MySQL、前端LayUI框架没有授权费用,部署在自己服务器上,除了服务器租金没有任何额外支出。
- 后续维护不挑人。PHP程序员在市场上多得像米一样,将来公司想加功能,随便找一个PHP开发就能接手。要是用了冷门技术栈,源码烂在自己手里没人看得懂才是最尴尬的。
有朋友可能会问,用Java做是不是更“正规”?如果公司规模很大,需要多端实时同步、复杂权限体系、上万级并发,那确实应该上Java或Go。但中小家政公司一天就几十上百个订单,MySQL单表在千万级数据量以下性能完全没问题。技术选型最忌讳的就是“盲目追重”,杀鸡用牛刀只会给自己增加运维负担。
1.3 这套系统具体能解决什么
从使用端来看,这套系统落地之后,朋友的业务发生了几个立竿见影的变化:
- 订单状态全流程可视化。从客户打电话进来创建订单,到派单、接单、服务中、完成、回访,每一步都在系统里有明确状态。客服再也不用靠微信聊天记录回忆订单进度。
- 派单效率大幅提升。系统根据阿姨的服务技能标签和当天已接单量自动推荐合适的人选,坐席一键派单,阿姨在系统里就能看到属于自己的新订单,不用在群里翻聊天记录。
- 工资从半天缩短到一分钟。月底点击“生成工资单”,系统自动汇总当月已完成的订单提成、底薪和罚款,生成工资表。朋友说这是他最满意的一个功能,省下的时间够他多跑两趟业务。
- 客户资产沉淀下来。每个客户的服务记录、偏好、地址、备注全部存在系统里,即使客服换人,新客服打开客户列表就能完整了解历史,不会因为人员流动丢掉客户。
2. 系统架构与数据库设计
2.1 整体架构和目录结构
系统采用经典的B/S架构,浏览器直接访问,服务端渲染为主。前端用的是LayUI框架加jQuery,图表部分接了Echarts;后端是PHP原生代码,按简单的MVC分层写的,没有引入重量级框架,这样做的目的是方便二次开发——懂一点PHP的人都能看懂,不用先学一套框架规范。
接口层面我预留了JSON格式的REST风格API,地址在api/目录下,以后想接微信小程序或者APP,直接复用这一层接口就行,不需要把后台的HTML页面逻辑硬塞给移动端。
目录结构是这样的:
├── admin/ # 后台管理模块 │ ├── controller/ # 控制器层,接收请求、调用模型 │ ├── model/ # 数据模型层,封装SQL操作 │ ├── view/ # 视图模板层,HTML页面 │ └── common/ # 公共函数、配置文件 ├── api/ # API接口模块,输出JSON ├── static/ # 静态资源 CSS/JS/图片 ├── upload/ # 用户上传文件目录 ├── install/ # 安装向导,自动建表 └── index.php # 入口文件我特意把install/目录做成一个可视化安装向导,用户上传源码后访问一次,系统自动创建数据库表并写入初始配置。这样即使不懂技术的使用者也能独立完成部署,不需要手动去执行SQL文件。
2.2 核心数据表逐张拆解
数据库我一共设计了9张表,基本覆盖了家政公司日常经营的所有核心数据。下面一张一张说,这些表的结构直接决定了业务逻辑怎么写。
用户表(user)
存系统登录账号,字段包括用户名、密码、姓名、手机号、角色、状态。角色分为三类:管理员、坐席、服务人员。密码用加密方式存储,我开发时用的是MD5加盐,生产环境建议换成PHP的password_hash()函数,更安全。
客户表(customer)
客户是家政公司最重要的资产,所以这张表字段比较细。除了姓名、电话、地址,我还加了小区名称、经纬度、来源渠道、备注四个字段。小区名称配合经纬度是为了将来做“就近派单”,来源渠道用来统计获客效果,备注则记录“家有两猫”“门禁密码后六位”这样的特殊信息。这些细节看起来不起眼,实际用起来非常方便。
服务项目表(service_item)
家政公司卖的其实是具体的服务产品,而不是笼统的“家政服务”。这张表定义SKU:服务名称、标准单价、标准时长、计价单位、提成方式、提成比例。比如“日常保洁”单价120元,按次计价,提成方式为按单提成40%;“月嫂”按月计价,提成可能是固定的。把提成规则挂在服务项目上,而不是统一用一个比例,这样才能灵活应对不同业务的利润空间。
服务人员表(staff)
管理阿姨和师傅的基本信息:姓名、电话、身份证号、服务技能标签、工作状态、入职日期、底薪、客户评分。技能标签我用JSON格式存储,比如["日常保洁","擦玻璃"],这样在派单页面就能用标签快速筛选出能接对应服务的人。工作状态分为在线、休假、离职,排单时自动过滤掉不可用人员。
订单表(orders)
这是系统的核心表。订单编号、客户ID、服务项目ID、服务人员ID、订单状态、预约服务时间、服务地址、实际金额、提成金额、备注、创建时间、完成时间。订单状态我定义了一个流转状态机:待接单、待服务、服务中、已完成、已取消、待售后。每一步的流转在代码里都做了校验,不允许从“已完成”直接跳回“待接单”这种非法操作,避免数据错乱。
工资结算表(salary)
月底结算就靠这张表:服务人员ID、结算周期、底薪、提成总额、奖金、罚款、实发工资、是否已结算。系统按月份汇总订单表中的提成金额,加底薪、扣罚款,生成一条工资记录。这里要特别注意,结算过的记录要锁定,不能因为后续改单导致历史工资被篡改。
售后回访表(after_sale)
订单完成后自动生成一条待回访记录,客服跟进后填写满意度、回访内容、回访时间、回访人。家政行业的复购率很大程度上取决于售后体验,有了这张表,管理者可以直观看到每个客户的满意度趋势,也能找出评分低的阿姨进行针对性培训。
操作日志表(operate_log)
记录谁在什么时间做了什么操作,包括操作人、动作类型、关联订单ID、操作内容、IP地址、创建时间。当初第一版系统没有这张表,朋友跑了几天后说“系统没问题”,结果一个客户投诉阿姨放鸽子,两边各执一词,谁改的订单都查不到。加上操作日志后,所有关键操作都有据可查,管理纠纷时底气足很多。
系统配置表(config)
键值对结构,存放公司名称、客服电话、佣金默认比例、收款码图片路径等全局配置。把这类数据从代码里抽出来放到数据库,以后改配置不用动代码,直接在系统设置页面操作就行。
2.3 数据库设计踩过的坑
数据库设计是整个系统里我最想分享经验的部分,因为真的踩了不止一个坑。
第一个坑是差点用FLOAT存金额。开始时图省事,金额字段全部用FLOAT,跑了一段时间发现工资对不上——FLOAT在累加时会丢失精度,一毛钱可能变成九分钱,阿姨的眼睛可是雪亮的。后来全部改成DECIMAL(10,2),问题彻底解决。记住一句话:凡是涉及钱的字段,一律用定点数,不要用浮点数。
第二个坑是订单号用了自增ID。第一版订单表主键直接当订单号显示,后来发现两个问题:一是客户能根据订单号推断出公司的业务量,二是多表联查时自增ID语义不清晰。我改成JD+年月日+三位随机数的格式,比如JD20250101001,既有辨识度,也避免订单号暴露内部数据。
第三个坑是忘了设计软删除。一开始删除客户直接DELETE,后来发现删除操作会把历史订单的关联关系一起搞丢。现在所有关键表都加了status字段,删除只是标记状态,数据仍然保留,报表统计和追溯都是完整的。
3. 核心功能模块的实现细节
3.1 登录与三层权限控制
系统的登录模块没有做什么花哨的东西,就是最经典的Session会话控制。登录成功之后把用户ID和角色写进SESSION,然后写一个权限校验的中间件函数,在每个控制器开头调用。
// 权限校验中间件 function checkAuth($allowedRoles) { session_start(); if (!isset($_SESSION['user_id'])) { header('Location: /login.php'); exit; } if (!in_array($_SESSION['role'], $allowedRoles)) { die('无权访问该页面'); } }调用方式很直接:在订单管理控制器里写checkAuth([1,2]),就表示只有管理员和坐席能访问这个页面;在工资结算控制器里写checkAuth([1]),就只有管理员能进去。阿姨登录后只能看到自己的订单列表和工资明细,连客户电话都看不了,避免阿姨绕过公司直接跟客户私单。
3.2 订单全生命周期管理
订单是这套系统的心脏。我在设计订单状态流转时,专门画了一张状态图(代码里用常量定义):
- 1 = 待接单(客服刚录入,还没有派给阿姨)
- 2 = 待服务(已经派单,阿姨确认接单)
- 3 = 服务中(阿姨到达客户家,点击开始服务)
- 4 = 已完成(服务结束,系统自动算提成)
- 5 = 已取消(客户或公司主动取消)
- 6 = 待售后(服务完成后自动进入回访流程)
每次状态变更都统一走orderStatusChange()函数,这个函数会做三件事:校验当前状态是否可以过渡到目标状态;更新订单表状态字段;把操作记录写入操作日志。以“派单”为例:
// 派单动作 public function assignOrder($orderId, $staffId) { $order = $this->find($orderId); if ($order['order_status'] != 1) { throw new Exception('当前状态不能派单'); } // 绑定阿姨,状态改为待服务 $this->update($orderId, [ 'staff_id' => $staffId, 'order_status' => 2 ]); // 写操作日志 $this->log($orderId, '派单', "指派给 {$staffId}"); }这里的状态校验非常关键。我一开始没有做严格校验,结果测试阶段自己手滑把一条“已完成”的订单误改成“待接单”,搞得统计数字乱了半天。后来把所有非法状态跳转全堵死,代码里还加了提示:“当前状态不支持该操作”。
3.3 派单与排班推荐逻辑
派单是家政公司管理者每天最头疼的事。我的设计思路不是做全自动派单,而是“人工决策为主,系统推荐为辅”。坐席在派单页点击“推荐阿姨”后,系统按四步过滤:
- 按订单的服务项目匹配阿姨的
skill_tags技能标签 - 过滤掉工作状态不是“在线”的阿姨
- 按当天已完成和待服务的订单数量升序排列,避免某些阿姨被过度派单
- 如果客户地址录入了经纬度,再按距离由近到远排序
这四步过滤完,页面上会展示一个推荐列表,每行显示阿姨名字、技能标签、当天单量、距离,坐席可以一键指派。同时我保留了一个“手动指定”入口,因为真实业务里客户经常会点名要某个阿姨,这种需求系统不应当阻止。
推荐算法不复杂,但胜在实用。朋友用了之后跟我说,以前一早上要花两个小时打电话协调阿姨,现在十分钟就排完了,因为系统把“谁有空、谁能干、谁最近”一次性算清楚了。
3.4 工资自动结算模块
工资模块算是这套系统里技术含量不高但业务价值最大的功能。家政行业工资结构复杂:保洁是按单提成,保姆是固定月薪,临时开荒是按时薪算,还有各种罚款和奖金。如果纯靠Excel,月底真的能算到怀疑人生。
我的解决方案是给每个服务项目设置独立的提成规则,工资计算时按订单逐条汇总:
SELECT staff_id, SUM(commission_amount) AS total_commission FROM orders WHERE order_status = 4 AND finish_time BETWEEN '2025-01-01' AND '2025-01-31 23:59:59' GROUP BY staff_id;这条SQL语音把当月所有已完成订单的提成按阿姨汇总。后台再把底薪、奖金、罚款加加减减,生成工资记录。这里有一个细节:提成金额不是订单生成时就算死的,而是在订单状态变成“已完成”的那一刻计算并写入订单表。这样做的好处是,如果客户临时增加服务时长导致实际金额变化,提成也能跟着变。
工资生成之后我加了一个“锁定”按钮,一旦确认结算,工资单就不能再被修改。这样既防止人为篡改,也给财务审计留了底。
3.5 数据看板与统计
系统首页是一个数据看板,用Echarts画了四张图:订单趋势折线图、阿姨产值柱状图、客户来源分布饼图、订单状态漏斗图。顶部还有四个核心指标卡:今日订单数、今日营收、待派单数量、本周回访完成率。
这个看板花的时间不多,但朋友反馈说,以前他都是凭感觉判断公司经营状况,现在每天早上看一眼就知道昨天接了多少单、哪个阿姨工作量最饱和、哪个获客渠道带来的客户最多。有一段时间他发现某个渠道的客户转化率特别低,一查发现是客服录入渠道时选错了,调整之后数据才准确。
4. 安装部署实战
4.1 环境要求
部署这套系统,最简单的方案是宝塔面板。环境要求如下:
- PHP 7.0+,推荐7.4或8.0版本
- MySQL 5.7+,推荐MySQL 8.0
- Nginx或Apache均可,宝塔默认Nginx
- 服务器内存1G以上足够(日订单几百单完全没问题)
4.2 宝塔面板部署完整步骤
第一步,把源码压缩包上传到服务器网站根目录,解压。我用的是/www/wwwroot/jiazheng这个路径,名称可以自己定。
第二步,在宝塔面板创建一个MySQL数据库,记住数据库名、用户名、密码。然后用phpMyAdmin导入源码install/目录下的database.sql文件,这个文件会自动创建全部9张表并插入初始数据。
第三步,修改admin/common/config.php里的数据库连接信息,把数据库名、端口、用户名、密码换成你自己的。
return [ 'db_host' => '127.0.0.1', 'db_port' => 3306, 'db_name' => 'jiazheng_db', 'db_user' => 'jiazheng_admin', 'db_pass' => '你的密码', 'db_charset' => 'utf8mb4' ];第四步,配置伪静态。如果用的Nginx,在站点设置里加上ThinkPHP风格的伪静态规则,保证URL能正常跳转。Apache一般不用额外配置。
第五步,访问http://你的域名/index.php,进入安装向导,按提示完成安装。安装完成后,系统会引导你删除install/目录,防止脚本被恶意重放。
默认后台登录地址是http://你的域名/admin/,初始账号admin,密码123456。登录后第一件事就是修改密码,并把管理员手机号绑定上。
4.3 部署后的检查清单
部署完成后不要急着录数据,先把这几项检查一遍:
- 数据库字符集是不是
utf8mb4。如果建库时不小心选了utf8,录入客户备注里的emoji表情会变成乱码。 upload/目录权限是否可写。如果上传图片提示失败,多半是目录权限不对,chmod 755 upload/即可。- 后台所有菜单能否正常点击。重点测试订单状态从“待接单”流转到“已完成”整条链路,看操作日志有没有记录。
- 修改
config.php里的默认密钥,改成一段随机的字符串,提高Session安全性。
5. 常见问题排查与避坑指南
5.1 典型问题速查表
我整理了一份部署和使用过程中最常遇到的几个问题,方便大家对照排查:
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 安装时数据库连接失败 | 数据库密码错误或账号没有授权 | 检查config.php配置,在宝塔里给数据库用户授权所有权限 |
| 页面乱码 | 字符集不是utf8mb4 | 统一改数据库、数据表、PHP连接三个层面的字符集 |
| 登录后跳回登录页 | SESSION没有正常开启 | 检查PHP的session配置,确认站点根目录可写 |
| 订单状态无法流转 | 状态机校验拦截了非法操作 | 看操作日志确认当前状态,走正确的流转路径 |
| 工资计算结果不对 | 服务项目的提成比例没有配置对 | 检查service_item表的commission_rate和commission_type字段 |
| 图片上传失败 | upload目录没有写权限 | 给upload目录设置755权限,PHP用户组要可写 |
| 页面报500错误 | PHP版本不兼容或扩展缺失 | 切换PHP版本到7.4/8.0,打开PHP错误日志定位 |
5.2 几个容易忽略的细节
有几个细节是常规文档不会写的,但实际运营中非常重要:
第一,一定要把操作日志表的数据定期备份。家政公司的“客诉纠纷”很多时候靠日志还原事实,日志丢失等于没有证据。我建议宝塔面板里设置每天自动备份数据库,保存最近30天。
第二,客户备注功能要规范使用。有的坐席会把“客户脾气差”“客户喜欢砍价”这种主观评价写进去,容易引发矛盾。我在系统里加了一个提示:“备注请填写客观信息,如门禁密码、宠物情况、服务偏好”。主观评价应该走回访表,而不是写给全员看。
第三,阿姨状态要及时维护。如果阿姨请假了但系统里还显示“在线”,派单系统会把她推荐出去,导致客户下单后没人接。最好指定一个坐席每天早晚各检查一次阿姨的工作状态。
6. 二次开发与扩展方向
6.1 从家政系统改造成其他预约型业务
这套系统最有价值的不是那几张表,而是“预约+派单+结算”的业务模型。把服务项目表、服务人员表、订单表改一改字段,就能快速改造成维修预约系统、宠物寄养系统、车辆保养预约系统、上门安装服务系统。我接外包的时候,经常用这套架构当底座,改个皮肤和字段就能交付一个新项目,开发成本能省一半。
更换行业的改造重点不在代码,而在业务规则:
- 维修行业要加“故障描述”“配件成本”字段
- 宠物寄养要加“宠物类型”“体重”“疫苗接种信息”
- 车辆保养要加“车辆型号”“保养里程”“配件清单”
这些都是在订单表、客户表上扩展字段的事,表结构不变,核心逻辑不动。
6.2 推荐的功能增强路径
如果你打算拿这套源码继续扩展,我建议按以下顺序来,性价比最高:
- 接入消息通知。在订单状态变化时调用阿里云短信接口或企业微信机器人通知相关角色,让阿姨不用一直盯着系统。这一步是现代家政服务体验的关键。
- 对接微信小程序。系统
api/目录的接口已经就绪,小程序端只需实现登录、查看订单、接单、开始/完成服务四个页面,就能让阿姨完全脱离PC端。 - 增加地图调度。派单页接入高德地图JS API,在地图上直接显示客户点和正在服务中的阿姨位置,实现“就近派单”。配合客户表的经纬度字段,这步改造基本是顺水推舟。
- 上线数据导出。增加“导出Excel”按钮,把订单表、工资表一键导出,方便财务对账和老板做汇报。
- 加一层缓存。当订单量增长到日单量几百以后,看板查询会变慢,可以用Redis缓存热门统计接口,或者给订单表按月分区。
还有一点,源码里的安装向导是通用的,如果别人拿这套源码来部署,建议把安装后的默认管理员账号改成随机生成的密码,并发到对方手机上,避免默认密码被人利用。这是个很小的动作,但能省掉很多安全上的麻烦。
我实际开发完这套系统之后最大的感受是:小系统的难点从来不在技术,而在于把业务逻辑想透。你花三天梳理业务流程,代码可能一天就写完了;反过来,业务没想清楚就急着写代码,写完也要推翻重来。这套源码我打包好了,需要的朋友在文章下留言,我看到后会发给你。源码是免费的,但希望你在使用的过程中,能把踩到的坑和改出来的经验也分享出来,让这套系统越来越完善。