毕业设计实战:基于SpringBoot的健身俱乐部网站设计与实现全攻略

0 阅读13分钟

毕业设计实战:基于SpringBoot的健身俱乐部网站设计与实现全攻略

在开发“基于SpringBoot的健身俱乐部网站”毕业设计时,曾因“课程预约与器材借用状态混乱”踩过关键坑——初期未设计清晰的预约状态机和器材借用联动机制,导致用户预约课程后教练端未收到通知、器材借用申请审核通过后库存未同步扣减、办卡信息与训练计划数据脱节,耗费4天重构预约管理模块、引入状态流转和库存联动机制才解决问题📝。基于此次实战经验,本文精简拆解核心开发流程,附避坑要点与实操细节,为同类毕设提供可落地的实施参考。

一、需求分析:聚焦课程+器材双核心,避免功能冗余

部分同学易陷入“功能堆砌”误区,比如我曾耗时3天开发“健身地图导航”模块,最终因偏离“健身课程、健身器材、会员卡办理、训练计划”核心需求被导师要求删减。明确“课程发布→用户预约→教练确认→器材借用→会员办卡→训练计划”的业务闭环,是降低返工率的关键。

1. 核心角色与功能(精简版)

角色核心功能
管理员用户管理、教练管理、健身课程管理、课程预约管理、健身器材管理、器材借用管理、会员卡信息管理、办卡信息管理、训练计划管理、教室信息管理、在线留言管理、系统管理
教练课程预约查看、训练计划管理、个人中心
用户健身课程浏览/预约/评论/收藏、健身器材浏览/借用/评论、会员卡浏览/办理、训练计划查看、在线留言、个人中心

2. 需求避坑要点

  • 拒绝空想调研:邀请12名健身爱好者和5名健身教练模拟“用户浏览课程→预约课程→教练确认→用户借用器材→办理会员卡→查看训练计划”完整流程,基于“用户需要知道预约进度和器材库存”需求,增设“预约状态跟踪”和“器材库存预警”模块,实用性远大于冗余的“健身地图”;
  • 明确约束条件:提前规定“预约编号自动生成(格式:YY+年月日+序号)”“课程预约需教练确认”“器材借用审核通过后扣减库存”“会员卡办理需审核后生效”,为系统实现提供明确依据。

二、技术选型:稳定框架+预约联动,新手可上手

前期曾尝试引入Redis缓存课程热度,因数据一致性难保证且学习成本高,调试耗时3天。最终确定“成熟框架+数据库事务”组合:

技术工具选型理由避坑提醒
Spring Boot 2.x + MyBatis-Plus快速开发,简化配置,高效实现CRUD和业务逻辑,声明式事务管理方便事务注解@Transactional记得在Service层添加;课程预约和器材借用必须加事务
Vue 2.x + ElementUI组件丰富,快速构建前后台界面,表格和表单组件好用预约状态用标签展示;器材库存用颜色标识
MySQL 5.7存储用户、教练、课程、器材、会员卡等核心业务数据金额字段用Decimal类型;事务要保证预约和器材库存一致性
Thymeleaf(可选)服务端模板引擎,适合快速开发后台管理界面毕设时间充裕可统一用Vue

三、数据库设计:业务关联清晰,支撑课程-器材-会员闭环

数据库设计直接影响后续开发效率。前期因未设计“预约状态字段”和“器材库存联动机制”,导致用户预约课程后教练未收到通知、器材借用后库存未更新。

