原创

基于SpringBoot2+vue2的健身房管理系统

温馨提示:
本文最后更新于 2026年05月28日,已超过 13 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

1. 资源

浏览全文可获取

2. 项目简介

健身房管理系统,旨在为健身房提供一个线上管理平台。系统主要面向两类用户:管理员普通用户

  • 管理员可以对系统中的基础数据进行管理,包括但不限于:健身房信息、教练信息、课程信息、器材信息、用户信息,以及管理课程类型和器材类型等字典数据。
  • 普通用户(会员)登录系统后,可以查看健身房、教练、课程、器材等公开信息。

系统提供了完整的后端服务接口(RESTful API)和前端管理界面(基于Vue.js),实现了数据查询、信息展示、后台管理、登录认证、权限控制等核心功能。

3. 技术栈

该项目采用前后端分离的架构,主要技术栈如下:

  • 后端

    • 核心框架: Spring Boot 2.2.2.RELEASE
    • 持久层框架: MyBatis Plus 2.3
    • 数据库: MySQL 5.7.32
    • 权限控制: Apache Shiro 1.3.2, 自定义Token拦截器
    • 工具库: Hutool, Fastjson, Commons-lang3, Commons-io
  • 前端(管理端)

    • 核心框架: Vue 2.x
    • UI组件库: Element UI
    • HTTP客户端: Axios
    • 图表库: ECharts
    • 其他: Vue Router, vue-json-excel, vue-qr, print-js
  • 开发与部署

    • 构建工具: Maven, npm / Vue CLI
    • 环境: JDK 1.8

4. 详细介绍

4.1 核心功能模块

  1. 基础数据管理:

    • 字典管理: 管理系统中的下拉选项数据,如性别、课程类型、器材类型等。这些数据存储在dictionary表中,并在项目启动时加载到ServletContext中作为全局缓存,用于前后端值的转换。
    • 类型管理: 可以增删改查具体的课程类型和器材类型。
  2. 健身房管理: 管理员可以对健身房信息进行增删改查,包括名称、照片、位置和详细介绍。普通用户只能查看。

  3. 教练管理: 管理员可以管理教练档案,包括姓名、手机号、头像、性别、所获荣誉和详细介绍。普通用户只能查看。

  4. 课程管理: 管理员可以发布和管理课程。每门课程关联一个教练和一个健身房,包含课程名称、类型、上课时间、介绍等信息。普通用户只能查看。

  5. 器材管理: 管理员可以管理健身器材信息,包括器材名称、类型、照片、数量、介绍。普通用户只能查看。

  6. 用户管理:

    • 管理员可以查看、新增、修改、删除系统用户。
    • 用户可以通过用户名和密码进行登录。登录时,系统会校验其会员是否过期(daoqi_time)。
    • 用户可以进行注册、重置密码操作。
    • 用户的头像、手机号、身份证号、邮箱、会员到期日等信息可在后台统一管理。
  7. 权限与认证:

    • 系统通过自定义的AuthorizationInterceptor拦截器实现Token校验。
    • /dictionary/page/file/upload/yonghu/register等公开接口外,其他接口都需要在Header中携带有效的Token进行访问。
    • 前端路由和菜单权限通过src/main/resources/admin/admin/src/utils/menu.js进行配置,区分管理员和用户的不同菜单。
  8. 数据可视化(图表统计):

    • 后端CommonController提供了丰富的图表统计接口(如/barSum, /barCount),支持对指定表的字段进行分组求和、计数统计,并返回ECharts所需的数据格式,为前端提供图表展示数据源。

4.2 数据库设计

  • yonghu (用户表): 存储用户账号、密码、个人信息、会员有效期等。
  • jiaolian (教练表): 存储教练信息。
  • jianshenfang (健身房表): 存储健身房信息。
  • kecheng (课程表): 通过jiaolian_idjianshenfang_id外键关联教练和健身房。
  • qicai (器材表): 通过qicai_types外键关联器材类型字典。
  • dictionary (字典表): 存储系统中的所有键值对配置,如sex_types(性别)、kecheng_types(课程类型)、qicai_types(器材类型)等。
  • users (管理员表): 存储后台管理员账号信息。
  • token (Token表): 存储用户登录后的token信息及过期时间。

4.3 业务逻辑与亮点

  1. 会员到期校验: 在用户(YonghuController)登录时,系统会判断yonghu表中的daoqi_time字段是否晚于当前时间,如果会员已过期,则拒绝登录。
  2. 字典表全局缓存: 项目启动时,通过DictionaryServletContextListener监听器将所有字典表数据加载到全局ServletContext中。在返回数据时,DictionaryServicedictionaryConvert方法会利用该缓存,自动将*_types等代码值(例如1)转换为对应的显示名称(例如),简化前端处理。
  3. 通用图表统计: CommonController中实现了通用的柱状图、饼状图数据生成逻辑。通过传入表名、分组字段、统计字段等参数,后端可以动态生成SQL并返回前端ECharts组件所需的标准xAxisyAxislegend数据,无需为每个图表单独编写接口。
  4. 批量导入: 控制器中预留了/batchInsert接口,配合PoiUtil工具类,可以实现通过Excel文件批量导入数据的功能(相关代码已注释,但结构完整)。
  5. 文件上传: 实现了统一的文件上传接口(/file/upload),用于处理教练头像、健身房照片、器材照片等资源文件的上传,并返回文件路径。

