可研
随着移动互联网的普及和全民健身意识的提升,传统健身房的运营模式面临着数字化转型的需求。本文设计并实现了一款基于微信小程序和Spring Boot后端架构的健身房服务小程序。该系统旨在为会员提供便捷的课程预约、场地预订、资讯浏览及个人信息管理服务,同时为健身房管理者提供高效的内容维护、预约核销、用户管理及数据统计功能。系统采用前后端分离架构,前端使用微信小程序原生开发,后端基于Java Spring Boot框架,数据库选用MySQL 8.0+。测试结果表明,该系统有效提升了健身房的运营效率和会员的服务体验,实现了线上线下服务的闭环管理。
系统需求分析
栏目浏览模块
- 小店动态:查看门店活动、促销套餐、课程更新等信息。
- 健身干货:浏览训练技巧、动作教学、增肌减脂等专业知识。
- 饮食科普:获取健身餐搭配、营养补充建议。
- 荣誉资质:查看场馆资质、教练团队及荣誉评价。
- 交互功能:支持详情查看、微信分享、关键词检索。
用户注册模块
- 首次使用需填写年龄、姓名、车辆情况等基本信息。
- 绑定微信账号,实现“一键登录”。
服务预约模块
- 预约类型:私教预约、团课预约(瑜伽、动感单车等)、场地预约(拳击台、拉伸区)。
- 预约展示:直观显示可预约时段及剩余名额。
- 到店核销:生成核销二维码,管理员扫码确认到店。
个人中心模块
- 我的预约:查看所有预约记录(已完成/进行中/已取消),支持取消操作。
- 资料修改:更新联系方式、健身目标等个人信息。
- 浏览历史:记录并回顾浏览过的内容。
- 我的收藏:收藏感兴趣的课程或文章。

