简介面向本科毕业设计、课程设计与项目实战场景这套图书馆预约系统微信小程序资料包提供从源码到部署的完整闭环。系统采用微信小程序开发工具Java后端MySQL数据库的B/S架构覆盖管理员、用户、员工三类角色管理员可维护首页公告、自习室类别朗读房/普通房/电脑房与预约记录用户可在个人中心修改资料、查看预约和信用积分员工则可核查预约并手动解除信用限制功能模块划分清晰。压缩包共5个文件含2个rar程序源码包、1个zip演示录像、1个txt运行环境说明和1个sql数据库脚本总大小约59.23MB演示录像便于快速了解操作流程环境说明可辅助完成数据库导入与前后端启动。目前已有341人学习适合需要搭建图书馆预约系统、准备毕业设计答辩或进行二次开发的微信小程序学习者。1. 图书馆预约系统带源码、数据库和录像的微信小程序毕设资源包每年毕设季“图书馆预约系统”都是微信小程序选题里的常青树场景贴近校园、三个角色自带权限链路、数据库不算复杂但足够展示设计能力所以很多课程设计和毕业设计都拿它做项目实战。这套资源包里tsgyy.sql 负责把用户、自习室、预约、留言、信用积分串成一张网tsgyy-wx 是跑在微信开发者工具里的前端工程tsgyy 是 Java 写的后端服务另附运行环境说明和演示录像。对要交毕业设计的学生它解决了“从哪下手”的问题对想练手小程序全栈的开发者它也是能对照着改的源码包。下文按数据库、小程序端、Java 后端、避坑、验证五层拆开。2. 技术选型拆解微信小程序 Java MySQL 的 B/S 结构怎么搭这套资源同时给了两个程序包tsgyy-wx.rar 是小程序前端工程tsgyy.rar 是 Java 后端工程中间通过 HTTP 接口通信数据最终落在 MySQL。整体是 B/S 结构在移动端的变体——小程序充当瘦客户端所有业务逻辑集中在服务端。毕业设计选这个组合的性价比在于前端不用碰安卓/iOS 原生开发后端 Java 生态资料多MySQL 又是最容易被答辩老师接受的数据库。一个完整的表设计、前后端联调就能把“需求分析 → 数据库设计 → 后端接口 → 前端页面”整条链路走通。2.1 三个角色的数据边界管理员、用户、员工各自能碰哪些表摘要里写得很清楚这套系统的用户角色是管理员、员工用户、普通用户三个。管理员管公告、自习室类别朗读房/普通房/电脑房、自习室信息与预约、留言回复、信用积分用户只管自己的资料、预约和积分查看员工用户是图书馆管理人员能看全部预约、看所有用户积分、手动解除限制。从数据库设计角度看这三个角色不需要拆成三张用户表常见做法是单表 users 加一个 role 字段0 普通用户、1 员工、2 管理员。权限控制落在两个地方后端接口做会话校验时判断 role小程序端根据登录后返回的 role 值决定渲染哪些菜单。这样设计的优点是账号体系只有一张表后续要加角色比如“值班员”只改枚举值和接口校验逻辑。数据对象管理员员工用户普通用户公告管理增删改查只读首页可见自习室类别朗读房/普通房/电脑房增删改查只读预约时筛选自习室信息增删改查只读预约时查看预约记录全部可见全部可见、可核销仅本人留言管理回复/删除只读提交留言信用积分调整查看、解除限制仅本人查看这张表也对应答辩时的功能讲解顺序先说需求再点表。如果想把系统改得更大可以引入独立权限表但毕设阶段用字段枚举已经够用别在权限模型上过度设计。我见过有人一上来就设计五张角色表结果数据维护成本和答辩复杂度都上去了老师们反而追着问为什么要拆。2.2 数据库表结构预约表、积分流水表是怎么把业务串起来的tsgyy.sql 导入后核心数据表至少有这几类用户表含角色和信用积分、自习室类别表朗读房/普通房/电脑房、自习室信息表、预约表、留言表、积分流水表。其中预约表是整个系统的枢纽它同时关联用户表和自习室表还承担冲突检测和信用扣分的判断依据。预约表常见的设计大概是这样CREATE TABLE t_reservation ( id INT NOT NULL AUTO_INCREMENT COMMENT 预约ID, user_id INT NOT NULL COMMENT 用户ID, room_id INT NOT NULL COMMENT 自习室ID, reserve_date DATE NOT NULL COMMENT 预约日期, start_time TIME NOT NULL COMMENT 开始时间, end_time TIME NOT NULL COMMENT 结束时间, status TINYINT DEFAULT 0 COMMENT 0预约中 1已完成 2已取消 3爽约, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 下单时间, PRIMARY KEY (id), KEY idx_user (user_id), KEY idx_room_date (room_id, reserve_date) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT自习室预约表;这里的关键字段是 reserve_date、start_time、end_time 三个的组合冲突检测就是拿这三个字段去查重叠区间status 字段记录预约生命周期信用积分扣不扣取决于最终落到哪种状态。日期用 DATE 单独拆出来而不是塞进 DATETIME是为了方便按天查询和按天做统计这也是图书馆预约类项目里最常见的做法。用户表里通常会有 credit 字段存当前积分再配一张 credit_log 流水表记录每次变更原因。流水表的好处是答辩时能拿出“可追溯”的证据扣积分不是拍脑袋每一次扣减都有记录。管理员调整积分、员工解除限制本质都是往这两张表里写数据。数据库这一层如果理解了后面看后端接口和小程序页面都会顺很多。3. 小程序端 tsgyy-wx从登录到预约的完整链路tsgyy-wx 这个工程解压后直接用微信开发者工具打开。项目结构很典型pages 放页面、utils 放公共工具、app.js 管全局登录态。我第一次看这套代码时最直观的感受是页面划分跟摘要里描述的功能一一对应基本没有多余的页面这在小程序毕设源码里算难得。下面把从登录态到预约提交的链路拆开讲。3.1 页面结构与请求封装登录态怎么传给 Java 后端小程序端不能直连 MySQL所有数据都要走后端接口。所以工程里一定有一个统一的请求模块把 url、method、data 封装好再在页面的生命周期里调用。目录结构大致是tsgyy-wx/ ├── app.js # 全局逻辑登录与用户信息 ├── app.json # 页面注册与窗口配置 ├── utils/ │ └── request.js # wx.request 封装 └── pages/ ├── index/ # 首页公告与自习室列表 ├── reserve/ # 自习室预约 ├── my/ # 个人中心资料修改与积分查看 ├── admin/ # 管理员功能 └── staff/ # 员工功能app.json 里注册的页面路径决定小程序能跳到哪些页面新增页面忘记注册会出现“page not found”这是新手最容易翻车的地方。请求封装通常是这样的// utils/request.js const BASE_URL http://localhost:8080/tsgyy; function request(url, method GET, data {}) { return new Promise((resolve, reject) { wx.request({ url: BASE_URL url, // 后端接口路径 method: method, // GET / POST data: data, header: { Content-Type: application/json }, success: (res) resolve(res.data), fail: (err) reject(err) }); }); } module.exports { request, BASE_URL };这个封装里的 BASE_URL 决定了小程序连哪台机器。如果后端跑在你自己的电脑上开发者工具里可以用 localhost一旦换到真机预览localhost 指向的是手机自己必须改成电脑的局域网 IP比如 http://192.168.1.101:8080/tsgyy。我帮别人调这套系统时至少有一半时间耗在这个地址上因为很多人忘了换 IP。登录态的处理常见做法是 wx.login 拿 code交给后端换 tokentoken 存在 storage 里每次请求带上。如果源码里用的是 session 机制那就检查 cookie 是否正常下发真机上要求域名是 HTTPS 且在小程序后台配置了 request 合法域名这一点在避坑章会专门说。个人中心页通常承载三个区块资料修改、我的预约、信用积分登录后刷新这三个区块的数据就能看到完整信息。提示开发者工具里改了 BASE_URL 之后点编译会自动重新加载但小程序有时会缓存旧代码改完建议清一次缓存再编译避免改了地址还请求旧域名。3.2 预约提交类别筛选、时间校验与状态回显预约页是整个小程序的核心页面摘要里特别提到自习室类别分朗读房、普通房和电脑房所以这个页面通常有两个联动选择先选类别再选该类别下的具体自习室然后选日期和时间段最后提交。提交按钮的逻辑里最重要的一步是本地先校验参数后端再查冲突前端校验能拦截空值和明显非法的时间区间减少无效请求。// pages/reserve/reserve.js const { request } require(../../utils/request); Page({ data: { roomId: , reserveDate: , startTime: 08:00, endTime: 10:00, roomList: [] }, // 监听日期选择 onDateChange(e) { this.setData({ reserveDate: e.detail.value }); }, // 提交预约 submitReserve() { const { roomId, reserveDate, startTime, endTime } this.data; if (!roomId) { wx.showToast({ title: 请选择自习室, icon: none }); return; } if (!reserveDate) { wx.showToast({ title: 请选择日期, icon: none }); return; } request(/reserve/add, POST, { roomId: roomId, reserveDate: reserveDate, startTime: startTime, endTime: endTime, userId: wx.getStorageSync(userId) // 从登录态里取 }).then(res { if (res.code 200) { wx.showToast({ title: 预约成功, icon: success }); this.loadMyReserves(); // 刷新“我的预约” } else { wx.showToast({ title: res.msg, icon: none }); } }).catch(() { wx.showToast({ title: 网络异常请检查后端服务, icon: none }); }); } });这里有个细节startTime 和 endTime 我用的是字符串后端会做时间比较有的源码里会用 picker 选时间段返回的是“08:00-10:00”这种整串后端解析时要 split 成两个字段改了前端别忘了后端。预约成功后的状态回显也很关键确认页要能区分“预约中/已完成/已取消/爽约”四种状态这个状态枚举在前后端必须保持一致否则页面显示会出错。3.3 员工端和管理员端同一个工程按角色渲染不同页面这套小程序没有拆三个独立 App而是登录后根据 role 值渲染不同界面。员工端和管理员端都复用预约列表组件只是操作按钮不同员工能确认完成、解除限制管理员还多了公告管理、类别管理、留言回复入口。这种按角色渲染的模式既减少重复代码也方便答辩演示——一个账号退出换另一个账号登录界面就变了。!-- pages/my/my.wxml 片段 -- view wx:if{{role 2}} view wx:for{{adminMenu}} wx:keyid{{item.name}}/view /view view wx:elif{{role 1}} view wx:for{{staffMenu}} wx:keyid{{item.name}}/view /view view wx:else view我的预约/view view信用积分/view /viewwxml 里的 wx:if 判断只是控制入口显示真正的权限校验一定在后端接口层再做一次否则懂点前端的人就能改掉 role 值看到别人的数据。我通常建议把角色信息加密存储后端每次请求从数据库查 role 复核而不是信任前端传过来的字段。演示录像里三个角色切换的过程对照代码看会更清楚建议拿到资源包后先按角色各跑一遍。4. Java 后端 tsgyy预约冲突检测与信用积分的实现tsgyy 这个 Java 工程是整套系统的业务核心。小程序端所有请求都会进到这里做参数校验、权限校验、数据库读写再返回结构化结果。从运行环境说明的内容推测它跑在 Tomcat 上通过 JDBC 或连接池连 MySQL。底层框架是原生 Servlet 还是 Spring Boot解压后看 pom.xml 或 lib 目录就清楚了不影响下面的分析思路。4.1 预约接口时间段重叠判断与状态流转预约功能最重要的后端逻辑是冲突检测。用户提交了 roomId、reserveDate、startTime、endTime 之后不能直接 insert得先查同一自习室同一日期下有没有时间重叠的未取消记录。重叠的数学条件是两个区间 A、B只要 A.start B.end 且 A.end B.start就能判定为撞车。SELECT COUNT(*) FROM t_reservation WHERE room_id #{roomId} AND reserve_date #{reserveDate} AND status 0 AND start_time #{endTime} AND end_time #{startTime};这条 SQL 最关键的是status 0这个过滤条件。如果漏了它已取消的预约也会占用名额用户会看到明明取消成功了再约同一个时间段却提示“已被预约”。查询返回 count 大于 0 就拒绝本次预约给前端返回“该自习室该时段已被预约”。接口层拿到参数后还应该校验 startTime 小于 endTime、reserveDate 不早于当天这些校验只放前端不够后端必须再做一遍。预约状态流转建议这样设计新增时 status0预约中员工核销后 status1已完成用户主动取消 status2已取消超时未到或预约了没来 status3爽约。信用积分的扣减规则跟这个状态强绑定——爽约扣分、正常完成不扣或加分。答辩时把这条状态流转线画出来比空谈需求分析有说服力得多。4.2 信用积分扣分事务、流水记录与员工解除限制积分模块在摘要里是管理员和员工用户的交集功能。用户能看到自己的积分员工能查看所有用户积分并手动解除限制。这里的“限制”通常指当信用积分低于某个阈值比如 60 分系统禁止该用户再次预约只有员工手动把用户状态恢复后才能继续约。扣减积分一定要用事务因为要同时改预约状态、用户积分、积分流水三张表任何一步失败数据就对不上了。// service/ReservationService.java Transactional(rollbackFor Exception.class) public void cancelReservation(Integer userId, Integer reservationId) { // 1. 改预约状态为取消 reservationDao.updateStatus(reservationId, 2); // 2. 查询当前积分并扣除下限为 0 User user userDao.selectById(userId); int newCredit Math.max(user.getCredit() - 2, 0); userDao.updateCredit(userId, newCredit); // 3. 插入一条积分流水方便追溯 creditLogDao.insert(userId, 取消预约, -2); // 4. 若积分低于阈值更新用户状态为“限制预约” if (newCredit 60) { userDao.updateStatus(userId, 1); // 1 表示受限 } }员工“手动解除限制”对应的是相反操作把 user 的 status 从 1 改回 0同时清掉或重置积分流水。这个操作必须记录操作人所以接口参数里通常会带 staffId。我见过有源码把解除限制做成直接改积分那样用户下一次爽约又会被限实际上是治标不治本不如把“限制状态”和“积分”拆成两个字段管理。4.3 数据库连接与运行环境连接池、时区与账号密码后端连不上数据库是跑这套源码的第一道坎。运行环境说明.txt 里会写 MySQL 版本和初始化账号通常配置文件里是 root 加一个默认密码。常见坑是 MySQL 8.x 的驱动类名和时区参数跟 5.x 不一样配置写不对就报 “Unknown database” 或者连接超时。# src/main/resources/db.properties jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/tsgyy?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8 jdbc.usernameroot jdbc.password123456如果本地 MySQL 是 5.7驱动用 com.mysql.jdbc.Driver 也行但 8.x 必须用带 cj 的那个类名这是最容易踩的版本兼容坑。连接池建议直接用工程里自带的配置先跑通再调参数毕设阶段连接池大小设 10 就够别为了炫技堆一堆参数。启动后端后先用 Postman 或浏览器直接请求一个接口确认能返回 JSON再去连小程序端这样能快速区分问题出在后端还是前端。5. 避坑指南这套毕设源码跑不通的五个常见原因写这一章是因为我拆过不少毕设资源包代码本身的坑少环境配置的坑反而最多。下面五条是照着这套图书馆预约系统实操时最容易撞上的每条都按现象、原因、解决给出来遇到问题直接对号入座。5.1 小程序请求失败一直转圈或者报 request:fail现象真机预览时小程序所有数据都加载不出来开发者工具里报 request:fail但后端日志显示根本没收到请求。原因两个最常见——开发者工具没开“不校验合法域名”开关导致 host 被拒或者真机上访问了 localhost而 localhost 在手机里指向手机自己根本到不了电脑。解决本地调试时在微信开发者工具的“详情 → 本地设置”里勾选“不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书”。真机预览时把 utils/request.js 里的 BASE_URL 从 localhost 改成电脑的局域网 IP并保证手机和电脑在同一 Wi-Fi 下同时关掉电脑防火墙对 8080 端口的拦截。改完清缓存重编译小程序端代码改动有时不会立刻生效。5.2 导入 tsgyy.sql 报语法错误或中文乱码现象用 Navicat 导入 tsgyy.sql 时弹出 1064 语法错误或者表导进去了但中文全是问号。原因MySQL 版本差异导致 SQL 语法不兼容另一个是连接和文件编码不一致文件是 UTF-8连接用的却是 GBK。解决导入前先用记事本打开 tsgyy.sql确认文件头部有没有 SET NAMES utf8mb4没有就手动在文件开头加一行。新建数据库时字符集选 utf8mb4、排序规则选 utf8mb4_general_ci。如果走命令行用mysql -u root -p --default-character-setutf8mb4 tsgyy tsgyy.sql避免命令行默认字符集干扰。导入后随便开一张表看中文注释是否正常不正常就重建库重来别在原库上反复改。5.3 预约冲突检测失效同一时段被约进两个人现象两个账号同时约同一个自习室同一时段系统都提示成功预约表里出现两条重叠记录。原因冲突检测的 SQL 漏了 status 条件把已取消的记录也算进去了或者后端 select 后 insert 之间没有加并发控制两个请求同时通过了检查。毕设演示时单账号串行操作不容易触发但答辩老师很可能会问“如果两个人同时点怎么办”。解决第一步把status 0加进冲突检测 SQL第二步在预约表上加联合唯一索引比如对 room_id、reserve_date、start_time、end_time、status 建组合索引让数据库层面的约束兜底。如果后端用了 Spring 事务还可以在 insert 前用 SELECT ... FOR UPDATE 锁行但毕设阶段建议用唯一索引简单而且答辩时能讲清楚。5.4 演示录像和本地跑出来的效果对不上现象照着录像里的操作点发现页面上没有录像里展示的按钮或者接口返回的数据跟录像里不一样。原因录像可能是作者在特定环境下录的比如管理员账号只存在于他的本地数据库、端口号不同、界面文案在后续版本改过。录像的本质是“演示参考”不是“验收标准”。解决以运行环境说明.txt 和源码为准。先确认种子数据有没有导入——很多页面空着不是 bug是数据库里没有测试数据。如果录像里有个公告但你的首页没有那就是 tsgyy.sql 里缺这条公告数据手动在表里插一条即可。这种差异十次里有九次是数据问题剩下一次是端口写死在后端配置里。5.5 登录成功后页面空白或数据不显示现象账号能登录进去但个人中心看不到预约记录管理员页面列表空白控制台报 401 或 403。原因登录返回的 token 或 userId 没有正确存进 storage后续请求没带身份凭证或者后端 session 过期前端没有做重新登录的跳转。解决检查 wx.setStorageSync 的调用时机和 key 名确认和后端接口里读取的字段一致。再看后端接口有没有拦截器拦截器对哪些路径放行。自测方法登录后手动清掉 storage 再刷新页面如果报 401说明拦截器逻辑是通的问题出在前端没把 token 带过去。遇到跨域或者 session 不同步的在后端统一响应头里加允许源配置再配个过滤器把 OPTIONS 预检请求直接放行。6. 部署验证与答辩技巧把演示录像变成加分项源码跑通只是第一步毕业设计最后看的是你能不能讲明白。我的习惯是拿到这类资源包先从头到尾跑一遍把每一步验证结果记成一张核对表阶段检查项通过标准数据库tsgyy.sql 导入成功中文不乱码核心表数据齐全后端Tomcat 启动无异常直接访问登录接口能返回 JSON小程序开发者工具编译通过首页公告能加载联调三个角色各登录一次普通用户能约自习室员工能核销管理员能改公告真机手机连同一 Wi-Fi 预览数据正常加载无 request:fail答辩演示时不要照录像念而是按业务线讲从用户预约自习室开始演示冲突检测怎么拒绝同一时段再切员工账号核销、查看积分、解除限制最后切管理员账号改公告、回复留言。整个过程要体现“我能说清楚每一张表、每一个接口的职责”。计算机毕业设计的答辩核心是让老师相信你理解了这套东西而不是背了几百行代码。还有一个加分细节把信用积分的扣分阈值比如低于 60 分禁止预约和状态流转预约中→已完成/已取消/爽约提前整理成一张图老师问起来直接讲图。答辩时间有限与其背代码不如把核心的冲突检测 SQL 和事务扣积分的逻辑讲透这两个问题是老师最常追问的点。这套资源拿到手正确的打开顺序是先看运行环境说明.txt再导数据库、启后端、改小程序地址、三端联调。我第一次拆这种包含源码、数据库、录像的毕设包时跳过了环境说明直接导库结果在 MySQL 版本上耗了一下午。从那以后我每次拿到项目都强制自己先读环境说明、再动手把环境对齐当作第一步。希望这次拆解能帮你在图书馆预约系统上少走几步弯路。本文还有配套的精品资源点击获取