尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

SpringBoot3+Vue3+MySQL实现健身房管理系统全栈实践

SpringBoot3+Vue3+MySQL实现健身房管理系统全栈实践 健身房管理系统怎么落地这次不聊需求文档直接从技术方案切入后端用 Java 的 SpringBoot3前端用 Vue.js3存储层用 MySQL组成一套典型的前后端分离管理项目。业务范围可以覆盖会员建档、会员卡续费、私教约课、团课排班、到场签到、订单流水和运营统计基本把一个小型健身房的日常经营闭环装进去了。这个项目的重点不在单个页面或单个接口有多炫而在于三条业务链路是否完整会员从注册到购卡再到约课和签到课程从排期到库存扣减再到核销订单从支付记录到后台统计。只要这三条链路在 SpringBoot3、Vue3 和 MySQL 的环境里能跑通、能联调项目作为课设、毕设或全栈练习的价值就实现了。运行门槛并不高它不像 AI 推理项目那样需要大显存显卡。一台普通开发机内存 8GB 以上安装 JDK 17、Node.js 18、MySQL 8.0就可以完成数据库初始化、后端启动、前端访问和接口验证。本文按照实际开发顺序展开先给核心能力做速览然后讨论适用场景与合规边界接着设计数据库和表结构再分别启动 SpringBoot3 后端与 Vue3 前端最后演示接口调用、批量导入、性能观察和常见问题排查。如果你正在准备 Java 全栈类课程设计或者想从零搭建一套健身房管理系统这篇文章可以直接作为实践参考。1. 核心能力速览与项目定位先给出一个总览表格方便快速判断这套健身房管理系统适不适合你正在做的事。能力项说明项目类型前后端分离的健身房运营管理系统后端技术栈Java 17、SpringBoot 3.x、MyBatis-Plus、Spring Validation、Spring Security可选前端技术栈Vue.js 3、Vite、Vue Router、Pinia、Axios、Element Plus数据库MySQL 8.0字符集使用 utf8mb4核心功能会员建档、会员卡续费、教练排课、私教/团课预约、签到核销、订单记录、统计看板运行环境JDK 17、Maven 3.8、Node.js 18、MySQL 8.0启动方式后端 Maven 启动或 Spring Boot 插件启动前端 npm run dev接口能力RESTful API可接入 Swagger 或 Knife4j 获取在线调试页面批量任务支持 Excel 会员批量导入、定时清理过期会员卡等扩展适合场景计算机类课设、毕业设计、Java 全栈学习、中小型健身房管理原型需要说明一点本文给出的包名、接口路径和 SQL 是通用实现示例不是某个特定开源仓库的快照。你拿到实际源码时只需要按自己的项目结构调整包路径、Controller 前缀和数据库连接参数。为什么推荐这套技术栈SpringBoot3 是当前 Java Web 后端的主流选择内置依赖管理和自动装配开发效率要远高于传统 SSM 手写配置Vue.js3 配合 Vite启动速度和开发体验比旧版本更顺MySQL 在中小型管理系统里仍然是性价比很高的关系型数据库。只要学会这套组合之后做校园管理系统、企业后台、预约平台等都可以复用同一套开发思路。2. 适用场景、权限边界与合规提醒先明确这个东西适合谁用。最匹配的使用者是正在做课程设计或毕业设计的计算机专业学生原因是健身房管理系统有清晰的实体关系会员、课程、预约、订单、管理员非常适合展示 CRUD、分页、登录鉴权和前后端联调能力。另一个适合人群是想快速上手 SpringBoot3 Vue3 全栈协作方式的开发者通过一个小而完整的项目比看十几个零散 Demo 更能理解高层级的接口约定和数据结构设计。它不适合直接拿来当成商业健身房的核心运营系统原因不是代码写不了而是生产环境需要考虑更复杂的问题。真实门店里会遇到多渠道订单、多人同时选课、退款异常、支付对账、员工权限审计、多地多门店数据同步等边界情况。个人项目通常会把支付场景做成预订单或手动标记收款不会接入真实支付通道。如果要商用务必补上支付资质、对账、审计、备份和权限管控。使用边界必须说清楚系统会保存会员手机号、身体数据、训练记录等个人信息这些属于隐私数据。开发阶段用测试手机号即可不要直接放真实客户信息。如果项目要上线需要对手机号、身份证等字段做加密存储数据库访问权限要按角色拆分操作日志要保留。涉及人脸识别、短信验证码、真实支付、电子合同等能力时必须确认对应的商业授权和合规要求个人学习者不要为了演示效果引入未授权的第三方接口。在校园项目汇报时建议把“技术实现”和“真实商用的资质差异”分开讲。技术评估环节可以展示预约库存、签到核销、订单统计这些核心流程合规评估环节要说明真实运营还需要哪些配套能力。这种表达在答辩和面试里更专业。3. 系统整体设计与核心功能模块从模块边界看健身房管理系统可以分成三个角色系统管理员、教练、会员。实际项目里可以再做扩展比如店长和收银员这里先以最简角色模型来设计。系统管理员负责会员管理、卡种管理、排课管理、订单查看和统计报表。教练可以查看自己的课程安排和已约课会员列表也可以手动标记会员到场。会员通过前台页面或移动端 H5 完成注册、选课和取消预约。前端页面和后端接口都用角色前缀做权限区分是最常见的做法。一套完整的管理系统可以拆成以下几个模块功能模块说明核心对象系统登录用户名密码登录、JWT 签发、角色鉴权User、Role会员管理会员建档、编辑、状态启停、分页查询Member卡种与续费查看卡种、展示有效期、订单新增MemberCard、Orders课程排期新增教练、添加课程、维护课表时间段CourseSchedule预约签到会员约课、取消约课、开课前签到核销Booking、Checkin订单管理会员购卡、续费、退卡记录Orders统计看板会员总量、课消次数、营收趋势Dashboard后端代码建议按模块分包而不是按三层架构平铺成一堆混乱的 Controller、Service、Mapper。推荐结构如下com.gym ├── common │ ├── Result.java │ └── exception ├── config │ ├── CorsConfig.java │ ├── SecurityConfig.java │ └── MybatisPlusConfig.java ├── modules │ ├── auth │ │ ├── controller │ │ └── service │ ├── member │ │ ├── controller │ │ ├── service │ │ ├── mapper │ │ └── entity │ ├── course │ ├── booking │ └── report └── GymApplication.java按模块分包的好处是后续扩展版块不会影响现状。会员模块是一个包课程模块是一个包预约模块又是一个包。某个模块需要发布或改造时影响面可控汇报代码结构时也更清晰。前端项目推荐用 Vite 创建 Vue3 工程目录结构大致如下src ├── api │ ├── request.js │ ├── member.js │ └── course.js ├── router │ └── index.js ├── stores │ └── user.js ├── views │ ├── dashboard │ ├── member │ ├── course │ └── booking └── utils └── auth.js前端 api 目录统一放 axios 请求方法router 目录统一维护路由views 目录按页面模块组织。这样后端加一个会员分页接口时前端只需要在 api/member.js 里添加一个函数然后在页面组件中调用。4. MySQL 数据库设计与核心表脚本数据库设计是健身房管理系统的基础。表结构设计得是否合理直接决定后续接口开发快慢。核心表至少有会员表、课程排期表、预约表、订单表和用户表。下面给出建库脚本和核心表脚本。CREATE DATABASE IF NOT EXISTS gym_management DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci; USE gym_management; CREATE TABLE member ( id BIGINT NOT NULL AUTO_INCREMENT COMMENT 主键, member_no VARCHAR(32) NOT NULL COMMENT 会员编号, name VARCHAR(64) NOT NULL COMMENT 会员姓名, phone VARCHAR(32) NOT NULL COMMENT 手机号, gender TINYINT DEFAULT NULL COMMENT 性别 0未知 1男 2女, level VARCHAR(32) DEFAULT normal COMMENT 会员等级, balance DECIMAL(10,2) DEFAULT 0.00 COMMENT 账户余额, status TINYINT DEFAULT 1 COMMENT 状态 1正常 0停用, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id), UNIQUE KEY uk_member_no (member_no), KEY idx_member_phone (phone) ) ENGINEInnoDB COMMENT会员表;会员表里的手机号要加普通索引因为前台查询会员时最常用的条件就是手机号。会员编号则要加唯一约束避免同一编号被重复创建。余额不做负数限制但在业务逻辑层必须校验扣款是否大于余额。课程排期表用来管理团课和私教课的时间段。这里把课程名、教练、上下课时间、预约容量、已预约人数放在同一张表方便前端做周历课表。CREATE TABLE course_schedule ( id BIGINT NOT NULL AUTO_INCREMENT COMMENT 主键, course_name VARCHAR(128) NOT NULL COMMENT 课程名称, coach_name VARCHAR(64) NOT NULL COMMENT 教练姓名, course_type TINYINT NOT NULL COMMENT 课程类型 1私教 2团操, start_time DATETIME NOT NULL COMMENT 开始时间, end_time DATETIME NOT NULL COMMENT 结束时间, capacity INT DEFAULT 1 COMMENT 预约容量, booked_count INT DEFAULT 0 COMMENT 已预约人数, status TINYINT DEFAULT 1 COMMENT 状态 1正常 0取消, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_course_start_time (start_time), KEY idx_course_type (course_type) ) ENGINEInnoDB COMMENT课程排期表;预约表必须设计成会员与课程排期多对多关系的中间表。预约时先检查 booked_count 是否小于 capacity然后插入预约记录并在同一事务中累加 booked_count避免超售。CREATE TABLE booking ( id BIGINT NOT NULL AUTO_INCREMENT COMMENT 主键, member_id BIGINT NOT NULL COMMENT 会员ID, schedule_id BIGINT NOT NULL COMMENT 课程排期ID, booking_time DATETIME NOT NULL COMMENT 预约时间, status TINYINT DEFAULT 1 COMMENT 状态 1已预约 0已取消 2已签到, remark VARCHAR(255) DEFAULT NULL COMMENT 备注, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_member_schedule (member_id, schedule_id), KEY idx_booking_schedule (schedule_id) ) ENGINEInnoDB COMMENT预约表;订单表建议单独拆分避免每次续费都修改会员卡主表导致的历史记录丢失。新增一条订单流水时写入金额、支付方式、关联会员 ID、订单状态再更新会员的有效期或余额。两张表的更新要放在同一事务中。CREATE TABLE orders ( id BIGINT NOT NULL AUTO_INCREMENT COMMENT 主键, order_no VARCHAR(64) NOT NULL COMMENT 订单编号, member_id BIGINT NOT NULL COMMENT 会员ID, order_type TINYINT NOT NULL COMMENT 订单类型 1购卡 2续费 3退款, amount DECIMAL(10,2) NOT NULL COMMENT 订单金额, pay_method VARCHAR(32) DEFAULT NULL COMMENT 支付方式, status TINYINT DEFAULT 0 COMMENT 状态 0待处理 1成功 2失败, remark VARCHAR(255) DEFAULT NULL COMMENT 备注, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_order_no (order_no), KEY idx_order_member (member_id) ) ENGINEInnoDB COMMENT订单表;设计建议第一不要滥用物理外键代码层管理数据关系更适合高并发扩展第二所有时间字段都使用 DATETIMEJava 侧统一传输 yyyy-MM-dd HH:mm:ss 字符串或使用 Jackson 配置第三状态字段用 TINYINT 并用常量或枚举语义化尽量不裸用魔法数字第四姓名、手机号这类高频检索字段必须设计索引DELETE 操作尽量改成逻辑删除。MySQL 字符集使用 utf8mb4连接串里也要带上 characterEncodingutf8避免前后端传中文时出现乱码。5. 环境准备与 SpringBoot3 后端启动后端启动前先确认本机环境。在命令行依次执行版本检查命令java -version mvn -v mysql --versionSpringBoot3 最低要求 JDK17这一点特别重要。如果你的电脑还停留在 JDK8直接运行项目会报 UnsupportedClassVersionError。建议安装 JDK17 或 JDK21并配置好 JAVA_HOME。创建数据库后在 resources 目录下新增 application.yml 配置文件。以本地开发环境为例连接参数如下server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/gym_management?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue username: root password: root hikari: maximum-pool-size: 10 minimum-idle: 2 connection-timeout: 30000 jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: Asia/Shanghai mybatis-plus: configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0SpringBoot3 项目如果要集成 MyBatis-Plus需要选择支持 SpringBoot3 的版本比如 mybatis-plus-spring-boot3-starter 3.5.x。因为 SpringBoot3 使用了 Jakarta EE 规范旧版 starter 里的 javax 包会冲突。pom.xml 核心依赖可以参考下面这份配置parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.2.5/version relativePath/ /parent properties java.version17/java.version /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-spring-boot3-starter/artifactId version3.5.7/version /dependency dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency /dependencies如果你的项目需要登录鉴权可以继续引入 spring-boot-starter-security也可以临时用拦截器做简单鉴权。建议先跑通会员模块再叠加安全控制避免一开始就陷入复杂的过滤器链问题。下面是一段会员分页查询的 Controller 示例展示 SpringBoot3 后端的接口写法。package com.gym.modules.member.controller; import com.gym.common.Result; import com.gym.modules.member.entity.Member; import com.gym.modules.member.service.MemberService; import jakarta.annotation.Resource; import org.springframework.web.bind.annotation.*; import java.util.List; RestController RequestMapping(/api/member) public class MemberController { Resource private MemberService memberService; GetMapping(/page) public ResultListMember page(RequestParam(defaultValue 1) Integer pageNum, RequestParam(defaultValue 20) Integer pageSize, RequestParam(required false) String keyword) { return Result.success(memberService.pageMembers(pageNum, pageSize, keyword)); } PostMapping public ResultMember create(RequestBody Member member) { memberService.createMember(member); return Result.success(member); } }Controller 只是接口入口不要把业务逻辑写在这里。新建会员时要判断手机号是否重复、生成会员编号、初始状态是否开启等这些操作都放在 Service 层。如果一个接口涉及订单表和会员表多次更新必须在 Service 层加事务注解。在项目根目录启动后端服务可以执行mvn spring-boot:run也可以先打包再运行 jar 包mvn clean package java -jar target/gym-admin-0.0.1-SNAPSHOT.jar启动成功的标志是控制台出现 Tomcat started on port 8080浏览器访问健康检查或接口地址不再连接拒绝。如果 8080 被其他进程占用可以修改 application.yml 里的 server.port或使用 8081、9090 等端口。6. Vue3 前端启动与前后端联调前端使用 Vue3 Vite 搭建。开始前检查 Node.js 环境node -v npm -vVite 5 需要 Node.js 18 或更高版本所以本地 Node 版本不要太老。项目如果自带 package.json直接在目录执行 npm install 安装依赖。由于国内网络环境不稳定推荐配置 npm 镜像npm config set registry https://registry.npmmirror.com npm install前端开发服务器的默认端口是 5173。要让页面请求访问到后端 8080最简单的方式是在 vite.config.js 中设置开发代理。import { defineConfig } from vite import vue from vitejs/plugin-vue export default defineConfig({ plugins: [vue()], server: { host: 127.0.0.1, port: 5173, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } })这样前端请求 /api/member/list 时由 Vite 开发服务器转发到 http://localhost:8080/api/member/list。后端不需要额外处理跨域开发阶段就可以正常联调。推荐把 axios 请求统一封装到 request.js 中并注入 JWT Token。示例代码如下import axios from axios const request axios.create({ baseURL: /api, timeout: 10000 }) request.interceptors.request.use(config { const token localStorage.getItem(gym_token) if (token) { config.headers.Authorization Bearer ${token} } return config }) request.interceptors.response.use( response { const res response.data return res }, error { console.error(接口请求失败, error) return Promise.reject(error) } ) export default request会员模块的 API 方法可以单独放在 api/member.js 中import request from /utils/request export function getMemberPage(params) { return request({ url: /member/page, method: get, params }) } export function addMember(data) { return request({ url: /member, method: post, data }) }前端启动命令npm run dev启动后访问 http://localhost:5173如果页面能显示登录页或后台首页说明前端工程正常。在这之后不要急着做样式先完成后端接口联调。联调时最容易出三类问题第一类是接口路径不一致前端请求 /member/page后端实际的 RequestMapping(/api/member) 却配了 /list第二类是参数类型不一致后端用 Long 接收 id前端传的是字符串第三类是跨域和代理问题代理配置改了但 Node 服务没有重启。遇到这三个情况直接看浏览器 Network 面板里的请求地址、状态码和响应体比反复刷新页面更快定位。7. 接口 API 调试与批量任务处理后端服务起来之后可以用 Postman、Apifox 或直接 curl 验证接口。如果配置了 Swagger 或 Knife4j启动后访问对应文档页面可以免去手写请求参数。假设系统设计了一个登录接口约定地址为 /api/auth/login请求体里包含用户名和密码。实际调用时请按自己后端 Controller 的 RequestMapping 为准。下面是 curl 调用模板curl -X POST http://localhost:8080/api/auth/login \ -H Content-Type: application/json \ -d {username:admin,password:123456}如果登录校验通过后端通常会返回一段 token前端之后访问业务接口时在请求头携带 Authorization。curl -X GET http://localhost:8080/api/member/page?pageNum1pageSize10 \ -H Authorization: Bearer 你的tokenPython 调试接口也很方便。批量导入会员时可以先在后端实现一个单条新增会员接口然后使用 Python 读取 Excel 批量调用。import requests base_url http://localhost:8080 token 改成登录接口返回的token headers { Authorization: fBearer {token} } payload { name: 张三, phone: 13800000000, gender: 1 } response requests.post( f{base_url}/api/member, jsonpayload, headersheaders, timeout10 ) print(response.status_code) print(response.json())批量导入场景需要在数据量变大后考虑幂等性。同一个 Excel 文件被重复导入时不能因为网络超时就在会员表里生成两条重复记录。因此批量导入前建议先按手机号查询会员是否存在如果存在则跳过或更新不存在才插入。每导入一条记录打印一条日志结束时再输出成功和失败数量。import openpyxl import requests wb openpyxl.load_workbook(members.xlsx) ws wb.active base_url http://localhost:8080 token 改成登录接口返回的token headers {Authorization: fBearer {token}} success 0 fail 0 for row in ws.iter_rows(min_row2, values_onlyTrue): payload { name: row[0], phone: row[1], gender: row[2] } response requests.post( f{base_url}/api/member, jsonpayload, headersheaders, timeout10 ) result response.json() if result.get(code) 200: success 1 else: fail 1 print(f导入失败: {payload}, {result}) print(f导入结束成功 {success} 条失败 {fail} 条)除了手动导入后端也可以使用 Spring 定时任务完成批量操作。比如每天凌晨清理已过期且未续费的会员卡或者定时把预约状态从“已预约”更新为“已失效”。给定时任务方法添加 Scheduled 注解并在启动类上增加 EnableScheduling 即可。这类定时任务必须加上方法日志和异常捕获防止一次数据库抖动导致后续任务不再执行。8. 资源占用与性能观察方法健身房管理系统虽然没有大模型的显存压力但作为 Java Web 项目同样需要关注 JVM 内存、MySQL 连接池和前端构建资源。运行时可以先确定配置参数再做观察和调优不要在“能打开页面”和“运行健康”之间画等号。定期处理预约签到、订单统计等操作时如果用户量上涨容易出现两类问题一类是 MySQL 连接池不够用连接等待超时另一类是慢 SQL 拖慢接口响应。默认情况下HikariCP 连接池最大连接数是 10如果系统并发不高够用如果要做压测可以适当调高 maximum-pool-size但后台数据库也要同步放开最大连接数上限。观察 Java 进程资源最基础的方法是查看进程 PID 和 JVM 内存占用jps -l jcmd pid GC.heap_info jstat -gc pid 5000先用 jps -l 找到 jar 包对应的 Java 进程再用 jstat 每秒或每 5 秒打印一次 GC 情况。如果 Full GC 频繁说明堆内存偏小或项目存在内存泄漏如果是大批量导入 Excel 时发生内存上涨建议限制单批导入条数分批次提交。SpringBoot 服务启动时如果需要限制内存可以在运行 jar 包时加上 JVM 参数java -Xms512m -Xmx1024m -jar target/gym-admin-0.0.1-SNAPSHOT.jar开发机上用 512MB 到 1GB 堆内存运行即可生产环境建议先压测再决定堆大小不要盲目分配过大内存导致本机资源耗尽。前端资源方面npm install 阶段主要占用的是磁盘和网络npm run dev 启动后内存占用会随项目体积上升。如果项目启动很慢可以先去掉暂时不需要的路由懒加载如果热更新卡顿建议关闭部分大文件依赖或使用 chunk 拆包。前端编译打包时同样要关注内存Node.js 默认堆大小有限遇到“JavaScript heap out of memory”可以设置 NODE_OPTIONS 后再构建export NODE_OPTIONS--max-old-space-size2048 npm run build后端最容易拖慢性能的是 N1 查询。会员分页接口如果先查会员列表再循环查询每个会员的卡订单接口响应会随页大小线性变慢。优化方式是使用 MyBatis-Plus 联表查询或批量查询必要时在 Mapper XML 中写固定 SQL只查当前页需要的记录。接口层建议统一响应结构例如完整响应字段为 code、message、data。封装成 Result 类之后全局异常处理器可以返回一致格式前端拦截器能够根据 code 判断业务成功或失败。返回结构保持一致也方便后续接入网关、日志采集和监控链路。9. 常见问题排查清单根据我接触过的同类管理项目经验启动和联调阶段最容易踩的坑往往是环境问题而不是业务代码问题。下面整理一份排查清单遇到故障时逐项对照。问题现象可能原因排查方式解决方案后端启动报 UnsupportedClassVersionErrorJDK 版本过低SpringBoot3 需要 JDK17java -version安装 JDK17 或更高版本Java 进程启动后立即退出端口被占用或数据库配置错误查看控制台日志最后 20 行释放端口/修改 application.yml报 Communications link failureMySQL 没有启动或连接地址错误测试本机 mysql 命令行连接启动 MySQL修改 url 连接串报 Public Key Retrieval is not allowed客户端连接 MySQL 时未允许获取公钥查看异常信息url 增加 allowPublicKeyRetrievaltrue报 Access denied for user root数据库账号密码错误用 mysql -u root -p 测试修改 application.yml 中的 username/password前端页面能开但请求 404后端接口路径不匹配打开浏览器 Network 面板看请求地址按后端 Controller 的 RequestMapping 调整前端报跨域错误没有配 Vite 代理或后端 CORS 没配检查浏览器 Console 网络状态在 vite.config.js 配 proxy或后端配置 CORSnpm install 报 ERESOLVE unable to resolve dependency tree依赖版本冲突查看 npm 错误信息使用 npm install --legacy-peer-deps 或同步依赖版本MyBatis-Plus 报 Invalid bound statementMapper 接口或 XML 映射读取不到检查启动类 MapperScan、XML namespace配置 MapperScan检查 XML location中文存入数据库变成乱码数据库字符集或连接字符集不一致执行 show variables like character_set%将库表改为 utf8mb4url 增加 characterEncodingutf8会员预约出现超卖没有做库存校验和事务控制查看约课接口日志预约时先判断容量再在同事务里更新 booked_count批量导入重复数据缺少幂等控制查询导入日志按照手机号或会员编号先查重再插入端口占用是出现频率很高的问题。SpringBoot 默认端口是 8080前端 Vite 默认端口是 5173。本机如果同时开启了其他 Java 服务或 Node 服务就可能冲突。Windows 下查看端口占用可以使用netstat -ano | findstr 8080查到占用端口的 PID 后先到任务管理器确认进程身份别盲目结束系统进程。Linux 和 macOS 下可以使用lsof -i :8080如果只是收到端口被占用但不清楚进程来源优先修改项目端口而不是强杀进程。还有一个常见问题是本地数据库密码与配置文件不一致。很多人重装 MySQL 后root 密码与代码中旧密码不一致导致接口全部连不上。更稳妥的做法是在配置中心或环境变量中读取数据库密码而不是把密码写死在代码里至少也要保证 application.yml 使用 .gitignore 排除再提交。10. 最佳实践与使用建议项目可以跑通只是第一步更高标准是把一套代码组织得结构清楚、可维护、可演示。下面的建议来自实际开发习惯建议在写健身房管理系统时直接套用。第一数据库脚本独立保存放在项目根目录的 sql 目录下并写明版本号或初始化日期。不要只靠手工建表否则换一台电脑时会非常痛苦。建议脚本包含建库、建表、基础数据插入三部分后端项目启动前可以直接导入。第二安全相关的设计要放在模块边界做而不是每个 Controller 里都写密码判断。密码不要明文存储使用 BCryptPasswordEncoder 加密。后端项目接口不能全部匿名访问至少把会员新增、订单删除、统计分析等管理端接口保护起来。第三前端和后端的传参命名尽量统一。Java 项目习惯使用驼峰命名MySQL 表字段使用下划线命名MyBatis-Plus 开启 map-underscore-to-camel-case 后可以自动映射。这样前端传 memberName后端实体用 memberNameJSON 输出也保持一致不会出现一会儿 member_name 一会儿 memberName 的情况。第四批量操作必须留日志和失败重试机制。Excel 导入会员时不要只弹出一个“导入成功”的提示至少要记录导入总数、成功数、失败数并给出失败原因比如“手机号已存在”“姓名为空”。如果是夜间定时任务还需要把执行结果写入任务日志表或控制台日志文件。第五涉及真实会员和订单数据时遵循最小权限原则。开发环境只用测试数据数据库账号不要给 root生产环境单独建立只读和可写账号。凡是保存手机号、年龄、身体数据的表尽可能做加密或脱敏处理。个人项目里加入人脸识别、采集身份证信息等功能要非常谨慎没有明确授权不要引入真实数据。第六不要把前端构建产物和 node_modules 提交到代码仓库。项目根目录要写好 .gitignore把 target、node_modules、dist、*.log、application-local.yml 这类文件排除掉。换一台电脑时只需要 clone 源码再重新执行 npm install 和 mvn clean package。第七提供一套可复现的启动文档。README 里写清楚环境版本、数据库导入方式、后端启动命令、前端启动命令和默认账号。这样到答辩或者面试演示时不需要临时在电脑上重新排查环境也降低项目交付时的沟通成本。如果你第一次跑 SpringBoot3 Vue3 全栈项目建议顺序是先启动 MySQL 并导入 SQL再启动后端接口用 curl 或 Swagger 调通会员分页和会员新增两个接口确定后端无误后再启动前端。不要同时开着多个终端反复改环境一次变量控制在最少的范围能大幅降低排查难度。从技术复盘角度看健身房管理系统本身不是一个“高算法难度”项目它的难点在于业务状态多、实体关系多、接口约定多。把会员状态、预约状态、订单状态这些枚举在设计阶段先梳理清楚后续的开发和剪裁都会顺畅很多。本文这套路由大致覆盖了从 Java 后端到 Vue3 前端、从 MySQL 表设计到接口调试的完整流程建议收藏备用下次接到类似管理系统需求时可以直接照着搭。
返回列表