ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Java三端美容管理系统源码实战:从部署到二次开发避坑指南

Java三端美容管理系统源码实战:从部署到二次开发避坑指南

简介:这是一套面向Java开发者与美容行业信息化从业者的美容管理系统源码,采用多端架构,包含后台管理端、商家端与微信端,可支撑消费者关注服务号后在线预约项目、到店消费与服务的完整业务闭环。系统基于IMS框架开发,后台与商家端使用easyui及美化主题包,微信端采用aui框架并集成微信JSSDK,实现分享、地图定位、模板消息推送,同时接入威富通第三方支付,覆盖微信、支付宝、扫码枪扫码及微信H5支付,并集成阿里大于短信功能。压缩包共约2000个文件,整体85.05MB,以png、js、css、java、jsp、html、jar、xml等为主,涵盖前端页面、后端逻辑、样式资源与依赖库,另有sql脚本与配置文件,便于快速部署与二次开发。目前已有303人学习下载,适合需要研究多端Java项目架构、微信生态集成与支付对接的开发者参考借鉴。

1. 三端分离的 Java 美容管理系统:一份能跑起来的源码到底长什么样

很多做 Java 课程设计或者接私活的朋友,拿到「美容管理系统」这类关键词时,第一反应是去搜现成的后台管理系统模板,结果下回来一堆只有 CRUD 的脚手架,业务逻辑全靠自己编。这份源码不太一样的地方在于,它把一套美容行业的实际业务拆成了三个端:后台管理端、商家端、微信端。后台负责平台级配置和审核,商家端给门店店长用,微信端面向 C 端顾客做预约、查看订单和会员卡。三个端共用一套 Java 后端服务,数据库表结构也是打通的,不是那种三个独立项目硬拼在一起的缝合怪。

从技术选型上看,这套源码走的是典型的 Java Web 路线,后端大概率是 Spring Boot + MyBatis-Plus 的组合,前端后台管理部分常见做法是 Vue3 或者 Layui,微信端则是微信小程序原生开发或者 uni-app 编译过去。之所以说「大概率」,是因为这类三端项目在 Java 生态里最稳的搭配就是这一套,换别的反而容易在部署时翻车。适合谁用?如果你正在做课程设计、毕业设计,或者想拿一个带真实业务场景的项目练手三端联调,这份源码的完整度是够的。但如果你指望它开箱即用直接上线运营,那得先看看后面的部署坑再说。

2. 三端架构拆解:从数据库表到接口分层怎么对上号

2.1 后台、商家端、微信端的职责边界

先把这个系统的三端关系理清楚,不然后面改代码的时候很容易改错地方。后台管理端是平台运营方用的,核心功能包括商家入驻审核、服务项目分类管理、平台公告、数据统计看板。商家端是给具体门店用的,店长在这里维护自己的服务项目、美容师排班、订单核销、会员卡管理。微信端是顾客侧,顾客通过小程序浏览附近门店、预约服务、查看自己的会员卡余额和消费记录。