5. 部分代码

5.1 权限拦截器 (AuthorizationInterceptor)

该拦截器负责对所有请求进行Token验证,是系统安全的核心。

@Component
public class AuthorizationInterceptor implements HandlerInterceptor {

    public static final String LOGIN_TOKEN_KEY = "Token";

    @Autowired
    private TokenService tokenService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // ... (跨域设置)

        // 1. 判断是否需要忽略认证
        if (handler instanceof HandlerMethod) {
            annotation = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
        }
        if(annotation!=null) return true;

        // 2. 获取Token并验证
        String token = request.getHeader(LOGIN_TOKEN_KEY);
        TokenEntity tokenEntity = tokenService.getTokenEntity(token);

        if(tokenEntity != null) {
            // 3. 验证通过,将用户信息存入Session
            request.getSession().setAttribute("userId", tokenEntity.getUserid());
            request.getSession().setAttribute("role", tokenEntity.getRole());
            return true;
        }

        // 4. 验证失败,返回401错误
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.print(JSONObject.toJSONString(R.error(401, "请先登录")));
        writer.close();
        return false;
    }
}

5.2 课程管理控制器 (KechengController)

展示了标准的RESTful API实现,包含分页查询、详情、保存、更新和删除功能。

@RestController
@RequestMapping("/kecheng")
public class KechengController {
    @Autowired
    private KechengService kechengService;
    @Autowired
    private DictionaryService dictionaryService;

    /**
    * 后端列表(分页)
    */
    @RequestMapping("/page")
    public R page(@RequestParam Map<String, Object> params, HttpServletRequest request){
        // ... 角色判断
        PageUtils page = kechengService.queryPage(params);
        // 字典表数据转换
        List<KechengView> list =(List<KechengView>)page.getList();
        for(KechengView c:list){
            dictionaryService.dictionaryConvert(c, request);
        }
        return R.ok().put("data", page);
    }

    /**
    * 后端保存
    */
    @RequestMapping("/save")
    public R save(@RequestBody KechengEntity kecheng, HttpServletRequest request){
        // 1. 检查数据唯一性
        Wrapper<KechengEntity> queryWrapper = new EntityWrapper<KechengEntity>()
            .eq("jiaolian_id", kecheng.getJiaolianId())
            .eq("jianshenfang_id", kecheng.getJianshenfangId())
            .eq("kecheng_name", kecheng.getKechengName());

        KechengEntity kechengEntity = kechengService.selectOne(queryWrapper);
        if(kechengEntity==null){
            // 2. 设置时间并保存
            kecheng.setInsertTime(new Date());
            kecheng.setCreateTime(new Date());
            kechengService.insert(kecheng);
            return R.ok();
        }else {
            return R.error(511,"表中有相同数据");
        }
    }
    // ... update, delete等其他方法
}

5.3 字典值转换服务 (DictionaryServiceImpl)

该服务利用反射和全局缓存,自动将实体中的Integer类型代码字段转换为字符串类型的显示值字段。

@Service("dictionaryService")
public class DictionaryServiceImpl extends ServiceImpl<DictionaryDao, DictionaryEntity> implements DictionaryService {

    @Override
    public void dictionaryConvert(Object obj, HttpServletRequest request) {
        // 1. 通过反射获取实体中所有以 "Types" 结尾的 Integer 字段
        // 2. 从 ServletContext 中获取全局缓存的字典表 Map
        Map<String, Map<Integer, String>> dictionaryMap= (Map<String, Map<Integer, String>>) servletContext.getAttribute("dictionaryMap");

        // 3. 遍历这些 "Types" 字段
        for (String s : fieldNameList) {
            // 4. 获取 "Types" 字段的整数值,并从 dictionaryMap 中获取对应的显示名称
            // 5. 将显示名称赋值给对应的 "Value" 字段
            value.set(obj, s2);
        }
    }
}

6. 部分截图

img1
img2
img3
img4
img5
img6
img7
img8
img9
img10
img11
img12
img13
img14

7. 项目总结

该项目是一个功能完备、结构清晰的健身房管理系统。它采用了主流的Spring Boot + Vue技术栈,实现了前后端分离的开发模式。

优点:

  1. 架构清晰: 项目严格遵循MVC分层架构,后端分为Controller、Service、Dao、Entity等层次,前端基于Vue组件化开发,结构易于理解和维护。
  2. 功能完整: 覆盖了健身房管理的核心业务流程,从基础数据维护(字典、类型)到核心业务管理(教练、课程、器材、会员),逻辑闭环。
  3. 设计良好:
    • 利用MyBatis Plus简化了数据库操作。
    • 通过Token认证保证了API的安全性。
    • 字典表的全局缓存和自动转换机制是系统的亮点,显著提升了开发效率和数据处理的一致性。
    • 通用的图表统计接口体现了较高的抽象设计能力,避免了重复开发。
  4. 数据校验: 在后端保存/更新时,对数据的唯一性做了校验,保证了数据完整性。

总体而言,这是一个具有学习和参考价值的中型Web项目,展示了企业级应用开发中许多实用的技术和设计思想。

自助获取:https://fifteen.xiaobias.com/source/207

正文到此结束
本文目录