1. 核心表结构(精选12张表)

  • 管理员表(users):id、username、password(MD5加密)、role、addtime;
  • 用户表(yonghu):id、zhanghao(账号)、mima(密码)、xingming(姓名)、xingbie(性别)、nianling(年龄)、shouji(手机)、touxiang(头像)、addtime;
  • 教练表(jiaolian):id、jiaolianzhanghao(教练账号)、mima(密码)、jiaolianxingming(教练姓名)、xingbie(性别)、nianling(年龄)、shouji(手机)、touxiang(头像)、addtime;
  • 健身课程表(jianshenkecheng):id、kechengmingcheng(课程名称)、kechengleixing(课程类型)、shangkedidian(上课地点)、kechengjiage(课程价格)、kechengjieshao(课程介绍)、kechengtupian(课程图片)、jiaolianzhanghao(教练账号)、jiaolianxingming(教练姓名)、clicktime、clicknum、addtime;
  • 课程预约表(kechengyuyue):id、kechengmingcheng(课程名称)、kechengleixing(课程类型)、kechengjiage(课程价格)、yuyueshijian(预约时间)、yuyueshuoming(预约说明)、jiaolianzhanghao(教练账号)、jiaolianxingming(教练姓名)、zhanghao(用户账号)、xingming(用户姓名)、sfsh(审核状态)、shhf(审核回复)、ispay(支付状态)、addtime;
  • 健身器材表(jianshenqicai):id、qicaimingcheng(器材名称)、qicaileixing(器材类型)、guige(规格)、shuliang(数量)、qicaiweizhi(器材位置)、qicaijieshao(器材介绍)、qicaitupian(器材图片)、addtime;
  • 器材借用表(qicaijieyong):id、qicaimingcheng(器材名称)、qicaileixing(器材类型)、guige(规格)、shuliang(借用数量)、jieyongshijian(借用时间)、beizhu(备注)、zhanghao(用户账号)、xingming(用户姓名)、sfsh(审核状态)、shhf(审核回复)、addtime;
  • 会员卡信息表(huiyuankaxinxi):id、huiyuankamingcheng(会员卡名称)、huiyuankaleixing(会员卡类型)、huiyuankaqixian(会员卡期限)、banlijiage(办理价格)、huiyuankajieshao(会员卡介绍)、huiyuankatupian(会员卡图片)、addtime;
  • 办卡信息表(bankaxinxi):id、huiyuankamingcheng(会员卡名称)、huiyuankaleixing(会员卡类型)、huiyuankaqixian(会员卡期限)、banlijiage(办理价格)、bankashijian(办卡时间)、bankashuoming(办卡说明)、zhanghao(用户账号)、xingming(用户姓名)、sfsh(审核状态)、shhf(审核回复)、ispay(支付状态)、addtime;
  • 训练计划表(xunlianjihua):id、kechengmingcheng(课程名称)、kechengleixing(课程类型)、kaishishijian(开始时间)、jieshushijian(结束时间)、xunlianneirong(训练内容)、zhanghao(用户账号)、xingming(用户姓名)、jiaolianzhanghao(教练账号)、jiaolianxingming(教练姓名)、addtime;
  • 教室信息表(jiaoshixinxi):id、jiaoshimingcheng(教室名称)、jiaoshiweizhi(教室位置)、jiaoshizhuangtai(教室状态)、jiaoshishebei(教室设备)、addtime;
  • 在线留言表(zaixianliuyan):id、userid、username、avatarurl、content、cpicture、reply、rpicture、addtime。

2. 关键业务SQL示例

示例SQL(查询用户课程预约及器材借用记录):

-- 查询用户的课程预约和器材借用记录
SELECT 
    y.*,
    j.qicaimingcheng,
    j.shuliang as jieyong_num,
    j.sfsh as jieyong_status
FROM kechengyuyue y
LEFT JOIN qicaijieyong j ON y.zhanghao = j.zhanghao
WHERE y.zhanghao = #{zhanghao}
ORDER BY y.addtime DESC

关键避坑:课程预约需关联教练和用户;器材借用审核通过后需扣减库存;办卡信息需关联会员卡信息。

四、核心功能实现:8大模块满足答辩需求

无需复杂功能,优先完成以下8个核心模块,其中课程预约与器材借用联动是答辩重点。

1. 用户/教练管理(人员模块)

  • 核心逻辑:管理员管理用户和教练信息(账号、姓名、联系方式等);
  • 页面设计:用户列表显示账号、姓名、性别、年龄、手机;教练列表显示教练账号、姓名、手机;
  • 代码要点(用户注册):
public void addYonghu(Yonghu user) {
    // 校验账号是否重复
    LambdaQueryWrapper<Yonghu> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(Yonghu::getZhanghao, user.getZhanghao());
    if (yonghuMapper.selectCount(wrapper) > 0) {
        throw new RuntimeException("账号已存在");
    }
    user.setAddtime(new Date());
    yonghuMapper.insert(user);
}

