
简介这份资源面向学习微信小程序开发的学生与校园信息化实践者提供一套可直接参考的宿舍管理系统完整项目源码解决宿管与学生双向登录、日常事务线上化管理的需求。压缩包共约2000个文件整体8.4MB以769个js与393个ts脚本承载业务逻辑258个json与236个md用于配置和说明文档另有wxml、wxss页面文件及proto、yml等辅助配置结构完整便于按模块研读。已有1958人学习下载说明其在同类课程设计与小程序练手中具有一定参考热度。项目覆盖签到定位、卫生评分、留言回复、晚归申请等核心模块并预留MySQL数据库接口用于密码校验与数据存储读者可据此理解小程序端与后端的数据交互思路也可作为课程设计或毕业设计的改造基础快速搭建自己的宿舍管理应用。1. 需求先立住宿舍管理为什么值得单独做一套小程序宿舍管理这件事表面看只是查寝、报修、登记三件小事真落到一栋楼上麻烦立刻翻倍。楼长手里是纸质表格辅导员手里是聊天记录后勤手里又是另一套台账学生想知道自己那盏坏掉的灯什么时候修只能挨个问。信息在三个角色之间来回搬运谁都没有一份准数。这套基于微信小程序的宿舍管理系统要解决的就是这种“数据各存一份、流程靠人传话”的散乱状态。它适合正在做课程设计或毕业设计的同学也适合需要给一栋宿舍楼快速搭一套可用台账的管理人员。选微信小程序而不是原生 App理由很实在学生不用装新软件扫码即用微信开发者工具一套环境就能把前端、云函数、数据库串起来对个人或小组交付来说省掉的是最耗时间的分发和适配环节。2. 总体架构设计小程序端、云函数与数据库的三层职责划分这套系统我一般按三层来切小程序端负责界面与交互云函数负责业务规则和数据校验云数据库负责持久化。三层之间只通过接口约定通信不让页面直接操作数据库这样后面加功能、改字段都不会牵一发动全身。2.1 三层结构各自管什么小程序端只做三件事展示数据、收集输入、发起请求。它不判断“这个床位能不能分配”也不计算“报修单是否超时”这些规则全部下沉到云函数。云函数是整套系统的黑匣子每个函数对应一个明确的业务动作比如提交报修、审批入住、生成查寝记录。云数据库则按集合划分学生、宿舍、床位、报修单、查寝记录各占一个集合集合之间用学号、宿舍号做关联字段。这样切的好处是页面改版不影响业务逻辑业务规则调整也不用动前端。血泪经验是很多同学一开始图省事在页面里直接写数据库查询等到要加权限校验时发现每个页面都得改一遍返工量比一开始分层大得多。2.2 数据模型与集合划分数据模型是这套系统的地基字段定得糙后面查询和统计都会难受。下面这张表是我通常采用的集合划分和关键字段实际做的时候可以按需增减但关联字段一定要提前定好。集合名关键字段说明students_id、studentNo、name、gender、className、phone学生基础信息studentNo 唯一dorms_id、buildingNo、roomNo、capacity、currentCount宿舍信息roomNo 楼内唯一beds_id、dormId、bedNo、studentNo、status床位与学生的绑定关系status 取空闲/占用repairs_id、studentNo、dormId、content、status、createTime报修单status 取待处理/处理中/已完成inspections_id、dormId、inspector、score、remark、checkTime查寝记录score 为卫生评分字段命名统一用驼峰时间统一存时间戳而不是字符串这两条看着不起眼但能省掉后面排序和范围查询时的大量格式转换。床位表单独拆出来而不是把床位号塞进学生表是为了支持换寝和空床位统计这个设计在答辩时也比较好讲清楚。2.3 角色与权限的落地方式系统里通常有三类角色学生、宿管、管理员。学生只能看自己的信息和提交报修宿管能看本楼数据和处理报修管理员拥有全部权限。权限判断不放在页面里靠隐藏按钮实现而是在云函数入口统一校验。// 云函数入口统一做角色校验避免每个页面各写一套 const cloud require(wx-server-sdk) cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) exports.main async (event, context) { const { OPENID } cloud.getWXContext() // 从用户集合中查出当前 openid 对应的角色 const userRes await cloud.database().collection(users) .where({ openid: OPENID }).get() if (userRes.data.length 0) { return { code: 401, msg: 用户未注册 } } const role userRes.data[0].role // 按 action 分发每个 action 声明自己允许的角色 const actionMap { submitRepair: [student], handleRepair: [dormManager, admin], addInspection: [dormManager, admin] } const allowRoles actionMap[event.action] || [] if (!allowRoles.includes(role)) { return { code: 403, msg: 无权限执行该操作 } } // 校验通过后进入具体业务处理 return await handleBusiness(event, role, OPENID) }这段代码的关键点在于actionMap把“哪个动作允许哪些角色”集中声明在一处新增功能时只加一行配置不用去翻每个页面。OPENID由微信上下文直接给出不信任前端传上来的身份参数这是防止越权的基本做法。参数说明上event.action是前端约定的动作名event.payload携带业务数据返回统一用code加msg的结构前端按code判断成功与否。3. 核心模块实现报修、查寝与床位分配三条主流程模块实现阶段最忌讳平均用力把三条主流程做扎实系统就立住了。报修流程考验的是状态流转查寝流程考验的是批量录入床位分配考验的是并发下的数据一致性。3.1 报修流程的状态机设计报修单不是简单的增删改查它有明确的状态流转待处理 → 处理中 → 已完成中间允许取消。状态流转必须由云函数控制前端只能发起“申请变更”不能直接改状态字段。// 报修状态流转校验只允许合法跳转 const TRANSITIONS { pending: [processing, cancelled], processing: [done], done: [], cancelled: [] } async function updateRepairStatus(repairId, targetStatus, operatorRole) { const db cloud.database() const res await db.collection(repairs).doc(repairId).get() const current res.data.status // 检查目标状态是否在当前状态的合法去向里 if (!TRANSITIONS[current].includes(targetStatus)) { return { code: 400, msg: 不允许从 ${current} 变更为 ${targetStatus} } } // 学生只能取消自己的待处理单宿管才能推进处理 if (targetStatus cancelled operatorRole ! student) { return { code: 403, msg: 仅学生可取消报修 } } await db.collection(repairs).doc(repairId).update({ data: { status: targetStatus, updateTime: Date.now() } }) return { code: 0, msg: 状态更新成功 } }状态机写成常量表好处是规则一目了然答辩时被问到“如果用户重复点击完成怎么办”可以直接指着TRANSITIONS说非法跳转会被拦掉。updateTime每次变更都刷新方便后面做超时提醒。这里容易翻车的地方是前端也维护了一份状态文案两边对不上所以状态值统一用英文枚举中文只在展示层映射。3.2 查寝记录的批量录入与评分查寝是宿管的高频操作一层楼几十间宿舍一间间点开录入效率太低。我的做法是提供一个批量录入页按宿舍号顺序列出所有房间宿管逐间填评分和备注最后一次性提交。// 批量提交查寝记录逐条校验后写入 async function batchAddInspection(list, inspector) { const db cloud.database() const validList [] for (const item of list) { // 评分必须在 0 到 100 之间备注长度不超过 200 if (item.score 0 || item.score 100) { return { code: 400, msg: 宿舍 ${item.roomNo} 评分越界 } } if (item.remark item.remark.length 200) { return { code: 400, msg: 宿舍 ${item.roomNo} 备注过长 } } validList.push({ dormId: item.dormId, inspector, score: item.score, remark: item.remark || , checkTime: Date.now() }) } // 全部校验通过后再批量写入避免部分成功部分失败 await db.collection(inspections).add({ data: validList }) return { code: 0, msg: 成功录入 ${validList.length} 条 } }先全量校验再统一写入是为了避免“前五条成功、第六条失败”这种半截状态宿管看到报错后不知道哪些已经存了。批量写入用数组形式一次提交比循环单条写入少很多网络往返。评分范围定在 0 到 100备注限长 200这两个约束在页面输入框上也要同步限制前端拦一道、后端再拦一道双保险。3.3 床位分配与并发冲突处理床位分配是整套系统里最容易出问题的地方。两个宿管同时给不同学生分配同一张空床如果只是先查后写很可能都查到“空闲”然后都写成功最后一张床住了两个人。// 分配床位时用条件更新只有 status 仍为空闲才写入成功 async function assignBed(bedId, studentNo) { const db cloud.database() const res await db.collection(beds) .where({ _id: bedId, status: free }) .update({ data: { studentNo, status: occupied, assignTime: Date.now() } }) // updated 为 0 说明条件不满足床位已被占用 if (res.stats.updated 0) { return { code: 409, msg: 该床位已被占用请刷新后重试 } } return { code: 0, msg: 分配成功 } }关键在where条件里带上status: free把“检查”和“写入”合并成一次原子操作数据库层面保证只有第一个请求能改成功。返回409让前端提示刷新而不是静默失败。这个思路在换寝、退宿场景同样适用凡是涉及“占用状态”的变更都要用条件更新而不是先查后改。踩坑最多的情况是同学用doc(bedId).update()直接改绕过了状态条件并发问题就藏不住了。4. 避坑与常见问题上线前最容易翻车的五个点这一章是我带项目时反复强调的部分很多问题在开发阶段看不出来一到真实使用就暴露。下面五条按“现象 → 原因 → 解决”展开建议在提交前逐条对照。4.1 列表页首次加载空白现象是页面打开后列表区域一片空白下拉刷新才有数据。原因通常是onLoad里发起异步请求但没等数据回来就渲染了或者请求失败被静默吞掉。解决方式是在onLoad里调用统一的加载函数请求前先置loading状态失败时给出明确提示而不是留白。我一般会在页面 data 里放loading、list、error三个字段三种状态各有对应 UI。4.2 云函数超时导致提交失败现象是报修提交偶尔失败重试又成功。原因是云函数里做了多次串行数据库查询单次请求耗时逼近超时上限。解决方式是合并查询、减少往返能一次查出来的不要分三次查批量写入用数组提交。另外把非关键逻辑比如写操作日志放到主流程之后异步处理不要让用户等待。4.3 权限校验被前端绕过现象是普通学生通过修改请求参数调用了宿管接口。原因是权限只在前端隐藏了按钮云函数没有二次校验。解决方式就是第 2 章那套actionMap集中校验所有写操作必须经过云函数入口的角色判断前端隐藏按钮只是体验优化不是安全边界。4.4 时间字段格式混乱现象是列表排序错乱或者按日期筛选查不到数据。原因是有的地方存字符串、有的地方存时间戳比较时类型不一致。解决方式是全库统一存时间戳展示时再格式化成可读文本格式化函数只写一份放在公共工具里不要每个页面各写一套。4.5 换寝后旧床位未释放现象是学生换寝后原床位仍显示占用空床位统计偏少。原因是换寝逻辑只更新了新床位忘了把旧床位状态改回空闲。解决方式是把换寝封装成一个云函数事务式操作先释放旧床位再占用新床位任一步失败则回滚。这类跨集合的联动操作一定要在一个函数里完成不要拆成两次前端请求。5. 验收与答辩用一份检查清单把方案讲圆验收这件事我一般分两步走先自己按清单过一遍功能再准备一套能讲清楚设计取舍的答辩话术。功能验收不要凭感觉点几下按角色和流程列清单逐项打勾。验收项操作路径通过标准学生提交报修学生端 → 报修 → 填写提交列表出现新单状态为待处理宿管处理报修宿管端 → 报修列表 → 处理状态变为处理中完成后变已完成非法状态跳转直接调用接口改状态返回 400数据不变批量查寝录入宿管端 → 查寝 → 批量提交全部成功或全部失败无半截数据床位并发分配两个账号同时分配同一床位仅一个成功另一个提示已占用越权访问学生身份调用宿管接口返回 403答辩时最容易被问到的三个问题提前准备好答案为什么选小程序而不是 App答分发成本和开发环境统一数据一致性怎么保证答条件更新和集中校验权限怎么防绕过答云函数入口统一判断。回答时尽量落到具体字段和具体函数不要停留在“做了权限控制”这种层面。还有一个实用技巧答辩演示前把数据库里的测试数据清一遍只留几条能串起完整流程的记录。演示时按“学生提交 → 宿管处理 → 管理员查看统计”的顺序走一遍比随机点页面有说服力得多。我吃过一次亏演示时列表里混着几十条脏数据翻了三页才找到要展示的那条场面很尴尬。从那以后我每次演示前都强制走一遍数据清理和流程彩排把要讲的每一步都实际点一遍。希望帮到你。本文还有配套的精品资源点击获取