总体设计
本系统采用前后端分离的开发模式,具体技术栈如下:
- 前端:微信小程序(Native开发),使用微信开发者工具。
- 后端:Java Spring Boot框架,提供RESTful API接口。
- 数据库:MySQL 8.0+,存储业务数据。
开发工具:
- IDE:IntelliJ IDEA (2023.2.1+)
- 数据库管理:Navicat 16+
- 小程序开发:微信开发者工具
系统架构设计
- 表现层:微信小程序负责页面渲染和用户交互,后台管理端嵌入小程序中,通过权限控制访问。
- 业务逻辑层:Spring Boot处理核心业务逻辑,如预约规则校验、核销状态更新、数据统计等。
- 数据访问层:通过MyBatis框架操作MySQL数据库,实现数据的持久化存储。
数据库设计
| 字段名 | 类型 | 长度 | 约束 | 说明 |
|---|
| id | BIGINT | 20 | PK, AI | 主键ID |
| openid | VARCHAR | 64 | NOT NULL, UNIQUE | 微信OpenID |
| name | VARCHAR | 50 | | 姓名 |
| age | INT | 3 | | 年龄 |
| phone | VARCHAR | 20 | | 联系电话 |
| vehicle_info | VARCHAR | 100 | | 车辆情况 |
| fitness_goal | VARCHAR | 255 | | 健身目标 |
| create_time | DATETIME | | | 注册时间 |
| status | TINYINT | 1 | DEFAULT 1 | 状态(1正常 0禁用) |
| 字段名 | 类型 | 长度 | 约束 | 说明 |
|---|
| id | BIGINT | 20 | PK, AI | 主键ID |
| name | VARCHAR | 100 | NOT NULL | 项目名称 |
| type | TINYINT | 1 | NOT NULL | 类型(1私教 2团课 3场地) |
| description | TEXT | | | 项目描述 |
| max_capacity | INT | | | 最大容纳人数 |
| sort_order | INT | | DEFAULT 0 | 排序权重 |
| is_available | TINYINT | 1 | DEFAULT 1 | 是否可用 |
| rule_desc | VARCHAR | 500 | | 预约规则说明 |
| 字段名 | 类型 | 长度 | 约束 | 说明 |
|---|
| id | BIGINT | 20 | PK, AI | 主键ID |
| user_id | BIGINT | 20 | FK | 用户ID |
| project_id | BIGINT | 20 | FK | 项目ID |
| reserve_date | DATE | | NOT NULL | 预约日期 |
| time_slot | VARCHAR | 50 | NOT NULL | 预约时段 |
| verify_code | VARCHAR | 64 | UNIQUE | 核销二维码字符串 |
| status | TINYINT | 1 | DEFAULT 0 | 状态(0待核销 1已完成 2已取消) |
| create_time | DATETIME | | | 创建时间 |
| verify_time | DATETIME | | | 核销时间 |
| 字段名 | 类型 | 长度 | 约束 | 说明 |
|---|
| id | BIGINT | 20 | PK, AI | 主键ID |
| category | TINYINT | 1 | NOT NULL | 分类(1动态 2干货 3饮食 4荣誉) |
| title | VARCHAR | 200 | NOT NULL | 标题 |
| content | LONGTEXT | | | 正文内容(支持HTML) |
| cover_image | VARCHAR | 255 | | 封面图URL |
| view_count | INT | | DEFAULT 0 | 浏览量 |
| publish_time | DATETIME | | | 发布时间 |
| 字段名 | 类型 | 长度 | 约束 | 说明 |
|---|
| id | BIGINT | 20 | PK, AI | 主键ID |
| username | VARCHAR | 50 | NOT NULL, UNIQUE | 用户名 |
| password | VARCHAR | 100 | NOT NULL | 加密密码 |
| role | TINYINT | 1 | NOT NULL | 角色(1超级管理员 2普通管理员 3核销员) |
| status | TINYINT | 1 | DEFAULT 1 | 状态 |
| last_login | DATETIME | | | 最后登录时间 |
核心代码
@RestController
@RequestMapping("/api/reservation")
public class ReservationController {
@Autowired
private ReservationService reservationService;
@PostMapping("/create")
public Result create(@RequestBody ReservationDTO dto, HttpServletRequest request) {
Long userId = UserContext.getCurrentUserId(request);
return reservationService.createReservation(userId, dto.getProjectId(), dto.getDate(), dto.getTimeSlot());
}
@PostMapping("/verify")
public Result verify(@RequestParam String code, HttpServletRequest request) {
Long adminId = AdminContext.getCurrentAdminId(request);
return reservationService.verifyReservation(code, adminId);
}
}
@Service
public class ReservationService {
@Autowired
private ReservationMapper reservationMapper;
@Autowired
private ProjectMapper projectMapper;
@Transactional(rollbackFor = Exception.class)
public Result createReservation(Long userId, Long projectId, String date, String timeSlot) {
Project project = projectMapper.selectById(projectId);
if (project == null || project.getIsAvailable() == 0) {
return Result.error("该项目不可预约");
}
int bookedCount = reservationMapper.countByProjectAndSlot(projectId, date, timeSlot);
if (bookedCount >= project.getMaxCapacity()) {
return Result.error("该时段名额已满");
}
String verifyCode = UUID.randomUUID().toString().replace("-", "");
Reservation reservation = new Reservation();
reservation.setUserId(userId);
reservation.setProjectId(projectId);
reservation.setReserveDate(DateUtil.parse(date));
reservation.setTimeSlot(timeSlot);
reservation.setVerifyCode(verifyCode);
reservation.setStatus(0);
reservationMapper.insert(reservation);
return Result.success("预约成功", verifyCode);
}
public Result verifyReservation(String verifyCode, Long adminId) {
Reservation reservation = reservationMapper.selectByVerifyCode(verifyCode);
if (reservation == null) {
return Result.error("无效的核销码");
}
if (reservation.getStatus() != 0) {
return Result.error("该预约已" + (reservation.getStatus() == 1 ? "完成" : "取消"));
}
reservation.setStatus(1);
reservation.setVerifyTime(new Date());
reservationMapper.updateById(reservation);
return Result.success("核销成功");
}
}
UI设计


后台管理系统设计

Git代码
点击下载