SpringBoot+Vue美容院管理系统架构与实现
1. 项目概述:企业级美容院管理系统的技术架构解析
这套美容院管理系统采用当前主流的全栈技术方案,后端基于SpringBoot框架构建,前端使用Vue.js实现,数据持久层采用MyBatis框架,数据库选用MySQL。这种技术组合在中小型企业级应用中具有显著优势:SpringBoot的自动配置特性让后端服务快速搭建,Vue的组件化开发模式提升前端开发效率,MyBatis的SQL灵活性满足复杂业务查询需求,而MySQL作为成熟的关系型数据库则保障了数据可靠性。
提示:系统完整源码包含前后端所有模块,从会员管理、预约排班到库存管理和财务统计,覆盖美容院日常运营全流程。
2. 核心功能模块设计
2.1 会员管理体系实现
采用RBAC权限模型设计,会员数据表包含基础信息、消费记录、皮肤档案等字段。前端使用Vue的Element UI组件构建表单,后端通过SpringBoot的@RestController暴露RESTful API。一个典型的会员查询接口实现如下:
@GetMapping("/members/{id}") public ResponseEntity<MemberVO> getMemberDetail( @PathVariable Long id, @RequestHeader("Authorization") String token) { // 权限验证 if(!authService.validateToken(token)){ return ResponseEntity.status(401).build(); } // 业务逻辑 Member member = memberService.getById(id); MemberVO vo = new MemberVO(); BeanUtils.copyProperties(member, vo); // 关联查询消费记录 List<Consumption> consumptions = consumptionService.listByMemberId(id); vo.setConsumptions(consumptions); return ResponseEntity.ok(vo); }2.2 预约排班系统
采用时间片分割算法处理并发预约,数据库使用乐观锁防止超订。前端日历组件基于FullCalendar改造,支持拖拽调整预约时间。关键数据库表设计:
| 字段名 | 类型 | 描述 |
|---|---|---|
| id | BIGINT | 主键 |
| staff_id | BIGINT | 美容师ID |
| member_id | BIGINT | 会员ID |
| start_time | DATETIME | 开始时间 |
| end_time | DATETIME | 结束时间 |
| status | TINYINT | 状态(0待确认 1已预约 2已取消) |
| version | INT | 乐观锁版本号 |
3. 技术实现细节
3.1 SpringBoot后端关键配置
在application.yml中配置多数据源和事务管理:
spring: datasource: primary: url: jdbc:mysql://localhost:3306/beauty_salon?useSSL=false username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver secondary: url: jdbc:mysql://localhost:3306/beauty_salon_report?useSSL=false username: report password: report123 driver-class-name: com.mysql.cj.jdbc.Driver jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+83.2 Vue前端工程结构
采用Vue CLI创建的典型项目结构:
src/ ├── api/ # 接口定义 ├── assets/ # 静态资源 ├── components/ # 公共组件 │ ├── MemberCard.vue │ └── Calendar.vue ├── router/ # 路由配置 ├── store/ # Vuex状态管理 ├── utils/ # 工具函数 └── views/ # 页面组件 ├── member/ └── appointment/4. 系统部署方案
4.1 数据库初始化
提供完整的SQL建表脚本,包含索引和基础数据:
CREATE TABLE `member` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `phone` varchar(20) NOT NULL, `gender` tinyint(1) DEFAULT '0', `birthday` date DEFAULT NULL, `skin_type` varchar(20) DEFAULT NULL, `balance` decimal(10,2) DEFAULT '0.00', `points` int(11) DEFAULT '0', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `idx_phone` (`phone`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;4.2 前后端分离部署
推荐使用Nginx作为前端静态资源服务器,配置示例:
server { listen 80; server_name salon.example.com; location / { root /usr/share/nginx/html/dist; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }5. 开发注意事项
MyBatis缓存问题:在开启事务的方法中,一级缓存可能导致查询不到最新数据。解决方案:
- 在Mapper接口上添加@CacheNamespace(flushInterval=60000)配置缓存刷新
- 关键更新操作后手动调用clearCache()
Vue性能优化:
- 使用v-if替代v-show减少初始渲染压力
- 大数据列表采用虚拟滚动(vue-virtual-scroller)
- 路由组件懒加载
SpringBoot安全配置:
- 必须配置CSRF防护
- 接口权限校验使用Spring Security或Shiro
- 敏感数据加密存储
MySQL优化建议:
- 为高频查询字段建立复合索引
- 大表考虑分表策略
- 定期使用EXPLAIN分析慢查询
这套系统在实际部署时,建议先在小规模门店试运行,验证预约高峰期的系统稳定性。我们曾遇到过一个典型问题:当多个店员同时为同一会员添加服务项目时,由于未做并发控制导致余额计算错误。最终通过Redis分布式锁+数据库事务的方案解决:
public boolean addService(Long memberId, List<ServiceItem> items) { String lockKey = "member:" + memberId; try { // 获取分布式锁 boolean locked = redisTemplate.opsForValue() .setIfAbsent(lockKey, "1", 30, TimeUnit.SECONDS); if(!locked) { throw new BusinessException("操作过于频繁,请稍后重试"); } // 开启事务 return transactionTemplate.execute(status -> { try { // 业务逻辑 memberService.consumeBalance(memberId, totalAmount); consumptionService.saveRecords(memberId, items); return true; } catch(Exception e) { status.setRollbackOnly(); throw e; } }); } finally { redisTemplate.delete(lockKey); } }对于需要处理大量数据分析的报表模块,建议单独使用读库或配置MySQL主从复制。系统还预留了微信小程序对接接口,可通过改造RESTful接口快速实现移动端接入。