news 2026/10/7 4:20:16

微信小程序+Vue3+Spring Boot大创项目管理系统全流程实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
微信小程序+Vue3+Spring Boot大创项目管理系统全流程实战

做毕设最怕的就是拿到了“只有登录界面和几个空页面”的假源码,看起来功能一堆,一跑全是死路。我这次把一套基于微信小程序的大学生创新创业训练项目管理系统完整跑通了全流程:学生打开小程序申报项目、上传材料、查进度,指导老师和学院管理员在后台审核,校级管理员通过Vue3后台管理系统做立项、拨款统计和结题验收,三端数据互通,源码整理好之后可以直接当毕设交。这篇就按我实际的开发顺序把整套系统掰开揉碎讲清楚,适合拿毕业设计做管理系统的同学参考,也适合想在公司内部快速搭一套轻量级项目管理工具的人。

1. 项目背景与系统定位:大创工程到底要管理什么

1.1 大创项目业务流拆解

大学生创新创业训练项目(下面就叫“大创”)大多数学校按这三类走:创新训练、创业训练、创业实践。不管哪种类型,业务主线都特别统一:学生组队申报,指导老师审核,二级学院初审,学校创新创业管理部门组织立项评审,然后是漫长的执行期,中间有中期检查,最后结题验收、登记成果。

你没看错,这套流程跟论文投稿的外审流程非常像——提交、层层审核、意见返回、修改重提,全部围绕“一个项目档案”展开。所以做系统之前千万别急着自己发明状态,先把学校的真实流程画出来。

大多数学校实际用到的状态可以收敛成这几个:

状态含义操作角色
待提交学生编辑中,未正式申报学生
待指导老师审核已提交,等老师点头指导老师
待学院审核老师通过,学院管理员初审学院管理员
待校级审核学院通过,校级评审校级管理员
已立项评审通过,正式立项校级管理员
进行中项目执行阶段,可提交中期材料学生/指导老师
待结题学生提交结题申请学生
已结题验收通过,归档校级管理员
已驳回任意环节被退回,学生修改后重新提交各审核角色

这个状态流转表是整个系统的定盘星。我的建议是先把这张表画出来再做数据库,否则做出来的流转一定乱。

1.2 系统角色与核心模块边界

这套系统我做成了四个角色:学生、指导老师、学院管理员、校级管理员。理论上还可以拆出独立的评审专家角色,但毕设阶段学院管理员和评审角色合一,演示效果反而更集中。

  • 学生端(微信小程序) 页面包括:微信授权登录、手机号绑定、项目申报表单、我的项目列表、项目详情、中期/结题材料提交、审核进度时间线、消息通知。

  • 指导老师端(微信小程序内复用) 老师登录后看到的是“我指导的项目”和“待我审核”两个入口,能下载学生提交的材料,填写审核意见。

  • 管理后台(Vue3 Web) 学院管理员能看本院所有项目,做初审;校级管理员能跨学院看全部项目,立项评审、结题验收,还能做全校统计。

功能边界这里有个坑非常典型:很多人把“学生申报”和“后台审核”做成两套系统,学生交一次材料、管理员用Excel另存一次,接口没通。毕设答辩的时候面试老师最在意的是闭环——你在小程序提交,后台能收到;后台驳回,小程序能看到驳回理由。这一步打通以后,系统逻辑上才是完整的。

2. 技术选型解析:小程序原生 + Vue3 + Spring Boot 这套组合为什么顺

2.1 小程序端:原生还是 uni-app

之前有个读者一直纠结要不要用 uni-app,说以后可以顺便发App。说实话,毕设项目我不推荐为了“以后可能跨端”牺牲当下的确定性。原生微信小程序开发的包最小、调登录授权和上传接口最直接、真机预览出问题最好排查。uni-app还要维护一套自己的编译链路,真机调试的时候报错定位层级多一层,除非你的标题明确要求“基于uni-app的跨端应用”,否则原生是更稳的选择。

这一套小程序我用的原生语法,没有任何第三方UI框架,表单是自己写的。不是不能用ColorUI或者Vant,而是大创申报表单的字段大多是非标准的,自己写可控性高、改起来快。自己写这几个表单页面的工作量:一个通用输入组件、一个日期选择器、一个文件上传组件、一个单选框分组,总共不到2天。