三端共用同一个数据库,但接口层做了区分。常见做法是在 Controller 层用路径前缀区分,比如/admin/**、/merchant/**、/wx/**,然后在拦截器里做角色权限校验。这种设计的好处是后端只维护一套业务逻辑,坏处是如果权限拦截器写得不严谨,很容易出现越权访问。源码里如果这部分做得粗糙,你在二次开发时就得自己补上。

数据库表的设计上,核心表大概有这些:user(平台用户)、merchant(商家信息)、service_item(服务项目)、appointment(预约订单)、member_card(会员卡)、beautician(美容师)。表之间的关联靠merchant_id和user_id串起来。你拿到源码后第一件事应该是把 SQL 文件导入数据库,然后对着 ER 图把外键关系看一遍,不然后面查订单数据时连表都能连错。

2.2 后端分层与关键配置

Java 后端的分层结构基本是 Controller → Service → Mapper → Entity 这条线。源码里如果用了 MyBatis-Plus,那 Mapper 层大部分是继承BaseMapper,单表 CRUD 不用自己写 SQL。但美容管理系统里有些查询是跨表的,比如查某个商家的预约订单列表,需要关联用户表和美容师表,这种就得在 XML 里手写 SQL 或者用 MyBatis-Plus 的@Select注解。

配置文件方面,application.yml里重点看三个地方:数据库连接、微信小程序的appid和secret、文件上传路径。数据库连接不用多说,改成你本地的地址和密码就行。微信小程序的配置是很多人容易忽略的,源码里如果写死了作者的appid,你直接跑起来微信端会报错,必须换成你自己在微信公众平台注册的小程序appid。

# application.yml 关键配置片段 spring: datasource: url: jdbc:mysql://localhost:3306/beauty_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: your_password driver-class-name: com.mysql.cj.jdbc.Driver wechat: appid: wx_your_appid_here # 换成你自己的小程序 appid secret: your_appsecret_here # 换成你自己的小程序 secret file: upload-path: /data/upload/ # 文件上传目录,确保有写权限

这段配置里,serverTimezone=Asia/Shanghai不加的话,插入订单时间会差 8 小时,这是个经典坑。upload-path如果指向一个不存在的目录,上传服务项目图片时会直接抛异常,建议提前建好目录并给写权限。

2.3 微信端登录与接口联调

微信端的登录流程是整套系统里最容易卡住的地方。标准流程是:小程序端调用wx.login()拿到code,把code传给后端,后端用code+appid+secret去调微信的jscode2session接口,换回openid和session_key,然后后端生成自己的 token 返回给小程序。源码里如果这部分封装好了,你只需要确认appid和secret配置正确就行。

联调的时候,微信开发者工具里要勾选「不校验合法域名」,否则本地localhost的接口请求会被拦截。这个设置在新版开发者工具里藏得比较深,在「详情」→「本地设置」里。另外,微信端的接口请求封装通常会在request.js或者http.js里统一处理 token 注入和错误码,你改接口地址的时候改这一个文件就行,不用满项目找。

// 微信端 request 封装示例 const request = (url, method, data) => { return new Promise((resolve, reject) => { wx.request({ url: baseUrl + url, // baseUrl 在 config.js 里配置 method: method, data: data, header: { 'token': wx.getStorageSync('token') || '' // 从本地缓存取 token }, success: (res) => { if (res.data.code === 401) { // token 过期,重新登录 wx.navigateTo({ url: '/pages/login/login' }) } resolve(res.data) }, fail: reject }) }) }

这段封装里,token是从本地缓存取的,登录成功后要记得wx.setStorageSync('token', token)存进去。如果源码里没做 401 统一处理,token 过期后用户会一直卡在请求失败状态,体验很差,建议自己补上。

3. 本地跑通三端:环境准备与启动顺序

3.1 后端启动前的数据库准备

拿到源码后不要急着mvn spring-boot:run,先把数据库搞定。源码包里一般会有一个sql文件夹,里面是建表语句和初始数据。导入之前先建库,字符集用utf8mb4,不然微信端用户昵称里的 emoji 存进去会变问号。

# 建库并导入数据 mysql -u root -p -e "CREATE DATABASE beauty_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;" mysql -u root -p beauty_db < sql/beauty_db.sql

导入完成后,检查一下user表里有没有初始管理员账号,通常源码里会带一个admin账号,密码可能是123456或者admin123。如果没有,你得自己往表里插一条,密码字段如果是 MD5 加密的,记得用 MD5 工具生成。

3.2 后端编译与启动

数据库准备好之后,用 IDEA 或者 Eclipse 导入 Maven 项目,等依赖下载完。如果依赖下载慢,在settings.xml里配个国内镜像。启动类通常叫BeautyApplication或者Application,找到带@SpringBootApplication注解的那个类,右键运行。

启动过程中如果报Table 'beauty_db.xxx' doesn't exist,说明 SQL 导入不完整,回去检查是不是有些表没建。如果报Access denied for user,检查application.yml里的数据库密码。如果报端口占用,改server.port,默认 8080 被占的概率很高。

启动成功后,浏览器访问http://localhost:8080/admin或者http://localhost:8080/swagger-ui.html(如果集成了 Swagger),能看到接口文档或者登录页就说明后端通了。

3.3 后台管理端和商家端的启动

后台管理端如果是 Vue 项目,进入admin-ui或者vue-admin目录,先npm install,再npm run dev。npm install阶段如果卡在node-sass或者sass-loader上,这是老项目的通病,换成dart-sass或者降低 Node 版本到 14 能解决。启动后默认端口一般是 8081 或者 9528,看vue.config.js里的devServer.port。

商家端如果是独立的前端项目,启动方式一样。但有些源码里商家端和后台管理端是同一个 Vue 项目,通过路由和权限区分,这种就只需要启动一个前端。你拿到源码后先看目录结构,如果只有一个vue-admin目录,那大概率是合在一起的。

前端启动后,接口地址通常在.env.development或者config.js里配置,指向后端地址http://localhost:8080。如果前端能打开但登录报 404,检查这个地址后面有没有多写或者少写/api前缀。

3.4 微信端导入与预览

微信端用微信开发者工具打开,导入wx-miniprogram或者miniprogram目录。导入后第一件事是改appid,在project.config.json里把appid换成你自己的,或者在开发者工具界面右上角「详情」里改。不改的话没法预览,只能看代码。

改完appid后,检查config.js或者utils/config.js里的baseUrl,指向后端地址。本地调试时后端地址写http://localhost:8080,但微信开发者工具需要勾选「不校验合法域名」才能请求通。真机预览的话,localhost不行,得换成你电脑的局域网 IP,比如http://192.168.1.100:8080,并且手机和电脑要在同一个 WiFi 下。

4. 避坑排查:三端联调时最容易翻车的五个地方

4.1 微信端登录报code been used或invalid code

现象是小程序端调登录接口,后端返回微信的错误码40163或者40029。原因是wx.login()拿到的code只能用一次,如果前端在登录按钮上绑定了多次点击事件,或者后端在换openid时重试了,就会报这个错。解决办法是在前端登录按钮上加防抖,或者后端在换openid失败时不要用同一个code重试,而是让前端重新调wx.login()拿新code。

4.2 后台管理端登录后接口全部 401

现象是登录成功了,token 也存了,但后续请求全部返回 401。原因通常是前端请求拦截器里 token 的 header 名称和后端不一致。比如前端写的是Authorization,后端读的是token,或者反过来。解决办法是打开浏览器开发者工具的 Network 面板,看登录成功后返回的 token 字段名,再看后续请求的 Request Headers 里 token 有没有带上,名称对不对。改前端request.js里的 header 设置就行。

4.3 商家端上传图片失败,报File size exceeds maximum

现象是商家端上传服务项目图片时,小图能传,大图报错。原因是 Spring Boot 默认的文件上传大小限制是 1MB,超过就抛MaxUploadSizeExceededException。解决办法是在application.yml里加配置:

spring: servlet: multipart: max-file-size: 10MB max-request-size: 10MB

改完后重启后端。如果还报错,检查 Nginx 有没有做反向代理,Nginx 也有client_max_body_size限制,默认 1MB,需要改成10m。

4.4 数据库中文乱码

现象是后台管理端录入的中文服务项目名称,在微信端显示成问号或者乱码。原因是数据库连接 URL 里没加characterEncoding=utf8,或者数据库本身的字符集不是utf8mb4。解决办法是检查application.yml里的 JDBC URL,确保有useUnicode=true&characterEncoding=utf8,然后检查数据库和表的字符集,用SHOW CREATE TABLE service_item;看CHARSET是不是utf8mb4。不是的话用ALTER TABLE改。

4.5 预约订单时间差 8 小时

现象是用户在小程序端预约了下午 3 点,后台管理端显示的是晚上 11 点。原因是 JDBC URL 里没配serverTimezone,或者配成了UTC。解决办法是把serverTimezone改成Asia/Shanghai,同时检查 MySQL 服务器的时区设置。如果 MySQL 本身时区是 UTC,可以在my.cnf里加default-time-zone='+08:00',或者用SET GLOBAL time_zone = '+08:00';临时改。

5. 二次开发切入点:从改一个业务字段到加一张表

5.1 给服务项目加一个「原价」字段

假设你想在服务项目里加一个「原价」字段,用来显示划线价。操作步骤是:先在数据库service_item表里加一列original_price DECIMAL(10,2),然后在 Entity 类里加对应属性,Mapper XML 里的resultMap和查询 SQL 加上这个字段,Service 层不用动,Controller 层的入参和出参 DTO 加上这个字段,最后前端表单和列表页加上对应的输入框和显示列。这套流程走一遍,你就摸清了这个项目的代码脉络。

// ServiceItem.java 实体类加字段 private BigDecimal originalPrice; // 原价 // ServiceItemMapper.xml 查询语句加字段 <select id="selectById" resultMap="BaseResultMap"> SELECT id, name, price, original_price, merchant_id, ... FROM service_item WHERE id = #{id} </select>

改完记得重启后端,前端也要重新编译。如果前端用的是 Vue,改完.vue文件热更新会自动生效,不用重启。

5.2 加一张「优惠券」表并打通三端

加新表比改字段复杂一些,但套路是一样的。先在数据库建coupon表,字段包括id、merchant_id、name、discount_amount、min_order_amount、start_time、end_time、status。然后生成 Entity、Mapper、Service、Controller 这一套。后台管理端加优惠券管理页面,商家端加优惠券发放功能,微信端在预约下单时可选优惠券。

这里的关键是优惠券的核销逻辑要放在订单支付成功之后,不能在预约时就扣掉,否则用户取消预约优惠券就丢了。常见做法是在appointment表里加一个coupon_id字段,订单创建时关联优惠券,支付回调里把优惠券状态改成「已使用」。

5.3 用 MyBatis-Plus 代码生成器加速开发

如果你要加的表比较多,手写 Entity 和 Mapper 太慢,可以用 MyBatis-Plus 的代码生成器。在pom.xml里加mybatis-plus-generator依赖,写一个CodeGenerator类,配置好数据库连接和包路径,运行一下就能生成 Entity、Mapper、Service、Controller 四件套。

// MyBatis-Plus 代码生成器核心配置 AutoGenerator generator = new AutoGenerator(); generator.setDataSource(new DataSourceConfig() .setUrl("jdbc:mysql://localhost:3306/beauty_db") .setUsername("root") .setPassword("your_password") .setDriverName("com.mysql.cj.jdbc.Driver")); generator.setGlobalConfig(new GlobalConfig() .setOutputDir(System.getProperty("user.dir") + "/src/main/java") .setAuthor("your_name") .setOpen(false)); generator.setPackageConfig(new PackageConfig() .setParent("com.beauty") .setModuleName("coupon") .setEntity("entity") .setMapper("mapper") .setService("service") .setController("controller")); generator.execute();

生成出来的代码是模板化的,业务逻辑还得自己填,但至少省掉了建文件和写基础 CRUD 的时间。生成之前记得把url、username、password换成你自己的,setOpen(false)是生成后不自动打开文件夹,改成true也行。

5.4 验证改动是否生效的检查清单

改完代码后,按这个顺序验证:先看后端启动日志有没有报错,再看数据库表结构是不是改了,然后用 Postman 或者 Swagger 调一下新接口,确认返回数据正确,最后打开前端页面操作一遍,看数据能不能正常显示和提交。如果中间哪一步不对,就停在那一步排查,不要跳过去。我自己的习惯是每改一个功能点就提交一次 Git,这样出问题了可以快速回滚,不至于改到最后不知道哪一步引入了 bug。

从那以后我每次拿到这类三端源码,都强制自己先跑通登录流程再动业务代码,因为登录不通后面全是白搭。希望这份拆解能帮你少走点弯路。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进