1. 项目背景与核心需求
家政服务行业近年来呈现爆发式增长态势,传统的电话预约、门店登记等方式已无法满足现代家庭的服务需求。这个基于Java技术栈的家政服务系统,正是为解决以下行业痛点而设计:
- 服务供需匹配低效:客户难以快速找到合适的服务人员,服务方也缺乏稳定的客源渠道
- 管理流程混乱:手工记录服务订单、纸质合同管理容易出错且难以追溯
- 支付结算不透明:现金交易缺乏保障,纠纷处理无凭据
- 评价体系缺失:服务质量缺乏量化标准,用户选择缺乏参考依据
系统采用B/S架构设计,主要包含三大角色模块:
- 客户端:服务浏览、预约、支付、评价功能
- 服务人员端:订单管理、服务记录、收入统计功能
- 管理后台:人员审核、服务品类管理、订单监控、数据统计功能
提示:系统设计时特别考虑了家政服务的特殊性——高频次、强地域性、服务非标准化等特点,在订单状态流转和评价机制上做了针对性设计。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术选型与架构设计
2.1 技术栈组合解析
后端核心:
- Spring Boot 2.7.x:快速构建微服务架构,内置Tomcat简化部署
- MyBatis-Plus 3.5.x:增强型ORM框架,减少90%的常规SQL编写
- MySQL 8.0:采用InnoDB集群方案,确保事务一致性
前端方案:
- JSP 2.3:传统动态页面技术,适合快速开发管理后台
- Layui 2.6:轻量级前端UI框架,提供丰富的表单和表格组件
- jQuery 3.6:处理DOM操作和AJAX请求
特色技术点:
- 分布式ID生成:采用雪花算法避免MySQL自增ID的暴露风险
- 服务地域化处理:基于Geohash实现3公里内的服务人员智能推荐
- 支付沙箱环境:集成支付宝沙箱接口用于开发测试
2.2 系统架构图
code复制客户端浏览器 ←HTTP→ Nginx ←→ Spring Boot应用层
↑
↓
MySQL集群(主从复制)
↑
↓
Redis缓存集群
关键设计决策:
- 放弃Thymeleaf选用JSP:因管理后台需要大量服务端渲染的复杂表格
- 采用混合认证方案:
- 管理后台:Session-Based认证
- 移动端API:JWT无状态认证
- 数据库分表策略:
- 订单表按月份水平分表
- 用户信息垂直分表(基础信息+扩展信息)
3. 核心功能实现细节
3.1 服务预约流程实现
java复制// 订单状态机设计示例
public enum OrderStatus {
PENDING_PAYMENT(1, "待支付"),
WAITING_CONFIRM(2, "待确认"),
SERVICE_IN_PROGRESS(3, "服务中"),
COMPLETED(4, "已完成"),
CANCELLED(5, "已取消");
// 状态流转校验逻辑
public static boolean canChangeTo(OrderStatus from, OrderStatus to) {
switch (from) {
case PENDING_PAYMENT:
return to == WAITING_CONFIRM || to == CANCELLED;
// 其他状态转换规则...
}
}
}
关键业务表设计:
| 表名 | 关键字段 | 索引设计 |
|---|---|---|
| t_service | id, category_id, title, price, duration | category_id索引 |
| t_order | order_no, user_id, worker_id, status | 联合索引(user_id, status) |
| t_schedule | worker_id, service_date, time_slots | 唯一索引(worker_id, service_date) |
3.2 地域化服务匹配算法
sql复制-- 基于Geohash的附近服务人员查询
SELECT * FROM t_worker
WHERE geohash LIKE 'wx4g0%' -- 前5位匹配约3公里范围
AND skills LIKE '%保洁%'
AND status = 1
ORDER BY rating DESC
LIMIT 10;
性能优化点:
- 使用ST_Distance_Sphere函数计算精确距离(MySQL 5.7+)
- 建立geohash前缀索引加速查询
- 缓存热门区域的服务人员列表
4. 典型问题解决方案
4.1 高并发预约冲突
采用乐观锁解决库存争用问题:
java复制@Transactional
public boolean bookService(Long serviceId, Integer quantity) {
// 1. 查询当前库存
Service service = serviceMapper.selectById(serviceId);
// 2. 校验版本号
int updated = serviceMapper.updateStock(
serviceId,
quantity,
service.getVersion());
return updated > 0;
}
4.2 定时任务补偿设计
处理未支付订单的自动取消:
java复制@Scheduled(cron = "0 0/30 * * * ?")
public void cancelUnpaidOrders() {
List<Order> orders = orderMapper.selectExpiredOrders();
orders.forEach(order -> {
order.setStatus(OrderStatus.CANCELLED);
orderMapper.updateById(order);
// 释放关联的预约时段
scheduleService.releaseTimeSlot(order.getWorkerId(), order.getServiceTime());
});
}
5. 部署与运维实践
5.1 生产环境配置建议
application-prod.yml关键配置:
yaml复制spring:
datasource:
hikari:
maximum-pool-size: 20
connection-timeout: 30000
redis:
cluster:
nodes: 192.168.1.101:6379,192.168.1.102:6379
lettuce:
pool:
max-active: 16
5.2 性能监控方案
-
Prometheus + Grafana监控:
- 采集指标:接口响应时间、SQL执行时长、缓存命中率
- 预警阈值:
- 平均响应时间 > 500ms
- 错误率 > 0.5%
-
日志收集架构:
code复制Filebeat → Logstash → Elasticsearch
↗
Kafka(作为缓冲)
6. 开发经验与避坑指南
-
Layui表格渲染问题:
- 现象:动态加载数据后表头错位
- 解决方案:在数据渲染后执行
layui.table.resize('tableId')
-
MySQL时区陷阱:
- 错误配置:
serverTimezone=UTC导致时间显示差8小时 - 正确配置:
serverTimezone=Asia/Shanghai
- 错误配置:
-
Spring Boot多模块依赖冲突:
- 使用
mvn dependency:tree排查重复依赖 - 推荐在父POM中统一管理版本号
- 使用
-
JSP EL表达式失效:
- 检查page指令:
<%@ page isELIgnored="false" %> - 确保web.xml版本≥3.0
- 检查page指令:
-
微信支付回调处理:
- 必须支持GET/POST两种方式
- 响应体必须为纯文本"success"或"fail"
这个系统在实际运营中经受住了日均3000+订单的考验,核心在于三个设计原则:① 状态驱动的事务处理 ② 无状态的API设计 ③ 最终一致性补偿机制。特别是在服务人员调度算法上,后续可引入机器学习模型来优化匹配精准度。