2.2 管理后台:为什么用 Vue3 + Element Plus

现在做后台管理系统,尤其是一年以内的新项目,直接上 Vue3 + Vite + Element Plus + Pinia 是共识。Vue3组合式API写业务逻辑比Vue2的Options API舒服得多,数据响应式粒度更细,Element Plus组件对表单回显、表格分页、弹窗确认的支持极其成熟,两天就能把 CRUD 界面拼出来。

我用到的具体组件:el-table 做项目列表、el-tabs 切审核状态、el-form 做筛选、el-upload 做成果材料预览、el-statistic 做统计卡片。路由用的 Vue Router,动态菜单根据登录用户的角色过滤,取数用的 axios 封装拦截器,token 存在 localStorage,刷新后重新拉用户信息。

另外要说一句,毕设源码里“后台管理系统模板”很多人直接下个现成的然后填页面,这个思路高效,但一定要跑通动态路由和权限控制,否则面试一问就露馅。

2.3 服务端:Spring Boot + MySQL + 事务设计

服务端我使用的是 Spring Boot 2.7 + MyBatis-Plus + MySQL 8,身份认证选择 JWT。很多教程喜欢给毕设上 Spring Security,但如果你自己没玩熟它,光放行规则就能卡你两天。我的方案很简单:一个 HandlerInterceptor,读 Authorization 里的 token,校验后把 userId、角色塞进请求上下文,只有需要权限的接口手动加个注解,逻辑清楚还不用学 Spring Security 那套过滤器链。

数据表是这个系统最值得花时间设计的地方,我最终落成这几张核心表:

  • user:用户表,openid、昵称、头像、手机号、角色、学院ID
  • project:项目主表,项目名称、类型、级别、金额、状态、申报学生ID、指导老师ID、学院ID
  • project_member:项目成员表,一个项目多名学生
  • review_record:审核记录表,谁在什么时间把项目从什么状态变成了什么状态,附带意见
  • material:材料表,项目ID、材料类型、文件URL、上传人ID、上传时间
  • fund_detail:经费明细表,金额、用途、凭证附件、审核状态

核心注意点:审核记录表必须有。没有这张表,系统就没有操作留痕,学生被驳回后老师也看不到历史意见,管理审计完全为零。

3. 小程序端核心功能:登录、导航栏、申报上传一整套落地方案

3.1 微信登录与手机号获取的完整链路

先说登录,这套逻辑在所有微信小程序系统里几乎通用。前端调用wx.login()拿一个临时 code,传给后端,后端拿着 code 去微信接口换 openid 得到用户唯一身份。

很多同学把 code 换出来的 openid 直接当前端账号来用,这样做不安全,openid 应该只在后端和微信之间流转。我在后端/api/auth/login里做了这么几件事:接收 code,调微信 code2Session 接口,查数据库判断用户是否存在,不存在就自动注册一个新账号,然后签发 JWT 返回给前端。

手机号这块是个容易踩重坑的地方。新版微信要求通过<button open-type="getPhoneNumber">获取用户授权,你可以从e.detail.code里拿到一个手机号 code,再传给后端。注意:前端拿不到手机号明文,必须在后端用 code 调微信接口换取,个人主体的小程序没有这个权限,只能先用手机号登录做兜底方案。毕设演示建议做两套:微信授权登录 + 手机号绑定,这样评审现场即使网络环境不稳定也不会卡在登录环节。

代码里处理好 token 过期就行:axios 响应拦截器检测到 401,跳回登录页并提示重新授权,同时清理本地用户信息。

3.2 自定义导航栏高度适配,别再用固定值

这可能是小程序开发最“小但磨人”的问题。如果你选择自定义导航栏(为了放好看的标题和返回按钮),就不能把导航栏高度写成你 iPhone 模拟器上的数值,安卓刘海屏、全面屏、不同字体缩放下的胶囊位置都不一样。

封装好的工具函数长这样:

// utils/navigation.js function getNavInfo() { const sysInfo = wx.getWindowInfo() || wx.getSystemInfoSync(); const menuBtn = wx.getMenuButtonBoundingClientRect(); const statusBarHeight = sysInfo.statusBarHeight || 20; const navBarHeight = (menuBtn.top - statusBarHeight) * 2 + menuBtn.height; return { statusBarHeight, navBarHeight, menuBtn, totalTopHeight: statusBarHeight + navBarHeight, }; }