2. 健身课程管理(核心资源模块)

  • 核心逻辑:教练/管理员发布健身课程(名称、类型、地点、价格、介绍、图片)→用户浏览、预约、评论、收藏;
  • 页面设计:课程卡片式展示,显示名称、类型、地点、价格、教练;详情页展示完整介绍;
  • 代码要点(课程发布与热度更新):
@Transactional
public void addJianshenkecheng(Jianshenkecheng kecheng) {
    kecheng.setClicknum(0);
    kecheng.setAddtime(new Date());
    jianshenkechengMapper.insert(kecheng);
    
    log.info("教练 {} 发布了课程 {}", kecheng.getJiaolianxingming(), kecheng.getKechengmingcheng());
}

// 课程点击量更新
public void updateClickNum(Long courseId) {
    Jianshenkecheng course = jianshenkechengMapper.selectById(courseId);
    course.setClicknum(course.getClicknum() + 1);
    course.setClicktime(new Date());
    jianshenkechengMapper.updateById(course);
}

3. 课程预约管理(核心业务流程)

  • 核心逻辑:用户预约课程→填写预约说明→教练审核→审核通过后支付→形成预约记录;
  • 页面设计:预约列表显示课程名称、预约时间、审核状态、支付状态;审核弹窗带意见输入;
  • 代码要点(课程预约与审核):
@Transactional
public void addKechengyuyue(Kechengyuyue yuyue) {
    // 1. 校验是否已预约
    LambdaQueryWrapper<Kechengyuyue> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(Kechengyuyue::getKechengmingcheng, yuyue.getKechengmingcheng())
           .eq(Kechengyuyue::getZhanghao, yuyue.getZhanghao());
    if (kechengyuyueMapper.selectCount(wrapper) > 0) {
        throw new RuntimeException("您已预约过该课程");
    }
    
    yuyue.setSfsh("待审核");
    yuyue.setIspay("未支付");
    yuyue.setYuyueshijian(new Date());
    yuyue.setAddtime(new Date());
    kechengyuyueMapper.insert(yuyue);
    
    log.info("用户 {} 预约了课程 {}", yuyue.getXingming(), yuyue.getKechengmingcheng());
}

// 预约审核
@Transactional
public void auditYuyue(Long yuyueId, Integer status, String reply) {
    Kechengyuyue yuyue = kechengyuyueMapper.selectById(yuyueId);
    yuyue.setSfsh(status == 1 ? "通过" : "拒绝");
    yuyue.setShhf(reply);
    kechengyuyueMapper.updateById(yuyue);
    
    if (status == 1) {
        log.info("用户 {} 预约课程 {} 已通过", yuyue.getXingming(), yuyue.getKechengmingcheng());
    }
}

// 预约支付
@Transactional
public void payYuyue(Long yuyueId) {
    Kechengyuyue yuyue = kechengyuyueMapper.selectById(yuyueId);
    yuyue.setIspay("已支付");
    kechengyuyueMapper.updateById(yuyue);
    
    log.info("预约 {} 支付成功", yuyueId);
}

4. 健身器材管理(资源管理模块)

  • 核心逻辑:管理员维护健身器材信息(名称、类型、规格、数量、位置)→用户浏览、借用;
  • 页面设计:器材列表显示名称、类型、规格、数量、位置;库存不足时红色标识;
  • 代码要点(器材库存管理):
public void addJianshenqicai(Jianshenqicai qicai) {
    qicai.setAddtime(new Date());
    jianshenqicaiMapper.insert(qicai);
}

// 器材借用时扣减库存
@Transactional
public void reduceStock(String qicaimingcheng, int num) {
    Jianshenqicai qicai = jianshenqicaiMapper.selectOne(
        new LambdaQueryWrapper<Jianshenqicai>()
            .eq(Jianshenqicai::getQicaimingcheng, qicaimingcheng)
    );
    if (qicai.getShuliang() < num) {
        throw new RuntimeException("器材库存不足");
    }
    qicai.setShuliang(qicai.getShuliang() - num);
    jianshenqicaiMapper.updateById(qicai);
}

