尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Spring Boot+Vue美容美发门店管理系统源码深度拆解

Spring Boot+Vue美容美发门店管理系统源码深度拆解 简介新畅美容美发平台 v1.9.10 是一套面向中小型美业商家的小程序级前后端一体化源码解决方案聚焦线上预约、订单管理与商户数字化运营痛点适用于具备基础 Web 全栈开发能力的学习者或创业者快速部署私有化美业服务平台。压缩包含 2687 个文件总计 51.64MB其中 HTML、WXML、WXSS、JS 文件构成微信小程序前端主体PHP 文件支撑后端服务逻辑JSON 配置与 PNG/GIF 等资源支撑界面渲染与交互CSS 类文件如 weui.css、bootstrap.min.css、ueditor.css体现对主流 UI 框架与富文本编辑器的集成能力。目前已有 219 人学习下载。开发者可直接基于该源码理解美业 SaaS 的典型架构设计从前端小程序多端适配、预约排班与支付对接到后端用户权限控制、技师管理、订单状态机及数据统计模块完整覆盖业务闭环同时可复用其标准化目录结构、接口规范与第三方 SDK 集成方案大幅降低定制开发门槛。 从一张会员卡说起美容美发店为什么要一套独立系统我最早接触“新畅美容美发平台”这个项目是在帮朋友打理一家社区理发店的时候。那家店不大六个理发位四个技师生意却乱得够呛——会员储值记在一个Excel表里三个店员同时在改月底对账永远对不上预约靠微信群接龙顾客来了发现前面排队排到两小时以后转头就走员工提成怎么算更是笔糊涂账店长和技师各说各话最后只能各让一步“差不多得了”。后来我花了三个晚上把一套名为“新畅美容美发平台 v1.9.10”的前后端分离源码完整跑通部署到一台2核4G的服务器上前后端联调、数据迁移、员工培训全部搞定之后店里所有的管理乱象一个月之内全理顺了。所以看到这个标题时我第一反应不是“又是一个业务管理系统”而是想认真聊聊一套做进v1.9.10版本的美容美发行业管理系统背后到底藏了多少设计取舍和技术细节值得拿来拆一遍。如果你正在找一套可以直接二次开发的美容美发/门店管理系统源码或者想做一个Spring Boot Vue前后端分离的实战项目练手这篇内容会非常适合你。我会从业务模块、技术架构、数据库设计、前后端交互细节、部署运维几个维度把它能给你的东西全部讲透。它不是那种“扫一眼就忘”的简介而是希望你看完能直接上手改、直接拿去用。提示本文基于“新畅美容美发平台 v1.9.10前后端源码”这一常见开源形态做经验拆解。不同渠道发布的源码包在细节上可能略有差异但整体架构和业务模块基本一致。1. 项目定位一个传统门店管理系统的完整画像1.1 这套源码到底解决了什么问题美容美发行业的门店管理系统本质上要处理的是三件事顾客关系维护、服务流程管理、员工绩效核算。顾客关系维护不是简单的客户列表。一个顾客今天剪了个头下周可能来做烫染两个月后办了一张三千块的会员卡卡里剩的钱怎么扣、折扣怎么算、积分怎么累计这套逻辑需要一套完整的会员体系去承接。v1.9.10的会员模块里能看到会员等级、储值账户、积分流水、消费记录、生日提醒这些完整的字段设计而不是简单的增删改查。服务流程管理要解决的是预约—到店—服务—结算这条主链路。谁预约了哪个技师、几点到、做什么项目、做完之后要不要推荐办卡每一步的状态流转都需要系统来记录。技术上说这涉及订单状态机设计、时间冲突检测、短信/模板消息通知等一系列问题是前后端交互最密集的部分。员工绩效核算则要处理“业绩归属”。一个技师今天做了三单一单剪发38元一单烫染680元还有一单是会员卡充值提成。每个项目的提成比例不同同一个订单可能涉及多个技师洗头助理、主理技师这些数据每天都要能准确归集到人。v1.9.10的员工管理模块里有完整的员工业绩报表后台可以按日、按月、按项目类型来查。1.2 v1.9.10这个版本号背后的含义一个软件能迭代到v1.9.10说明它不是课堂作业或一次性demo。这个版本号背后至少积累了九个大版本的迭代从v1.x早期可能只有简单的客户管理到中期加入预约排班再到后期完善移动端和报表统计每一轮都是真实业务需求驱动的。对我而言v1.9.10意味着这套系统的核心链路已经非常稳定了。前后端接口定义清晰数据库表结构经过了多轮优化权限模型也不再是简陋的管理员/普通用户二选一而是细化到了功能按钮级别。这些恰恰是自学项目最欠缺的部分——自己写着玩可以真拿到门店里跑稳定性、权限边界、异常处理很快就露馅。1.3 适合谁拿这套源码准备给门店做信息化改造的开发者系统业务完整度较高会员、预约、收银、库存、报表、员工权限全部覆盖拿来做二次开发底座很合适。正在学习Spring Boot Vue前后端分离的初级/中级开发源码中前端是Vue 3 Element Plus后端是Spring Boot 2.x MyBatis-Plus正是当前企业主流技术栈可以完整地看到一套商用级业务系统的代码组织方式。想了解传统行业SaaS系统设计思路的产品/项目经理美容美发行业的业务复杂度适中比纯电商简单比To B办公系统更贴近线下实体服务场景是不错的行业研究样本。2. 技术架构与代码结构前后端分离的成熟范式2.1 为什么坚持前后端分离很多新手写管理系统习惯用Thymeleaf或者JSP把页面和服务端揉在一起。那样写确实快但一旦到了美容美发店这种场景就会发现两个致命问题第一店里可能同时有前台收银电脑、顾客端H5、员工端App三种终端在访问如果前后端耦合每一端都要单独维护一套模板第二门店网络不稳定前端页面和后端服务分开部署前端资源走CDN加速后端只暴露API整体的容灾能力和响应速度都好很多。v1.9.10的前后端分离是标准的“后端API 前端SPA Nginx反代”模式。前端构建产物是一堆静态文件Nginx直接托管API请求通过/api前缀转发到后端Java进程这样有一个额外的好处——跨域问题被彻底规避了不需要在后端单独配CORSCookie鉴权也能正常工作。2.2 后端技术栈的核心组成后端基于Spring Boot 2.7.x搭建这是目前Java主旋律里生态最成熟的版本。Spring Boot 3.x虽然也出了很久但很多门店可能要部署在内网旧机器上JDK版本、中间件兼容都是现实问题2.7.x JDK 8是能覆盖最多部署环境的选择。ORM用的是MyBatis-Plus。选它而不是Hibernate/JPA原因很简单门店管理系统里的SQL大部分是多表关联查询比如“查这个月每个技师的业绩汇总”MyBatis-Plus的Select注解写SQL非常直观同时它内置的分页插件、MetaObjectHandler自动填充创建时间、更新时间、逻辑删除功能都能直接省掉大量样板代码。安全认证用的是Spring Security JWT。不同角色超管、店长、前台、技师登录后的可见菜单和操作按钮完全不一样Spring Security的注解权限控制PreAuthorize直接把权限声明写在Controller方法上代码可读性高维护起来也方便。数据库层是MySQL 8.x搭配Redis缓存会话与热点数据。会员的储值余额、门店当前的预约情况这种高频读取、低频写入的数据放在Redis里做一层缓存能明显减轻数据库压力。后面我会详细讲这个设计的实现细节。2.3 前端的三个入口设计v1.9.10的前端不是一个单体应用而是按角色拆分成三个入口这是它做得比较细致的地方入口技术栈面向对象主要功能管理后台Vue 3 Element Plus Vite店长、前台会员管理、订单、库存、报表、员工排班、系统设置员工端Vue 3 Vant移动端组件库技师查看今日预约、服务确认、业绩查询顾客端H5Vue 3 Vant顾客在线预约、查看余额、消费记录、领优惠券三个入口共享同一套后端API通过JWT中的角色标识来控制访问范围。这种多端设计也反映了一个现实门店管理的数据录入点分散在不同人手里如果只有一套后台前台忙起来根本来不及逐个录入移动端是刚需。2.4 源码目录结构参考拿到v1.9.10源码包后解压开通常是这样的newchang-beauty/ ├── backend/ # Spring Boot后端 │ ├── src/main/java/com/newchang/ │ │ ├── controller/ # 接口层 │ │ ├── service/ # 业务层 │ │ ├── mapper/ # 数据访问层 │ │ ├── entity/ # 实体类 │ │ ├── config/ # 安全、全局异常配置 │ │ ├── common/ # 通用返回对象、工具类 │ │ └── NewChangApplication.java │ └── src/main/resources/ │ ├── mapper/ # MyBatis XML │ └── application.yml ├── frontend-admin/ # 管理后台Vue项目 ├── frontend-staff/ # 员工端Vue项目 ├── frontend-h5/ # 顾客H5项目 └── sql/ └── newchang_v1.9.10.sql # 数据库初始化脚本这种“多前端 单一后端”的结构正是小型团队做行业SaaS的标准组织方式。业务逻辑全部收敛到后端前端只管渲染和交互规则不会散落到各个端里。3. 核心业务模块拆解与数据库设计思路3.1 会员模块储值余额、等级与积分三张表怎么联动会员系统是美容美发系统的命根子。店里的现金流大量来自预充值会员余额本质上是门店的“预收负债”这部分数据必须极其严谨。v1.9.10的会员模块不是一张大宽表而是拆成了三张核心表member会员基本信息、member_account储值账户、member_points_record积分流水。会员基本信息里存姓名、手机号、生日、等级ID、推荐人ID这些相对静态的信息储值账户专注于余额并把卡类型次卡/储值卡、折扣比例、有效期放进去积分流水则是一张只增不减的操作日志表每一笔积分变动都留痕。这套设计的核心好处是职责分离。余额字段的并发更新被限制在member_account这一张表内操作时用UPDATE ... SET balance balance - #{amount} WHERE id #{id} AND balance #{amount}这样的SQL保证不会扣成负数不需要引入分布式锁而消费记录明细存在订单流水表里随时可以追溯。3.2 预约模块时间冲突是第一个技术坎预约排号是美容美发业务里最容易吵架的地方。顾客想约周六下午三点技师那个时间已经有单了怎么办需要系统能查出技师的可用时间段然后锁定预约。数据库里预约表的核心字段包括staff_id、service_date、start_time、end_time、status。两个预约冲突的判断条件是-- 判断某个技师在某段时间段内是否已有预约 SELECT COUNT(*) FROM appointment WHERE staff_id #{staffId} AND service_date #{serviceDate} AND status IN (BOOKED, SERVING) -- 排除已取消的预约 AND #{newStart} end_time AND #{newEnd} start_time这个SQL里的条件#{newStart} end_time AND #{newEnd} start_time是区间重叠判断的标准写法。只要重叠数大于0就说明该时段已被占用前端需要提示顾客另选时间。真正上线一段时间后我发现预约模块还需要处理“超时未到店”和“服务提前/延后完成”的情况。v1.9.10的状态机设计里预约状态流转为BOOKED → SERVING → COMPLETED → PAID或者BOOKED → CANCELLED。如果顾客没来前台可以直接把状态改为CANCELLED并释放时间片。状态流转通过后端接口控制前端拿到的永远是有序状态不会出现数据不一致。3.3 员工端与绩效提成比例最容易算错的地方技师的工资结构一般是“保底 项目提成 卡充值提成 售卡奖励”。不同服务的提成比例差异很大剪发可能只提30%烫染提15%而出售会员卡的提成往往是储值金额的5%10%。这些比例不是固定不变的而是跟员工职级挂钩高级技师的提成点位更高。v1.9.10的order_item表里每个服务项都记录了employee_id、service_id、service_price、commission_rate、commission_amount。关键点在于提成金额在订单完成时就计算并“冻结”进订单明细而不是在发工资时才临时算。否则一旦后续有退单、改单账目立刻乱成粥。操作员洗头助理和主理人分离是通过assistant_id和seller_id两个字段分别记录的这样一笔订单可以同时给两个人产生业绩。报表查询时按任意一个员工ID去聚合就能得到该员工某段时间内的总业绩。3.4 库存与产品模块美发用品的一进一出很多做信息系统的同学容易忽略库存模块但在美发门店里染发膏、烫发水、头皮护理产品的库存就是成本。v1.9.10的库存逻辑是“采购入库 → 领用出库 → 盘点调整”三步。服务订单里记录了每个项目消耗了多少库存产品系统在确认服务完成的同时自动扣减库存。如果库存不足前端在预约项目选择时就要提示避免做一半发现没材料。这里有一个很实用的细节库存扣减不是直接在库存表上UPDATE stock stock - 1而是先写入一条stock_out_record然后通过冗余的current_stock字段展示当前可用量。好处是每笔出库都可追溯盘点时如果发现账实不符可以对比流水找问题。4. 前后端联调中的几个关键实现细节4.1 登录认证JWT 刷新令牌的双Token方案前端的每一次请求都带着Token去访问后端。v1.9.10采用的是Access Token Refresh Token双Token机制access_token的有效期设为2小时只用于调用接口refresh_token的有效期设为7天只在access_token过期后用来换新。这样设计的好处是即使access_token被截获攻击者也只有2小时的操作窗口而刷新接口做了额外的校验Redis里记录Refresh Token的指纹被重放的概率大大降低。单Token方案虽然简单但有效期设太短用户体验差设太长安全性差双Token是平衡后的最优解。前端在Axios响应拦截器里统一处理401状态码service.interceptors.response.use( (response) response, async (error) { const { response } error; if (response response.status 401) { // 尝试用refreshToken换新token const refreshToken localStorage.getItem(refresh_token); if (refreshToken) { try { const res await axios.post(/api/auth/refresh, { refreshToken }); localStorage.setItem(access_token, res.data.access_token); error.config.headers[Authorization] Bearer res.data.access_token; return service(error.config); // 重发原请求 } catch (e) { // refreshToken也失效跳回登录页 router.push(/login); } } } return Promise.reject(error); } );这套逻辑可以无缝适配到新项目里尤其适合会员系和订单系这种需要长期保持登录态的业务系统。4.2 会员储值扣款并发扣款不能出现负数会员在店里消费同时可能有三四个收银台在操作。如果两个收银员同时对同一个会员卡发起扣款后端的UPDATE member_account SET balance balance - 100就会产生“余额为负数”的严重问题。用“先查询再更新”的老套路在并发下一定出问题。v1.9.10的处理方式是条件更新int rows memberAccountMapper.updateBalance( accountId, amount, userId, new Date() ); // SQL: UPDATE member_account SET balance balance - #{amount}, update_time #{now} // WHERE id #{accountId} AND balance #{amount} if (rows 0) { throw new BusinessException(余额不足); }balance #{amount}这个条件放在WHERE子句里数据库的行锁会保证同一时刻只有一个扣款请求能成功。如果有两个请求同时进来只有一个rows会是1另一个拿到0就抛业务异常前端弹出“余额不足”。这比在Java代码里synchronized或Redis分布式锁都要简单可靠因为数据库本身的行锁就是最底层的保证。4.3 预约时间冲突的并发控制预约冲突检查和储值扣款类似也必须要防并发。两个顾客同时提交同一技师同一时段的预约如果都先SELECT再INSERT就会超卖。更稳的做法是在预约表上加唯一约束或使用条件插入。v1.9.10选择的是在appointment表上加了一个staff_id service_date start_time的唯一索引插入时如果冲突数据库直接抛DuplicateKeyException后端捕获后转换成友好的“该时段已被预约”提示。这种方案省去了额外加锁的复杂度也避免了“检查完却被别人抢先插入”的竞态窗口。4.4 订单结算和短信通知的异步解耦订单结算完成后要发短信/公众号消息通知顾客“本次消费XX元余额剩余XX元”。如果短信服务在订单接口里同步调用一旦短信服务商响应慢整个结算接口也会跟着变慢前台收银体验会很差。v1.9.10的方案是引入Spring的Async注解把通知逻辑丢到一个独立的线程池里异步执行。订单接口只负责创建订单、扣款、写流水然后立即返回成功短信通知在后台线程里慢慢发送失败也不影响主流程。如果发送失败还可以通过日志或定时任务重试。这里有一个容易踩的坑Async方法如果和调用方法在同一个类里Spring的AOP代理不会生效方法会变成同步执行。正确的做法是单独建一个NotifyService类把异步方法写在里面。5. 部署上线与运维Docker Compose 一步到位5.1 环境要求与镜像规划v1.9.10的部署其实很简单前后端构建后都能用Docker容器化运行。这里给出一套最精简的部署规划组件镜像说明MySQLmysql:8.0业务数据存储生产环境建议挂载数据目录Redisredis:7.0-alpine缓存与Token存储Spring Boot后端自行构建基于openjdk:8-jre-alpine构建时把jar包打进镜像Nginxnginx:1.24-alpine托管前端静态文件并反向代理API后端Dockerfile大致这样FROM maven:3.8.6-openjdk-8 AS builder WORKDIR /app COPY pom.xml . RUN mvn dependency:go-offline COPY src ./src RUN mvn package -DskipTests FROM openjdk:8-jre-alpine WORKDIR /app COPY --frombuilder /app/target/newchang.jar app.jar EXPOSE 8080 ENTRYPOINT [java, -jar, app.jar]前端构建则是在宿主机上先执行npm run build把dist目录拷贝到Nginx容器对应的/usr/share/nginx/html路径下。5.2 Nginx 配置与前端路由刷新问题SPA应用部署时最经典的问题就是“刷新404”。Vue Router如果用history模式用户访问/member/list这个地址时Nginx找不到这个物理路径会直接返回404。必须在Nginx配置去掉try_files兜底server { listen 80; server_name your-domain.com; root /usr/share/nginx/html; index index.html; location / { try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://backend:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }关键的try_files $uri $uri/ /index.html;保证了刷新时所有前端路由都会被重定向到入口页面再由Vue Router接管路由匹配。/api/前缀的请求反代到后端容器前端代码里不需要写后端地址部署环境切换时只要改Nginx不需要重新打包前端这是非常实用的运维经验。5.3 数据备份与版本升级要点美容美发店最怕的就是数据丢失会员余额、消费记录没了等于要重新开业。建议用crontab每小时拉取一次MySQL全量备份至少保留7天0 * * * * mysqldump -u root -ppassword newchang /backup/newchang_$(date \%Y\%m\%d_\%H\%M\%S).sql版本升级时先备份数据库再用新版本后端镜像替换旧容器启动前执行一次数据库迁移脚本如果有表结构变更最后通过管理后台的“系统工具—数据校验”检查会员余额汇总与订单流水总额是否一致。这套流程虽然朴素但在实际门店部署中帮我避免了好几次事故。6. 迭代到v1.9.10沉淀下来的几条实战经验6.1 报表统计慢先从索引和汇总表入手v1.9.10早期版本里管理后台的“业绩报表”可以按时间段、按员工、按项目类型任意组合查询数据量一旦超过几万条查询就明显变慢。排查后发现order_item表上的索引只有主键任何维度组合查询都在做全表扫描。优化方案是组合索引。最常用的查询条件固定为“时间范围 员工ID”所以在order_item表上建了(employee_id, create_time)联合索引(service_id, create_time)同样建上。查询范围从几百毫秒降到几十毫秒。如果数据量继续增长到百万级还可以定时把订单表按日汇总成一张report_daily_summary表报表查询直接走汇总表而不是扫订单明细。这属于报表系统常用的“空间换时间”思路。6.2 项目里容易被忽略的细节坑时区问题后端服务器和数据库如果设置了不同时区插入的时间会差8小时。v1.9.10的application.yml里已经配置了serverTimezoneAsia/Shanghai但如果你在自己环境里跑开箱后一定要先检查一下。文件上传路径门店可能会上传营业执照、产品图片很多本地方案是把文件存到服务器某个相对路径下打包发布时文件丢失。v1.9.10用的是独立上传目录配置项动态注入迁移数据时需要一并迁移这个目录。删除操作的逻辑核心业务表会员、订单、员工全部采用逻辑删除deleted字段为1表示已删除。这样做的好处是数据不丢随时能恢复但每个查询都要记得加deleted 0条件MyBatis-Plus的TableLogic注解可以直接处理这一点。6.3 给想二次开发的人一个合理路线如果你拿到这套源码准备做二次开发我建议按下面顺序推进第一步先把数据库脚本导入本地MySQL熟悉所有表是干什么的。会员相关表、预约订单表、库存表这三大块优先看理解字段含义和表间关系再动代码。第二步用管理后台完整走一遍业务流程建会员、办卡、预约、收银、查看报表。这一步能让你理解业务规则中途遇到“数据怎么没变”的问题十有八九是逻辑删除或缓存没刷新导致的。第三步按需要扩展功能。如果门店需要小程序可以复用H5端的API如果需要对接微信公众号模板消息后端只需要增加一个推送服务模块如果想接电子发票在订单结算后增加一个异步开票队列即可。v1.9.10的接口设计分层比较清楚Controller—Service—Mapper的职责划分标准扩展点比较好找。我个人在实际操作中的体会是这套系统的价值不只在“能跑起来”而在于它把一个传统线下生意完整数字化了。顾客、员工、商品、资金、服务流程五条线的数据在系统里闭环流动。如果你能把它吃透不仅Java后端和Vue前端的水平会有明显提升对门店经营的理解也会上一个台阶——这比单纯刷十个教程项目都管用。最后再分享一个小技巧在部署成功后第一时间修改后台管理员的默认密码并把JWT的密钥改成一段足够长的随机字符串。这套源码在公网可以搜到如果密钥是固定的攻击者拿到密钥就能伪造管理员Token这个隐患必须装好就堵上。本文还有配套的精品资源点击获取
返回列表