这个公式的逻辑是:胶囊按钮垂直居中于导航栏,导航栏高度等于胶囊上边界到状态栏下边界的距离乘以 2 再加胶囊自身高度。把所有页面自定义导航的padding-top设为totalTopHeight,再把胶囊右侧留出间距。我实测过 iOS 全面屏、安卓带虚拟按键的机型都没出现过“标题压到胶囊下面”的问题。

3.3 申报表单、多文件上传和列表分页

申报表单是学生端最重的页面。字段包含项目名称、项目类型(单选框)、级别(校级/省级/国家级)、预算金额、开始截止日期、项目简介,动态添加成员。表单校验放在前端做一层、后端做一层,前端用正则判断金额和必填项,后端拒绝空值;后端校验千万别省,因为数据分析页和统计看板都依赖这些字段的质量。

文件上传用wx.chooseMedia选择图片/文件,然后wx.uploadFile把文件POST到后端/api/upload,后端返回文件URL后,前端再把URL存进表单。UploadFile 的时候name字段要和后端 MultipartFile 参数名一致,否则你会收到“Required request part 'file' is not present”。

项目列表页最明显的体验优化是“进度时间线”。我用一个横向的progress-steps组件展示八个阶段,当前状态高亮,已完成的给绿色。页面改动也很小,后端返回status数值,前端映射成状态描述。列表的接口自带分页,page和size参数控制,触底加载的时候page + 1,下拉刷新重置到第一页。

4. 管理后台与审核链路由零到一的实现过程

4.1 动态路由与按钮权限:前端隐藏不等于安全

后台菜单按角色渲染,这一步很容易做:后端登录接口返回用户对象时带上role,前端根据角色过滤菜单数组,把没有权限的路由从router.addRoute里排除掉。细到按钮级别,我用了一个自定义指令控制“审核”按钮只对特定角色展示。

// 自定义 v-permission 指令 app.directive('permission', { mounted(el, binding) { const role = store.getters.role; const allowed = binding.value; if (allowed && allowed.every(r => r !== role)) { el.parentNode && el.parentNode.removeChild(el); } } });

不过要反复说一个原则:前端隐藏菜单只是用户体验,不是安全边界。后台每个接口都要校验角色,比如驳回项目接口必须校验当前用户是审核角色且只能操作本学院的项目,否则别人知道你的接口路径直接拿 token 调用就能越过 UI 操作数据。

4.2 审核状态机与并发放行

审核流程最怕的是两个问题:一是状态乱跳,学生明明还没提交,老师那边就显示“待结题”;二是并发,管理员和老师同时点击通过,数据库里状态被写了两遍。我的方案是在 project 表加一个status字段,每次审核都是带条件更新。

UPDATE project SET status = #{nextStatus}, audit_opinion = #{opinion}, audit_time = NOW() WHERE id = #{id} AND status = #{currentStatus}

上面 SQL 的判断条件保证了只有一个审核请求能成功,后提交的那个因为 status 已经不匹配会返回 0,然后我在 Java 里判断更新行数,如果为 0 就抛异常提示“项目状态已变化,请刷新后再试”。这不是什么高深的分布式锁,但对单个项目记录的并发更新来说足够可靠。

状态迁移用枚举定义,前端直接展示中文描述,后端审核接口用switch判断当前用户角色是否允许这个迁移。代码看起来多,但逻辑迁移一目了然。审核意见必填,驳回时必须填写理由,学生端首页会直接展示最新一条审核意见。

4.3 首页统计看板和报表SQL

管理员打开后台第一眼就是统计看板,这直接决定了系统“像不像一个真正的管理平台”。我做的是四个数字卡片:项目总数、待审核数、立项数、结题数,下方两个图表——各学院项目数量柱状图、立项级别占比饼图。

柱状图的数据来自一条 SQL:

SELECT college_name, COUNT(*) AS cnt FROM project WHERE deleted = 0 GROUP BY college_name ORDER BY cnt DESC

级别占比的SQL类似,GROUP BY level 就行。图表用的是 ECharts,按需引入柱状图和饼图,体积也不大。这类统计不需要在服务端额外建表缓存,数据量还没到那个级别,实时查询完全没问题。