5. 器材借用管理(借用流程模块)

  • 核心逻辑:用户申请借用器材→填写借用数量、时间、备注→管理员审核→审核通过后扣减库存;
  • 页面设计:借用列表显示器材名称、借用数量、借用时间、审核状态;
  • 代码要点(器材借用与库存联动):
@Transactional
public void addQicaijieyong(Qicaijieyong jieyong) {
    // 校验库存
    Jianshenqicai qicai = jianshenqicaiMapper.selectOne(
        new LambdaQueryWrapper<Jianshenqicai>()
            .eq(Jianshenqicai::getQicaimingcheng, jieyong.getQicaimingcheng())
    );
    if (qicai == null || qicai.getShuliang() < jieyong.getShuliang()) {
        throw new RuntimeException("器材库存不足");
    }
    
    jieyong.setSfsh("待审核");
    jieyong.setJieyongshijian(new Date());
    jieyong.setAddtime(new Date());
    qicaijieyongMapper.insert(jieyong);
    
    log.info("用户 {} 申请借用器材 {}", jieyong.getXingming(), jieyong.getQicaimingcheng());
}

// 借用审核通过时扣减库存
@Transactional
public void auditJieyong(Long jieyongId, Integer status, String reply) {
    Qicaijieyong jieyong = qicaijieyongMapper.selectById(jieyongId);
    jieyong.setSfsh(status == 1 ? "通过" : "拒绝");
    jieyong.setShhf(reply);
    qicaijieyongMapper.updateById(jieyong);
    
    if (status == 1) {
        // 扣减器材库存
        reduceStock(jieyong.getQicaimingcheng(), jieyong.getShuliang());
        log.info("器材借用 {} 审核通过,库存已扣减", jieyongId);
    }
}

6. 会员卡信息管理(营销模块)

  • 核心逻辑:管理员发布会员卡信息(名称、类型、期限、价格、介绍)→用户浏览、申请办卡;
  • 页面设计:会员卡卡片式展示,显示名称、类型、期限、价格;详情页展示完整介绍;
  • 代码要点:会员卡信息支持增删改查。

7. 办卡信息管理(会员转化模块)

  • 核心逻辑:用户申请办理会员卡→填写办卡说明→管理员审核→审核通过后支付→成为会员;
  • 页面设计:办卡列表显示会员卡名称、办理时间、审核状态、支付状态;
  • 代码要点(办卡申请与审核):
@Transactional
public void addBankaxinxi(Bankaxinxi banka) {
    banka.setSfsh("待审核");
    banka.setIspay("未支付");
    banka.setBankashijian(new Date());
    banka.setAddtime(new Date());
    bankaxinxiMapper.insert(banka);
    
    log.info("用户 {} 申请办理会员卡 {}", banka.getXingming(), banka.getHuiyuankamingcheng());
}

8. 训练计划管理(个性化服务模块)

  • 核心逻辑:教练为用户制定训练计划(课程、训练内容、时间)→用户查看执行;
  • 页面设计:训练计划列表显示课程名称、训练内容、开始/结束时间、教练;
  • 代码要点:训练计划关联用户和教练。 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述转存失败,建议直接上传图片文件 在这里插入图片描述

五、健身俱乐部特色功能设计(关键加分项)

健身俱乐部网站的核心在于“健身服务闭环”,即课程预约、器材借用、会员办卡、训练计划全流程管理,以下是实测有效的设计方案:

1. 课程-器材-会员全流程追溯

环节记录内容可追溯信息
课程发布课程名称、类型、地点、价格、教练什么课、谁教、多少钱
课程预约预约时间、审核状态、支付状态谁预约了、审核了吗、付钱了吗
器材借用器材名称、借用数量、借用时间、审核状态借了什么、借多少、批准了吗
会员办卡会员卡名称、办理时间、审核状态、支付状态办什么卡、多少钱、生效了吗
训练计划训练内容、执行时间、制定教练练什么、什么时候、谁安排的

2. 器材库存预警机制

// 定时任务检查器材库存
@Component
public class EquipmentStockTask {
    
