1. 项目背景与核心需求
家政保洁预约系统是近年来O2O服务领域的热门应用场景。随着城市化进程加快和生活节奏提速,越来越多的家庭开始依赖专业保洁服务。传统电话预约方式存在效率低下、服务记录混乱、价格不透明等问题,而一个基于SpringBoot+Vue的现代化预约系统能有效解决这些痛点。
我在实际开发中发现,这类系统需要重点关注以下几个核心需求:
- 用户端:便捷的预约流程、服务项目选择、时间安排、支付功能
- 服务端:订单管理、人员调度、服务评价、数据统计
- 系统层面:高并发处理、数据安全、移动端适配
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术选型与架构设计
2.1 为什么选择SpringBoot+Vue组合
SpringBoot作为后端框架具有明显优势:
- 自动配置简化了传统Spring项目的繁琐设置
- 内嵌Tomcat容器,部署便捷
- 丰富的starter依赖,快速集成MyBatis、Redis等组件
- 完善的生态和社区支持
Vue.js作为前端框架的考虑:
- 响应式数据绑定,简化DOM操作
- 组件化开发,提高代码复用率
- 轻量级且学习曲线平缓
- 与Element UI等组件库完美配合
2.2 系统架构设计
采用前后端分离架构:
code复制客户端层(Vue) → API网关层 → 业务逻辑层(SpringBoot) → 数据访问层 → 数据库
关键组件说明:
- 前端:Vue3 + Vue Router + Pinia + Element Plus
- 后端:SpringBoot 2.7 + MyBatis-Plus + Spring Security
- 数据库:MySQL 8.0 + Redis缓存
- 部署:Nginx反向代理 + Docker容器化
3. 核心功能模块实现
3.1 用户认证与权限管理
采用JWT实现无状态认证:
java复制// Spring Security配置示例
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager()));
}
}
前端路由守卫实现:
javascript复制// router/index.js
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!store.getters.isLoggedIn) {
next('/login')
} else {
next()
}
} else {
next()
}
})
3.2 预约服务模块设计
数据库表关键字段设计:
sql复制CREATE TABLE `service_order` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL,
`service_type` varchar(50) NOT NULL,
`appointment_time` datetime NOT NULL,
`address` varchar(255) NOT NULL,
`status` tinyint DEFAULT '0' COMMENT '0-待确认 1-已确认 2-服务中 3-已完成 4-已取消',
`price` decimal(10,2) NOT NULL,
`worker_id` bigint DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
时间冲突校验逻辑:
java复制public boolean checkTimeConflict(Long workerId, LocalDateTime startTime, int duration) {
LocalDateTime endTime = startTime.plusHours(duration);
return orderMapper.countByWorkerAndTime(workerId, startTime, endTime) > 0;
}
3.3 支付系统集成
采用支付宝沙箱环境实现支付流程:
- 前端调用后端创建支付订单接口
- 后端生成支付参数并签名
- 前端使用支付宝JS SDK发起支付
- 支付宝异步通知处理
关键代码片段:
java复制@PostMapping("/pay")
public Result createPayment(@RequestBody OrderPayDTO dto) {
// 校验订单状态
Order order = orderService.getById(dto.getOrderId());
if (order.getStatus() != OrderStatus.CONFIRMED) {
throw new BusinessException("订单状态异常");
}
// 调用支付宝接口
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setBizContent(JSON.toJSONString(new AlipayTradePagePayModel(){
{
setOutTradeNo(order.getOrderNo());
setTotalAmount(order.getPrice().toString());
setSubject("家政服务订单");
setProductCode("FAST_INSTANT_TRADE_PAY");
}
}));
return Result.success(alipayClient.pageExecute(request).getBody());
}
4. 系统优化与性能提升
4.1 高并发场景处理
采用多级缓存策略:
- 本地缓存(Caffeine)存储热点数据
- Redis缓存共享数据
- MySQL持久化存储
库存扣减方案对比:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 悲观锁 | 强一致性 | 性能低 | 库存极少场景 |
| 乐观锁 | 性能较好 | 重试成本高 | 中等并发 |
| Redis原子操作 | 性能最佳 | 实现复杂 | 高并发场景 |
最终采用Redis+Lua脚本实现:
lua复制local key = KEYS[1]
local change = tonumber(ARGV[1])
local current = tonumber(redis.call('GET', key))
if current >= change then
return redis.call('DECRBY', key, change)
else
return -1
end
4.2 前端性能优化
- 路由懒加载:
javascript复制const routes = [
{
path: '/services',
component: () => import('../views/Services.vue')
}
]
- 图片懒加载:
html复制<img v-lazy="item.image" alt="服务图片">
- API请求节流:
javascript复制import { throttle } from 'lodash'
methods: {
search: throttle(function(keyword) {
// API调用
}, 500)
}
5. 部署与运维方案
5.1 容器化部署
Docker Compose配置示例:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
volumes:
- ./mysql/data:/var/lib/mysql
redis:
image: redis:6
ports:
- "6379:6379"
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
- redis
frontend:
build: ./frontend
ports:
- "80:80"
5.2 监控与日志
SpringBoot Actuator配置:
properties复制management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=always
ELK日志收集方案:
- Filebeat收集日志
- Logstash过滤处理
- Elasticsearch存储
- Kibana可视化
6. 开发中的典型问题与解决方案
6.1 跨域问题处理
后端配置:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowCredentials(true)
.maxAge(3600);
}
}
前端代理配置(vue.config.js):
javascript复制module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true
}
}
}
}
6.2 时间处理时区问题
统一使用UTC时间存储:
java复制@Configuration
public class JacksonConfig {
@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
return builder -> {
builder.timeZone(TimeZone.getTimeZone("UTC"));
builder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");
};
}
}
前端显示时转换:
javascript复制import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'
dayjs.extend(utc)
dayjs.extend(timezone)
const localTime = dayjs.utc(utcTime).tz('Asia/Shanghai').format('YYYY-MM-DD HH:mm')
7. 项目扩展方向
- 智能派单系统:基于地理位置和服务员技能自动分配订单
- 会员成长体系:积分、等级、特权等激励机制
- 小程序端开发:覆盖更多用户场景
- 大数据分析:用户行为分析、服务热力图等
- 物联网集成:智能门锁临时密码等功能
在实际开发中,我发现有几个关键点需要特别注意:
- 时间字段一定要明确时区处理策略,避免出现显示时间错乱
- 支付回调接口要做好幂等处理,防止重复通知导致多次记账
- 服务人员的位置信息更新频率要合理,过高会影响性能,过低会导致派单不准确
- 前端表单验证要和服务端验证保持一致,不能仅依赖前端验证