后台管理端我还有一个特别实用的功能:按照“全部/待审核/已立项/已结题”条件筛选列表,配合分页和关键词搜索。这个看起来不重要,但在演示的时候可以用“输入关键字”快速给学生找到某个项目,省去翻页的尴尬。

5. 部署、避坑与压测经验,还有那些只写在文档角落的细节

5.1 小程序2MB限制与分包策略

微信开发者工具里主包超过2MB直接编译不通过,这是很多同学第一次跑毕设源码最常见的报错。源码里如果包含大量本地图片、引了几个体积大的 npm 包,很容易爆。

我的处理策略:所有本地图片压缩后再放,图标能用手绘 SVG 就不用 PNG;目录结构上把“我的项目”相关页面拆到分包里。

在app.json中这样配置分包:

{ "pages": [ "pages/index/index", "pages/login/index" ], "subpackages": [ { "root": "pages/project", "pages": ["project-list", "project-detail", "project-apply"] } ] }

分包之后,主包只留首页、登录页和公共组件,剩下申报、详情等全放分包里,主包体积立刻压下来。另外上传的文件全部走服务器,小程序里只存URL字符串,不要把图片Base64直接塞进setData,那样又慢又占包体。

5.2 真机调试、抓包与常见错误码

真机调试的时候微信开发者工具自带的调试器够用,但想抓 HTTPS 接口具体返回内容,我还是习惯开 Charles 或者 Reqable 做代理:电脑和手机连同一个局域网,手机代理指向电脑端口,安装证书后就能看到每个请求的请求头和响应体。

注意抓包调试只针对自己开发的程序,装证书的时候微信的代理开关也要对,安卓7.0以上默认不信任用户证书,调微信小程序不一定能直接解开,很多时候更是直接抓不到。我的经验是:先用开发者工具把接口调通,真机验证只是看 UI 和流程,抓包不到就靠前端日志和后端日志配合排查。

常见的微信小程序错误码也列成一个速查表:

报错原因处理
10002code 失效或 session_key 过期重新调 wx.login 拿新 code
401JWT token 失效/过期走登录流程重新获取
404接口路径对不上检查后端/api前缀和前端 baseURL
500后端异常看 Java 日志,多半是 SQL 或空指针
Invalid code前端 code 被用了两次后端缓存 code,勿重复查验

5.3 部署上线之前要确认的几件事

后端我是放在云服务器上,流程是:打包 jar 丢到服务器,用nohup跑,再用 Nginx 做反向代理和 HTTPS 终止。前端小程序发布前要在微信后台配置 request 合法域名,域名必须要备案过的 HTTPS,开发阶段可以勾选“不校验合法域名”,但体验版和正式版必须配置,否则请求直接被拦掉。

很多人忽略了文件存储路径的问题。如果上传文件存放在服务器本地,重启应用前要把临时目录加进配置,或直接用公网可访问的静态目录映射。有条件的话建议用一个专门存文件的域名地址,这样小程序端上传和预览用的都是https://file.xxx.com/...,不会和业务接口搅在一起。

小程序认证费用的问题也要提醒:个人主体的小程序很多权限没有,尤其是获取手机号这类敏感能力,必须用企业主体。毕设演示通常用测试号+开发者工具就够,真正发布上线才需要考虑认证和主体问题。

6. 后续扩展方向与毕设“不加分”陷阱

6.1 能快速增强的扩展点

如果你的毕设想要一些“亮点功能”,我实测这几个可以在短期内安全加进去且代码量不大:

  • 批量导入成员名单:EasyExcel 读 Excel 文件,前端上传后后端解析,把学生信息和学院信息写库。
  • 流程订阅消息:审核通过后给申报学生推送微信订阅消息,需要后端调用订阅消息接口,学生端先wx.requestSubscribeMessage。
  • 经费明细导流:结题时一键导出 Excel 汇总表,用 poi 模板生成。
  • 看板大屏:把统计图表全屏铺开,适合现场演示。

强烈不建议为了凑功能硬上人脸识别、实名认证或者支付模块。微信小程序的实名认证要额外应用权限,支付涉及商户资质,这类功能在毕设演示时空跑会露怯,而且没有实际业务场景支撑,反而让评委觉得“画蛇添足”。