    @Scheduled(cron = "0 0 9 * * ?") // 每天上午9点执行
    public void checkStock() {
        List<Jianshenqicai> list = jianshenqicaiMapper.selectList(null);
        for (Jianshenqicai eq : list) {
            if (eq.getShuliang() <= 5) {
                log.warn("器材 {} 库存不足,当前库存:{}", eq.getQicaimingcheng(), eq.getShuliang());
                // 可发送通知给管理员
            }
        }
    }
}

3. 热门课程推荐算法

// 基于点击量和预约量计算课程热度
public List<Jianshenkecheng> getHotCourses(int limit) {
    List<Jianshenkecheng> list = jianshenkechengMapper.selectList(null);
    
    for (Jianshenkecheng course : list) {
        // 获取预约数
        Long yuyueCount = kechengyuyueMapper.selectCount(
            new LambdaQueryWrapper<Kechengyuyue>()
                .eq(Kechengyuyue::getKechengmingcheng, course.getKechengmingcheng())
                .eq(Kechengyuyue::getSfsh, "通过")
        );
        
        // 热度 = 点击量×0.5 + 预约数×0.5
        double hotScore = course.getClicknum() * 0.5 + yuyueCount * 0.5;
        course.setHotScore(hotScore);
    }
    
    list.sort((a, b) -> Double.compare(b.getHotScore(), a.getHotScore()));
    return list.stream().limit(limit).collect(Collectors.toList());
}

4. 用户健身统计

-- 统计用户的课程预约和器材借用情况
SELECT 
    u.zhanghao,
    u.xingming,
    COUNT(DISTINCT y.id) as yuyue_count,
    COUNT(DISTINCT j.id) as jieyong_count,
    SUM(y.kechengjiage) as total_cost
FROM yonghu u
LEFT JOIN kechengyuyue y ON u.zhanghao = y.zhanghao AND y.sfsh = '通过'
LEFT JOIN qicaijieyong j ON u.zhanghao = j.zhanghao AND j.sfsh = '通过'
GROUP BY u.id

六、测试与答辩:流程演示为主,突出健身服务闭环

1. 核心测试用例

测试场景操作步骤预期结果
课程发布全流程教练发布课程→用户查看课程信息正确显示;点击量初始为0
课程预约流程用户预约课程→教练审核通过→支付预约记录生成;审核状态更新;支付状态更新
器材借用流程用户申请借用器材→管理员审核通过借用记录生成;器材库存扣减
会员办卡流程用户申请办卡→管理员审核通过→支付办卡记录生成;会员权益生效
训练计划制定教练制定训练计划→用户查看训练计划正确显示

2. 答辩准备技巧

  • 演示流程:分角色演示(管理员端 + 教练端 + 用户端)→ 教练发布健身课程 → 用户浏览并预约课程 → 教练审核预约 → 用户支付 → 用户申请借用器材 → 管理员审核 → 器材库存扣减 → 用户申请办理会员卡 → 管理员审核 → 用户支付 → 教练为用户制定训练计划 → 用户查看计划 → 展示完整的课程-器材-会员-训练健身服务闭环;
  • 业务讲解:准备一页PPT展示系统功能结构图(图4-1),说明每个模块的作用和角色定位;
  • 技术亮点:重点讲解课程预约与教练审核联动、器材借用与库存扣减联动、热门课程推荐算法;
  • 突出问题解决:讲清“如何保证器材库存不超借”(借用时校验库存+审核通过后扣减)、“课程预约如何通知教练”(预约记录关联教练账号)、“训练计划如何关联用户”(通过用户账号关联);提前预判“为什么要设计器材库存字段”,回答“便于管理员实时掌握器材数量,避免超借”。

结语

本文核心是“聚焦课程-器材-会员核心业务、实现健身服务闭环、设计完整的健身俱乐部网站”。毕设无需复杂系统,把课程管理+器材管理+会员办卡+训练计划的业务逻辑讲透、实现一个可运行的健身俱乐部网站、展示完整的健身服务闭环,即可成为答辩亮点。

若需完整项目源码(带详细注释)、测试数据SQL脚本、器材库存预警完整代码,可在评论区留言“SpringBoot健身俱乐部系统”获取;开发中遇问题(如事务一致性、库存扣减逻辑、预约状态流转),也可留言咨询~ 祝毕设顺利!🎉