
毕业设计拿到“基于微信小程序的游泳管理系统”这个题目时我的第一反应是这不就是一个预约软件吗等真正把业务拆开发现游泳馆要管的远不止预约——办卡、约教练、签到、查课表、统计到场人数每一块都得想清楚。这篇记录我从零搭完这个项目的完整思路和踩坑过程。配套的 LW 文档怎么组织、源码目录怎么规划、哪些代码一看就是加分项我也都会讲到。如果你正在选毕设方向或者接了游泳场馆管理的小需求这篇应该对你有直接帮助。这个题目的受众其实很明确计算机专业准备毕业设计的学生或者想做小程序练手项目但不想做那种烂大街商城的人。游泳管理系统的好处是业务场景足够实体化——人有角色、场有状态、钱有订单、课有排期改造成其他场馆系统健身房、羽毛球馆、自习室非常容易。1. 从选题到技术栈微信小程序和游泳管理系统的组合逻辑1.1 为什么游泳馆需要一套“管理系统”游泳馆的实际运营场景比你想象的复杂。我在调研阶段跑了两家当地游泳馆发现前台最头疼的几个问题电话预约经常冲突弹性时间段没法精确管理会员卡办了但忘带全靠报手机号查询效率低还容易出错私教课排课靠Excel教练变更课时学员根本不知道。所以游泳管理系统的核心价值不是“把纸质表变成电子表”而是解决三件事场地时段的可占用状态实时可见、预约流程的闭环预约→到场→签到→核销、用户的身份识别谁来过、买了什么、剩几次。把这三个问题想清楚后面的表设计和接口设计就有了依据。1.2 小程序不是唯一选择但确实是最省事的选择做毕设时你可能纠结过为什么选微信小程序而不做个网页端或者App我的观点是小程序在这类场馆场景里有天然的生态优势用户不用下载安装扫码就能用微信自带登录体系省去自己搞账号系统的麻烦如果需要推送“预约成功”“教练调课”通知订阅消息也是现成的。对比一下成本App需要适配安卓和iOS、还要考虑上架审核网页端做完还得解决“用户怎么找到入口”的问题。小程序是最贴近“用完即走”的工具型产品形态很匹配游泳馆这种低频但刚需的预约场景。当然小程序也有自己的坑包体大小限制、审核规则多、登录换手机号接口个人主体受限。这些我放到后面单独讲都是实际会被卡住的地方。1.3 技术栈选择原生还是uniapp后端怎么搭毕设项目的技术栈选择我建议遵循“稳定优先、能答辩说清原理”的原则。前端方案对比方案优点缺点建议微信原生小程序官方文档全、调试方便、编译产物最小只有 wxml/wxss代码复用不如 Vue没人带又想稳扎稳打选它uniappVue 语法、一套代码多端发布二次封装的问题定位麻烦打包后可能超 2MB想顺带学跨端开发可选后端我推荐 Spring Boot因为计算机毕业设计的主流选题还是 Java 方向答辩时老师对 Spring Boot 的提问范围是可以预判的依赖注入、自动配置、拦截器这些。如果你不熟 Java用 Node.jsExpress/Koa或者微信云开发也能做但要注意答辩时老师可能会盯着你问“为什么不用主流方案”。数据库基本就是 MySQL老牌稳定表关系也好讲清楚。Redis 不是必须的毕设这种并发量用数据库事务就够加了 Redis 反而要多解释一堆缓存一致性的问题。提示如果你选 Spring Boot端口、接口前缀、跨域配置、统一返回结果这些基础工程一定要提前搭好。后面每个模块只是往里填业务代码不然边写业务边补工程问题节奏会乱。2. 系统设计与数据建模把游泳馆的业务拆成表2.1 角色和业务流程这步不能懒建模前一定要先走一遍业务闭环我见过很多同学上来就画 ER 图结果连“用户预约后怎么签到”这个流程都没想清楚。游泳管理系统的核心流程是用户注册登录 → 查看场地/课程/教练 → 选择时间预约 → 提交订单 → 模拟支付 → 到馆签到 → 管理员核销/查看统计涉及的角色有普通用户泳客、教练、管理员。注意教练和管理员都应该在小程序里完成操作不要做两个端。最简单的方式是用户表加一个 role 字段前端按角色显示不同页面后端在接口层做权限校验。这样省掉一套后台管理系统的开发量但功能看起来依然完整。2.2 核心数据表从 users 到 reservations我在设计表时踩过一个坑想着把所有字段都塞进一张大表里后来发现“预约记录”和“订单”其实是两类东西。下面是我最终定稿的核心表清单表名作用关键字段users用户基础信息openid、nickname、phone、role、statuscoaches教练信息name、title、phone、intro、avatarcourses游泳课程course_name、course_type、coach_id、price、max_countperiods场馆时段start_time、end_time、price、capacityreservations预约记录user_id、period_id、course_id、reserve_date、statusorders订单支付order_no、user_id、reservation_id、amount、pay_statuscards会员卡user_id、card_type、total_count、used_count、expire_date其中 reservations 表是整个系统的核心它决定了“场地时间段”到底有没有被占掉。我的设计是场馆按小时间段比如每 30 分钟一段拆成 periods 表预约记录里存 reserve_date period_id这样一天多时段、多场地都可以扩展。如果你需要更细粒度达到“同一个泳道”的预约再加一个 lane_id 字段即可预留扩展位很重要。2.3 容易写错的字段设计状态、时间、软删除第一个坑是状态字段。预约状态至少要预留0待签到、1已签到、2已取消、3已过期。很多同学只写“已预约”和“已完成”两个状态等到做签到功能时发现还要区分“能不能签”“超时了怎么办”改表结构很痛苦。第二个坑是时间字段的类型。reserve_date 用 DATE 类型start_time/end_time 用 TIME 类型不要在 Java 里用字符串拼日期去比较MySQL 的日期函数在统计时好用得多。第三个坑是软删除。用户可能注销、管理员可能删错数据每条核心表都加一个 delete_flag 字段0正常 1删除所有查询默认带上WHERE delete_flag 0。毕设答辩时这个设计能直接回答老师“你如何处理数据安全性”的问题。另外提醒一点微信登录拿到的 openid 一定要做唯一索引。同一个用户每次登录返回的 openid 是固定的用它做登录凭证能天然避免重复注册问题。3. 核心功能实现拆解预约、签到、购票的落地细节3.1 小程序端页面架构与自定义导航栏适配页面规划上我分了五块首页、场地预约、课程预约、我的预约、个人中心。底部 tabBar 放四个入口个人中心放“管理员入口”按钮仅 role 为管理员时显示。这里有一个热搜词提到的问题微信小程序顶部导航栏高度。不同机型的胶囊按钮位置不一样标题栏高度也变如果使用自定义导航栏navigationStyle: custom页面顶部的文字和按钮很容易错位。我当时的适配代码是// 获取胶囊按钮信息 const menuButton wx.getMenuButtonBoundingClientRect(); // 获取状态栏高度 const windowInfo wx.getWindowInfo(); const statusBarHeight windowInfo.statusBarHeight; // 导航栏高度 (胶囊顶部 - 状态栏高度) * 2 胶囊高度 const navBarHeight (menuButton.top - statusBarHeight) * 2 menuButton.height;这段代码建议封装成公共模块所有自定义导航页面调用避免每个页面复制粘贴。真机测试时多找几台不同型号手机看看总有一款会给你惊喜负向的那种。3.2 场馆时段预约怎么防止两个人抢同一个时间段这是整个系统最核心的业务逻辑。用户选择日期和时段点了预约之后后端要保证“同一场地的同一时段不能被重复预约”。最直接的方案是数据库唯一索引 插入时捕获冲突。我在 reservations 表里给(venue_location, reserve_date, period_id)建立了唯一索引然后预约接口的核心逻辑是Override Transactional(rollbackFor Exception.class) public Result createReservation(ReservationDTO dto) { // 检查用户是否已有冲突预约 // 检查场地时段是否已被占用 // 插入预约记录 // 生成配套订单 }这里的关键是Transactional事务注解以及插入唯一索引冲突时捕获DuplicateKeyException。前两步的“查询再判断”在高并发下其实有竞态但唯一索引兜底保证极端情况下数据库也不会插入两条冲突记录。毕设答辩能被问到的并发问题这一个点就够讲清楚你的设计思路了。我当时也考虑过SELECT ... FOR UPDATE悲观锁但毕设场景演示不出差别反而会让代码更复杂。如果你做的是课设用“唯一索引事务”已经超过多数人的水平了。3.3 课程预约与名额控制满员之后怎么办课程预约的冲突检测方式和场馆预约略有不同课程不按固定时段重复但有一个“最多报名人数”的限制。核心逻辑如下// 课程预约时统计当前报名人数 Integer currentCount reservationMapper.countByCourseId(courseId); Course course courseMapper.selectById(courseId); if (currentCount course.getMaxCount()) { return Result.error(该课程已满员); }同样的逻辑建议在插入前判断插入后用事务保持一致性。这里的用户体验细节是前端在课程卡片上也要实时显示“已报 x/max 人”需要后端提供一个查询接口返回名额余量。不要只做一个满员时点击报错应该提前让用户看到名额情况。3.4 签到功能一次性完成但有三种实现姿势签到实现我建议做成“用户端自签 管理员端代签”的双通道。用户端逻辑在我的预约列表中找到当天的预约记录点击“签到”按钮后端校验当前时间与预约时段的关系。我允许提前 15 分钟、延后 15 分钟内签到超出这个窗口提示“不在签到时间”。代码里要特别注意时区问题直接用new Date()比较前端传来的时间戳不要在数据库里做字符串比较否则夏令时和其他时区问题会埋雷。管理员端逻辑管理员可以查看当日全部预约列表手动将某人标记为已签到。这样做的好处是覆盖了“用户忘带手机、手机没电、老人小孩不会操作”的情况。你还可以加一个扫码签到的增强——生成预约二维码管理员小程序扫码后自动核销。二维码我用的是wx.createQRCode适用于小程序码或者用普通二维码库生成一张预约编号图片流程都行。但扫码需要摄像头权限小程序隐私接口要配置好。3.5 订单与模拟支付不接真实微信支付真实微信支付需要商户号、企业资质认证个人主体毕设基本走不通。我当时直接做了一个“模拟支付”按钮用户点击支付后进入一个支付确认页点击“确认支付”后后端把 orders 表的 pay_status 从 0 改成 1并把 reservation 状态从 0 待支付改成 0 待签到。这里要注意预约记录和订单状态是一对一关联的支付成功前预约状态可以叫“待确认”或“锁定”不要和“待签到”混淆。如果你想加上一点真实感可以接入微信支付的原生流程展示但实际提交订单时走模拟链路。老师在验收时如果问“为什么不做真支付”你答“需要企业商户号和资质个人主体受限使用模拟支付保证流程闭环”这个回答在毕设场景里是加分的说明你懂边界。注意即使模拟支付也要在订单表设计好支付时间、支付方式字段。真实系统里这些字段是财务对账的关键我先预留好后续接入真实支付不用改表。4. 微信登录与手机号授权这个环节最容易把人卡死4.1 wx.login 拿到 code 之后的完整链路微信登录的完整链路是小程序端调用wx.login()拿到临时 code → 传给后端 → 后端拿 code 调微信接口换取 openid 和 session_key → 后端生成自己的登录态 token 返回前端 → 后续所有请求带 token。这里最容易被忽略的是后端不能直接把 openid 当作用户的“会话凭证”用因为它没有过期时间概念被拿到就能冒充用户。正确做法是后端自己生成 token随机UUID存到 Redis 或数据库同时设一个过期时间比如 7 天以后每个需要登录的接口通过拦截器校验 token。换 openid 的典型代码我贴一下// 小程序登录 code 换会话信息 String url https://api.weixin.qq.com/sns/jscode2session?appid appid secret secret js_code code grant_typeauthorization_code; // 返回 json 中包含 openid、session_key需要注意appid 和 secret 一定不要写在前端代码里也不要提交到 GitHub。我见过不少同学把这些配置硬编码在项目里传到开源仓库结果被别人盗刷接口。正确做法是放到application.yml里并加入.gitignore提交代码前检查一下。4.2 getPhoneNumber 的认证门槛和替代方案现在微信小程序获取用户手机号有两种方式一种是通过button open-typegetPhoneNumber点击后拿到动态令牌 code再调用后端接口换手机号另一种是原来的填写表单方式。但是这个接口现在有严格限制非企业主体小程序无法调用个人主体申请不到这个接口权限而且还需要在小程序管理后台配置用户隐私保护指引。我当时是一开始照着网上的文章调 getPhoneNumber点了按钮之后一直是 undefined查了二十多分钟才发现权限问题。如果你也做个人主体的毕设我建议直接用替代方案注册时让用户手填手机号 短信验证码后端模拟发送验证码或者用阿里云短信但需要企业资质登录时直接用微信一键登录。核心思路是能用微信身份就微信身份登录需要手机号用于业务联系时在个人资料里补填。另外还有一个坑模拟器的网络环境可能和真机不一致getPhoneNumber 在开发者工具里能弹出来真机上就报错。调试时要多留意这个差异别等答辩前一天才发现。4.3 session_key 的保密注意session_key 是调用微信敏感接口时用来解密的密钥绝对不能返回给前端更不能打进日志里。如果换手机号接口需要解密数据session_key 的服务端获取逻辑也只在后端做。很多毕设项目把 session_key 直接通过接口返回这是严重的安全漏洞答辩老师发现了会直接扣分。5. 打包发布与真机调试把 Demo 变成能演示的系统5.1 本地开发环境的 HTTPS 和域名校验小程序请求后端接口有一个硬规定正式版小程序只能请求https://且域名已在小程序管理后台配置过的接口。本地开发时开发者工具可以勾选“不校验合法域名”但我建议从第一天起就使用统一的baseUrl常量管理接口地址方便后面切换。真机调试时如果手机上打开了调试模式可以跳过域名校验但每次发布体验版/正式版时必须校验。还有一个细节开发阶段的 IP 地址比如http://192.168.1.100:8080只能在同一个局域网的真机上访问云服务器部署时还要考虑跨域问题。5.2 包体积超限处理 uniapp 的 2MB 魔咒热搜里有一条“uniapp 微信小程序打包 source size 2612kb exceed max limit 2mb”。这个坑我亲眼见过不止一个同学踩过。小程序主包体积上限是 2MB整个小程序目前是 20MB 左右但主包是 2MB图片、原生组件、第三方库一多就容易超。解决办法最有效的是分包加载主包只保留 tabBar 页面、公共组件、公共工具类场地预约、课程详情、预约记录这些页面全部放进分包pages/booking/分包之间页面跳转路径用/pkg-booking/pages/...格式图片处理是个大头不要在项目里放大量本地图片全部压缩后上传到服务器或图床用https://链接引用。如果项目用到地图、图表这类大组件库按需引入不要整包 import。5.3 真机调试中常见的差异模拟器跑通了真机却出问题这是小程序的常规操作。我遇到过的差异有模拟器的 storage 数据和真机不互通登录态经常“消失了”这不是 bug是环境隔离自定义导航栏的高度适配模拟器上完美iPhone 14 Pro Max 上胶囊和文字挤在一起权限弹窗获取位置、摄像头、录音权限时真机会弹出系统授权框需要在 app.json 里声明对应permission字段上传图片模拟器可以直接选本地文件真机需要调用wx.chooseMedia返回格式有差异所以项目做差不多时借一台安卓一台 iPhone把主要流程走一遍比写一百个console.log都管用。5.4 审核提审的注意事项毕设演示不上线怎么办毕设作品不一定要上线只要你能演示就行。走开发版或体验版即可不需要提交审核。但如果你打算上线让别人用有几个点第一微信小程序现在要求先完成备案才能发布。第二个人主体很多类目不可用体育场馆预约一般需要企业或个体工商户资质。第三涉及用户信息收集需要在后台配置《用户隐私保护指引》并声明收集手机号的用途。第四符合类目要求的服务范围里选“体育 体育场馆服务”。毕设答辩场景里我建议你就用“体验版”给老师演示现场扫码即可最稳妥也省去审核等待时间。6. LW文档和答辩准备代码之外的最后一公里6.1 配套文档结构怎么搭和源码对照着写跟“源码”配套的 LW 文档论文/文档在很多时候比代码更影响成绩因为它直接决定了答辩老师能不能快速看懂你的项目。我的文档目录是这样的摘要 关键词需求分析业务痛点、角色分析、可行性分析系统设计总体架构、功能模块划分、数据库设计系统实现核心功能、界面展示、核心代码讲解系统测试测试用例、结果分析总结与展望关键技巧是文档里的截图必须从你的实际运行系统里截不要用网图。数据库设计章节直接把建表 SQL 贴进去并在关键字段上加上注释。核心代码讲两块就行登录流程的 token 鉴权、预约防冲突的设计。不要大段贴页面代码老师更关心的是思路。6.2 测试用例整理10 条就够用但有讲究系统测试部分不需要几百条用例按功能模块整理 10-15 条高价值用例即可。例如编号测试模块操作步骤预期结果T01登录点击微信登录自动创建账号跳转首页T02场地预约选择已被预约的时段提示“该时段已被预约”T03场地预约两个账号同时间约同一时段只有一个成功T04课程预约课程已满员时点击报名提示“已满员”不能提交T05签到非签到时间段签到提示“不在签到时间”T06管理员管理员登录后查看统计数据显示今日预约数、到场数每条用例都对应一个可复现的操作路径。答辩时老师如果问“你这个系统怎么保证不出 bug”把测试用例表调出来直接加分。6.3 答辩高频问题和容易漏讲的设计点我整理了几个老师最爱问的问题以及你应该提前准备的答案“为什么选择微信小程序而不是App”——轻量、免安装、微信生态内登录与通知能力“系统的角色和权限是怎么设计的”——users 表的 role 字段 后端拦截器按角色放行接口“数据库表之间怎么关联”——重点讲 reservations 表如何关联 users、periods、courses“遇到的最大难点是什么”——并发预约冲突用唯一索引 事务解决“项目有哪些不足”——真实线上支付未接入、未做大数据量压力测试后续可以完善还有一个设计点一定要准备管理端的数据统计功能。不用做复杂图表一个“今日预约数、今日签到数、本月课程收入”的卡片式汇总页就足够。这个功能在演示时非常亮眼工作量却不大我强烈建议加上。在实际操作中我最想提醒你的是代码和文档一定要同步更新。我见过太多人写完代码再补文档最后补出来的文档跟源码对不上字段名换了、流程变了老师对着代码问一个问题就直接穿帮。把文档跟开发周期同步推进哪怕每一周只写一小节最后也只是合并汇总不会开夜车赶工。这个小程序做完之后改动的地方也比你想象的多。真正上线或者给真实场馆用时要处理支付回调、教练排班冲突、短信通知、数据备份这些生产问题。但作为毕设项目把预约闭环、角色权限、数据建模这几块讲清楚已经是一份能拿得出手的作品了。如果后面有想法可以把这个系统往“体育场馆多店版”改一套后台管多个场馆那又是另一个项目了。