6.2 别为答辩堆功能,逻辑闭环更重要

我见过最惨痛的教训是一个学弟的毕设系统列了一堆菜单:校园论坛、二手交易、课程表、心理测评……每个模块都只有列表页和静态弹窗。答辩老师随机点进“立项审核”模块问了一句:“这个项目从提交到结题,中间被老师驳回一次,数据和流程会怎样?”他答不上来。

管理系统做得好不好,从来不是看功能多不多,而是看一条业务流能不能走通。这个项目里,我把一条完整的数据流:学生提交 → 指导老师审核 → 学院审核 → 校级立项 → 中期汇报 → 结题验收,从数据库表设计到接口到小程序展示从头到尾站稳了。演示的时候你不用多讲清单,拿着小程序点一遍申报,后台立刻收到待审数据,老师给个驳回意见,小程序刷新看到状态和意见——这已经把管理系统的核心价值说完了。

最后分享一个我在实际部署时的小经验:开发环境的数据和正式环境一定分开,别拿测试数据给答辩看,一个叫“测试项目123”的申报记录会让整个系统显得很不严谨。初始化几条带真实感的样例数据,比如项目名称、学院、老师姓名、审核时间都填得像模像样,现场演示效果能提升一个档次。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 4:20:16

功放削顶失真与削底失真:成因诊断及电源余量优化实践

功放削顶失真这个词&#xff0c;玩音响的人多半都见过&#xff0c;但能把它彻底讲明白的人不多。前阵子帮朋友调试一台自己装的甲乙类推挽功放&#xff0c;大音量下声音发毛、高音刺耳&#xff0c;示波器一挂上去&#xff0c;正负半周都被整整齐齐地削平了&#xff0c;像是用刀…

作者头像 李华
网站建设 2026/10/7 4:17:47

agent-skills 实战:用技能链让 AI 编程助手遵循 TDD 工程纪律

1. 从“agent-skills”说起&#xff1a;为什么它值得你花时间研究第一次看到agent-skills这个标题&#xff0c;很多人会以为它只是某个仓库里堆了一堆提示词模板。但真正用过 AI coding agents 的人会明白&#xff0c;它解决的是一个非常具体、非常痛的问题&#xff1a;同一个模…

作者头像 李华
网站建设 2026/10/7 4:17:00

50个汽车性能MATLAB/Simulink仿真模型库深度评测与实战指南

1. 这套模型库到底值不值&#xff1a;从50个汽车性能模型说起前阵子把一套汽车性能MATLAB仿真模型库从头到尾过了一遍&#xff0c;一共50个Simulink模型&#xff0c;配套的源码以.m参数脚本和.slx/.mdl模型文件为主。说实话&#xff0c;刚拿到手的时候我是有点怀疑的&#xff1…

作者头像 李华
网站建设 2026/10/7 4:16:59

Agent Skills实战:让AI智能体按需调用技能包高效干活

最近我在折腾agent-skills这个开源项目&#xff0c;先说结论&#xff1a;它解决的不是"模型会不会回答问题"&#xff0c;而是"模型能不能动手把事做完"。第一次看到仓库时我以为它只是又一套工具调用框架的封装&#xff0c;但真正跑通一个技能包之后&#…

作者头像 李华
网站建设 2026/10/7 4:16:37

HP型磨煤机变加载液压系统设计:从原理到调试全解析

做磨煤机液压系统这些年&#xff0c;被问得最多的一个问题就是&#xff1a;HP型磨煤机到底要不要改成变加载&#xff1f;如果改&#xff0c;液压系统怎么设计才算真正靠谱&#xff1f;这个问题背后&#xff0c;其实是深度调峰常态化之后&#xff0c;传统定加载磨煤机“低负荷过…

作者头像 李华
网站建设 2026/10/7 4:16:33

电力通信站动力环境监控系统:从采集点到SCADA接入全解析

简介&#xff1a;这是一份电力自动化通信环境监控系统分析论文&#xff0c;面向电力系统运维、通信调度及变电站无人值守改造相关技术人员与电气专业学生。文档围绕通信站机房环境及动力设备监控、视频监控两条主线&#xff0c;详细梳理了温湿度、交直流配电、整流单元、蓄电池…

作者头像 李华