资讯动态

高校公寓报修系统开发:uni-app跨端与Spring Boot多角色权限设计

发布时间:2026/9/19 17:02:43 来源:尧图企业网站定制
1. 项目概述与需求拆解1.1 这个报修系统到底要解决什么问题高校学生公寓里的报修表面上是个“灯坏了、水管漏了”的小事但真正运营过宿舍管理的人都知道这里面的坑一点都不少。学生报修找不到人不知道找谁报修之后没有进度反馈只能干等维修工一天接几十单纸质单子容易丢、容易漏做完一单还要回办公室登记宿管和管理员更头疼月底想统计一下各类报修占比、维修耗时全靠翻本子。这些问题叠加在一起就把一个“小需求”撑成了一个“多角色协同”的项目。我做这个高校学生公寓宿舍报修管理系统App和小程序核心目标不是做一个“报修登记表”而是把“学生报修—维修工接单—管理员派单/监督—事后评价”这整条链路打通。学生不用再跑值班室填单子维修工手机上看单、干完拍照回传管理员后台能看实时数据和报表所有环节都有据可查。整个系统面向四种角色学生、维修工、宿管员、系统管理员。有人会问宿管员和系统管理员有什么区别后面我会详细拆。简单说宿管员管的是本栋楼的报修流转系统管理员管的是全局账号、楼栋、角色权限这一类底层配置。角色一多权限设计就成了第一个硬骨头。1.2 为什么选择“App 小程序”双端形态最初我只规划了一个微信小程序因为小程序免安装、用完即走学生接受度高。但做到一半好几个公寓管理方提了个需求维修工端最好有一个独立App因为维修工每天高频使用且经常要在现场拍照片、接语音通知小程序容易被聊天消息顶掉操作路径太长。所以最终方案定成了学生端用微信小程序维修工端和管理端用App。这里有个关键决策两端不能各写一套否则后续维护成本翻倍。我选择了uni-app作为前端框架一套代码同时打包成微信小程序和Android/iOS App。实测下来90%以上的业务代码可以复用只有涉及原生能力比如扫码、消息推送、蓝牙打印的部分需要做条件编译。这个项目的本质是一个典型的多端、多角色、状态驱动的管理类应用。读者如果是学生、刚入行的开发人员或者宿管系统相关从业者都能从这里找到可以直接落地的设计思路。本文后面所有内容都是围绕“多角色如何协同、状态如何流转、权限如何控制”这三个问题展开的这也是同类系统最值得抄作业的部分。2. 技术选型与整体架构设计2.1 前端跨端方案的取舍我先说结论这个项目的前端选了uni-appVue 3语法糖版本后端选了Spring Boot MyBatis-Plus数据库用MySQL缓存和部分消息用Redis文件存储用阿里云OSS。这套组合在很多校园管理类项目中都跑得比较稳。为什么不用原生开发原生Android 原生iOS 微信小程序三端要写三套代码。这个项目角色多、页面多学生端报修表单、维修工端接单列表、管理端数据看板、审批流、消息中心三套代码的代价不是“多写一遍”而是“改一个字段要同步三处”上线后修bug都修不过来。跨端框架在这个场景下是明显的更优解。选uni-app而不是Taro有我的考虑。Taro的React写法我也熟但这个项目里小程序端是学生主力端微信小程序的兼容性和原生组件调用频次很高。uni-app对微信小程序的原生能力封装更直接比如uni.chooseImage、uni.scanCode、uni.login这些API到小程序端能直接映射成微信接口遇到问题社区里资料也多对学生开发者和中小团队更友好。2.2 后端服务如何划分模块后端如果按微服务拆对于这个体量的宿舍报修系统反而过度设计。我采用“单应用 模块分包”的方式同一个Spring Boot工程里按功能域拆成auth模块、user模块、repair模块、notification模块、statistics模块。思考逻辑是这样的用户量和并发量在校园场景下都有明显波峰波谷——比如晚上熄灯前后报修集中平时基本空闲。单应用部署成本低一台2核4G的云服务器就能跑起来。但模块之间要隔离清楚尤其是权限校验、状态流转这类核心逻辑绝不能散落在各个Controller里。实际写代码时每个模块的Service是独立接口模块之间通过Service方法调用不直接访问对方的Mapper。这样以后真需要拆分服务边界还留着。认证授权方面我用的是Sa-Token框架。相比Spring SecuritySa-Token的鉴权注解更轻量支持角色权限的细粒度控制比如我可以在接口上直接写SaCheckRole(admin)配合自定义拦截器做到接口级权限管理。这个项目角色多这种注解式鉴权的开发效率优势很明显。2.3 小程序与App的数据交互设计双端数据交互遵循统一的RESTful API规范所有接口返回格式固定为{ code: 0, message: success, data: {} }code为0表示成功非0数值对应具体错误码比如1001表示token过期1002表示无权限2001表示报修单状态不允许当前操作。这种约定可以在小程序端用一个统一的request封装处理遇到1001自动跳转登录页遇到2001直接toast提示避免每个页面都写一遍错误处理逻辑。关于接口安全除了登录态token我还对写操作接口做了简单防重处理。学生连点“提交报修”按钮如果不做处理大概率会生成重复工单。我的做法是前端提交时生成一个uuid作为requestId后端Redis里存5分钟同一个requestId只允许处理一次。这个细节在演示和答辩时都很加印象分实际也真的能挡住重复提交。3. 数据库建模与核心表结构3.1 用户表与角色权限设计的正确姿势多角色系统的第一张核心表就是用户表。很多初学者爱把角色写死成字段比如user表里放一个role字段值是student或worker。这样做在角色很少时勉强能用但这个项目里有学生、维修工、宿管员、系统管理员而且同一个人可能既是学生又是宿管员——比如研究生兼任公寓助理。用死字段就废了。我的设计是user表只存账号、密码、姓名、手机号、头像等基础信息角色关系单独用user_role表维护多对多。再配合role表、permission表、role_permission表形成标准RBAC模型。实际操作时我不建议给每个角色都分配一串具体权限点而是采用“角色 多个权限点集合”的思路。学生角色的权限点包括repair:add、repair:list:own、repair:comment维修工角色的权限点包括repair:list:assigned、repair:accept、repair:complete管理员角色覆盖全部。这样建表时只需要维护三张关联表后端拦截器校验当前用户是否拥有对应权限点即可逻辑清晰后续加新角色也方便。3.2 报修单状态流转设计报修单是系统的数据核心状态字段我用int类型存储而不是varchar存中文因为状态字段要参与逻辑判断和统计聚合数字更可靠。我定义的状态流如下状态值状态含义当前可操作角色下一步可选状态0待派单宿管员1已派单1已派单维修工2处理中/ 4已驳回2处理中维修工3已完工3已完工学生无触发评价4已驳回宿管员1重新派单这里有一个特别容易被忽略的细节驳回操作到底是谁做的过去纸质工单时代往往是维修工上门后发现不属于自己负责范围再回来改。线上系统我改成维修工可以把订单退回但退回不是直接变成“待派单”而是先变成“已驳回”由宿管员确认后重新派单。为什么要加这个中间状态因为如果允许维修工直接改回待派单可能出现维修工嫌麻烦故意退单宿管员还不知道的情况。加一个驳回状态退回操作就有记录、有留痕、有审核责任明确。3.3 消息通知与评价体系的补充除了报修主表我额外设计了三张关联表repair_log、repair_message和repair_evaluation。repair_log是操作日志表记录每一次状态变更、谁改的、从什么状态改成什么状态、备注是什么。这张表最大的价值不是给学生看而是管理员事后追溯。比如某个维修工经常超时管理员可以拉出日志逐条看是接单接晚了还是完工拖了定位问题一目了然。repair_message是消息通知表学生提交报修后系统要向维修工和管理员推送消息状态变化后要向学生推送进度通知。消息表结构需要包含消息类型、关联报修单id、发送对象、是否已读等字段。推送方式上小程序端用订阅消息App端用极光推送这部分我在后面第5章详细说。repair_evaluation是评价表关联报修单包含评分1到5、评价内容、匿名标识。学生只有状态为“已完工”才能评价且同一张单只能评价一次。评价数据汇总后用于管理员考核维修质量。4. 多角色权限与业务流程实现4.1 学生端从提交报修到进度跟踪学生端的完整流程是登录小程序 - 提交报修单 - 查看进度 - 完工后评价。登录我用的是微信登录前端调uni.login获取code后端拿code换openid再和本校学生数据做绑定。这里有个坑校园场景下学生身份通常需要和学号绑定。我的做法是首次登录后弹窗绑定学号姓名通过Excel导入的名单做校验。绑定过之后下次登录直接识别身份。提交报修单时除了必填的楼栋、房间号、报修类型、问题描述我加了两个重要字段预约时间段和现场图片。预约时间段非常实用比如学生下午有课可以约下午三点后维修维修工安排路线时更合理。现场图片用uni.chooseImage选择或拍照传给后端前先做压缩避免一张原图五六MB传到OSS上既慢又费流量。我的压缩参数是宽1200、质量0.8实测在清楚展示故障细节的前提下单张图片能压到150KB左右。进度跟踪页面是一个状态时间轴。这个时间轴不是前端写死的而是后端根据repair_log动态生成的。比如一条记录“10:20 提交报修”、“10:35 宿管员已派单给张师傅”、“14:02 维修工开始处理”、“15:10 维修工提交完工”。学生看到的是一个闭环过程心里有底投诉率明显下降。4.2 维修工端接单、转单与完工维修工端是App使用频率最高我的交互设计原则是“减少输入、一键操作”。首页是待办列表顶部展示今日接单数、已完成数、平均处理时长三个数据卡下方是待处理报修单列表。每张卡片显示地址、报修类型、问题描述、预约时段、是否有图片右侧一个大大的“接单”按钮。接单逻辑里有一个细节接单不等于开工。很多系统把接单和开工混为一谈维修工一点“接单”就开始计时不合理。维修工可能在路上、在食堂或者一次接三单一起处理。我拆成两个动作接单表示接受这个任务和开工表示到现场开始处理。开工时记录start_time完工时记录end_time这样“平均处理时长”统计的才是真实的维修耗时而不是从接单开始算的待命时间。这个拆法在管理端看数据时会发现差异很大能准确反映维修工的效率。完工操作要求上传完工照片和填写配件费用。配件费用很重要不然每个月对账的时候维修工说买了个水龙头花了35宿管员根本不知道真假。我在完工表单里加了材料费字段后端记录后管理员可以定期导出对账。转单功能也保留在详情页里维修工填写转单原因后工单状态变为“已驳回”回到宿管员手里重新分配。4.3 管理端派单、统计与监督宿管员端和系统管理员端虽然都在App里但入口权限不同。宿管员的核心场景是“派单”。当学生报修新单进来列表里是待派单状态宿管员可以手动选择维修工也可以按规则一键自动派单。我的自动派单规则不复杂先匹配维修工负责区域再按当前待接单数量排序单量最少的优先。这个规则对分配均衡性很有帮助能避免“能干的累死、闲的闲死”。系统管理员则看到的是全局视图全校报修总量、各楼栋分布、各报修类型占比、维修工平均响应时间、完工率、超时率等。统计页面我用了echarts小程序端可以用ec-canvas组件App端用uni-app插件市场的echarts包装组件。数据看板能跑起来不难难的是指标定义。比如“响应时间”我定义为“报修提交到维修工点击接单的时间差”“处理时长”定义为“开工到完工的时间差”这两个指标分开统计管理层才看得明白问题出在派单环节还是维修环节。5. 小程序端关键功能落地细节5.1 用户登录与角色识别小程序端登录我采用wx.login获取临时code传给后端后端调用微信接口换取openid和session_key。拿到openid后去user表查openid是否绑定过如果绑定过直接签发token返回。如果没有绑定则返回一个标志位前端跳转到“学号绑定”页。角色识别放在token里。后端签发token时把当前用户的角色列表放进payload前端拿到token后解析就能知道当前角色。不同角色进入小程序首页会看到不同菜单——学生看到“我要报修”“我的报修”宿管员看到“待派单”“派单管理”“楼栋统计”。这里说说我在角色切换上踩过的坑同一微信用户可能既是学生又是宿管员比如研究生助管。一开始我用一个“当前角色”字段存Redis用户切换角色时更新。但这是有bug的——如果用户在A手机登录学生端又在B手机登录宿管端后登录的会把前面顶掉导致A手机上的操作突然变无权。后来我改成token里携带“当前角色”不同的登录会话各自独立角色切换时重新签发新token旧token自然失效。这样更符合实际使用习惯。5.2 报修表单动态配置报修类型的选项不是写死在页面上的我放在后端配置表里。为什么要动态因为不同季节、不同楼栋常见故障类型会变化。夏天空调报修多冬天热水器报修多有的新楼主要是门窗问题。运维人员直接改后台配置前端表单自动更新不用发版。表单里“问题描述”我限制为10到200字太短无法判断问题太长影响阅读。同时加上图片上传最多9张第一张作为封面图。报修类型切换时会联动展示不同的隐患提示。比如选择“电路故障”提示“如发现冒烟、火花请立即离开并及时报告值班室”选择“水管漏水”提示“请先关闭室内阀门”。这个细节虽然简单但能体现产品对安全场景的深度思考答辩或演示时是加分项。5.3 图片上传与定位获取图片上传推荐策略选完图片先在前端压缩再用uni.uploadFile上传到后端接口后端拿到后转存OSS并返回URL。这里要注意小程序的上传域名必须配置到微信公众平台后台的白名单里而且必须是HTTPS。第一次联调时我传图片一直报“url not in domain list”折腾半天才发现域名只加了request合法域名忘了uploadFile合法域名。这两个域名配置是分开的request合法域名管普通请求uploadFile合法域名管文件上传容易漏。定位获取用uni.chooseLocation或者wx.getLocation。学生报修时自动定位可以带出楼栋信息但有误差尤其校内楼栋密集的时候。我最终做成“自动定位作为参考楼栋和房间号必须手动准确选择”。楼栋和房间数据从后端接口拉取保证和管理系统里的数据一致而不是让学生自由输入。自由输入的结果一定是“3栋”“三号楼”“3号楼A区”这种混乱数据后续统计直接没法看。5.4 小程序顶部标题与页面配置有人会问页面顶部标题有什么好讲的实际上这里有个非常实际的需求同一个小程序不同角色进入首页要显示不同标题。学生端显示“学生公寓报修”宿管员端显示“公寓管理平台”。动态设置标题微信小程序里可以用wx.setNavigationBarTitleuni-app对应uni.setNavigationBarTitle。但要关注时机问题——如果页面onLoad的时候token还没解析出来标题就设置晚了。我的做法是在登录成功拿到角色后先更新全局状态再通过uni.reLaunch跳转到对应首页首页在onLoad里同步读取角色并设置标题。如果用户已经登录App冷启动直接进入首页我会在main.js里先做一次本地token检查再决定标题展示避免闪一下“学生公寓”再跳成“公寓管理平台”的尴尬。6. 常见问题与排查技巧实录6.1 登录用户不是该小程序的开发者这个报错我在联调阶段遇到过好几次尤其是团队协作时。学生A是项目创建者学生B负责小程序端联调用B的微信扫码预览时就报“登录用户不是该小程序的开发者”。原因很简单权限没配。需要项目创建者登录微信公众平台在“成员管理”里添加B的微信号并赋予“开发者”权限。还有一个类似的坑真机调试也需要真机上的微信账号是开发者不然会白屏。用开发者工具模拟器没事一到真机就翻车多半是这个原因。如果团队成员很多建议在项目一开始就拉一个权限清单谁是项目管理员、谁是开发者、谁是体验成员全都配上。否则联调的时候人等在那边权限搞半天很影响进度。6.2 图片上传失败与域名白名单图片上传失败的问题一半以上是域名配置问题另一半是文件大小超限。微信小程序对上传文件大小有限制单个文件不能超过10MB超过直接失败。我的压缩逻辑已经控制在了200KB左右基本触不到上限。但如果用户从相册选择了一张体积特别大的图压缩没来得及执行就上传也会出错。所以我在选择图片后、上传之前加了一个临时文件检查超过2MB就拒绝并提示用户重新选择。虽然这会导致用户需要重新操作但也好过上传失败毫无反馈。域名白名单问题还有一个隐蔽的点如果小程序使用了“不校验合法域名”的开发开关本地一切正常体验版和正式版就不行。因为体验版和正式版强制走合法域名校验。排查时一定要确认开发工具里那个勾是去掉的否则会被假象骗一天。6.3 消息通知收不到学生端小程序的消息通知我用的是微信订阅消息。订阅消息有严格的模板机制一个模板只能推一条而且需要用户触发订阅动作。学生提交报修时我调用wx.requestSubscribeMessage让用户授权订阅“报修进度通知”和“完工通知”两个模板。但微信规定每次提交只能弹出一次订阅授权最多能选三个模板。这里的问题是如果用户拒绝授权后续状态变化就推不出去。我的处理方案是不强求但在学生查看报修详情页时如果发现某个状态流转还没有被通知过就再次引导用户点击“开启进度提醒”按钮重新拉起订阅授权。另外订阅消息是一次的授权一次只能推一条不能持续推。所以这个项目里真正的强提醒放在维修工端的App推送——极光推送可以持续、可靠地触达学生端的小程序订阅消息只作为补充。如果学生端订阅消息一直收不到还有一个常见坑模板ID填错或者模板里的关键词字段顺序和后端传入的不一致。订阅消息的模板内容是一段文字比如“报修编号:{{thing1.DATA}} 状态:{{thing2.DATA}}”后端拼接时字段必须严格对应多一个空格都可能导致推送失败。排查时先看后端日志的推送返回码微信会明确告诉你哪个字段不匹配。6.4 多角色切换时页面缓存混乱多角色系统最容易出现的一个问题角色切换后页面还保留上一个角色的数据。比如宿管员A切换到学生身份后首页本应显示“我要报修”结果因为页面栈里有管理页面的缓存直接跳到了派单列表。这个问题主要是前端路由管理和页面生命周期没处理好。我踩过坑后总结了几条规矩角色切换必须用reLaunch或redirectTo不能用navigateTo。navigateTo会保留页面栈上一层的管理页面还在内存里。进入首页前先调用后端“获取我的角色信息”接口拿到角色后动态渲染菜单不做本地硬编码。涉及权限的页面请求失败时不能只弹个“无权限”就完事要主动触发一次角色刷新防止后端权限已变但前端还按旧身份渲染。做完这三条之后角色切换的bug基本消停了。核心原则是角色是后端数据前端只负责展示不要在本地缓存持久化身份信息。7. 上线与运营阶段的几个提醒小程序上线前备案这一步现在很多同学会卡住。微信小程序备案时要填写服务内容标识、前置审批项等。宿舍报修管理系统属于“生活服务/便民服务”类目不需要前置审批。备注信息建议直接写“高校学生公寓宿舍报修管理服务为学生提供在线报修、进度查询和评价功能”简明扼要别写太泛也不要包含小程序名称以外无关内容。审核过程中如果被要求补充材料一般是让你说明数据使用范围和学生信息保护措施提前准备一段说明文案能省不少时间。App上架的话Android各应用商店需要软著证书高校内部系统如果只在校园网内使用也可以选择不打包上架直接让维修工用Android安装包配上极光推送就够了。iOS上架需要开发者账号如果只是校内使用可以考虑用TestFlight做内部测试分发成本低一些。数据安全方面学生报修会涉及房间号、手机号这些都属于个人敏感信息。我建议在数据库层面对手机号字段做加密存储接口层做脱敏返回管理员后台完整展示时也要有操作日志。校园系统一旦出现学生隐私泄露不仅仅是技术事故搞不好要背处分这个底线必须守住。8. 关于这套系统我最后想说的几句整个项目从需求调研到双端上线我一个人前后写了大约六周工作日晚上和周末都泡在代码里。说实话最累的不是写代码而是反复跟宿管员、维修工确认流程细节。比如“接单”和“开工”为什么要分开一开始宿管员觉得多此一举等月末看到统计报表里维修耗时明显下降才认可这个设计。这说明一个道理多角色系统的核心难点不是技术而是你愿不愿意站在每个角色的位置把他们每天要做的事在脑子里过一遍。如果你也要做类似的项目我建议先别急着建表写接口花一个下午去学校公寓值班室坐着看看维修工是怎么接电话的宿管员是怎么在本子上记单子的学生是怎么气冲冲跑来催的。把这些场景画成流程图再动手写代码效率会高得多。我共享过一版简化版的数据库设计文档给身边同学很多人都直接拿来改了改。这里我可以分享的印象最深的一个经验是报修单的状态机一定要从第一天就设计清楚不要边写边改。一旦数据跑起来了状态加一个值意味着所有的统计报表、消息通知、页面判断全都要跟着动改一次成本极高。状态机宁可多想几个未来可能出现的状态也别图省事只留几个。比如留一个“已取消”状态给学生主动撤销留一个“待评价”状态做被动超时自动确认这些看起来用不着实际运营中一定会遇到。做这类校园管理系统收获最大的不是学会了某个框架而是学会怎么把一群线下流程混乱、角色诉求各异的真实需求拆成一套可运转的系统逻辑。这个过程比刷一百道面试题都有用。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价