恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
SpringBoot+微信小程序作业布置与批改系统全栈开发实践
首页
资讯中心
/
SpringBoot+微信小程序作业布置与批改系统全栈开发实践
SpringBoot+微信小程序作业布置与批改系统全栈开发实践
发布时间:2026/10/13 9:41:17
SpringBoot 加微信小程序做作业布置和批改系统这题目在毕业设计里属于常客了。它不算复杂到让人劝退但也绝对没有简单到能三天糊弄完——微信登录、文件上传、权限控制这几个环节哪个没处理干净都会让人卡上好几天。这篇文章我打算按自己的真实开发路径来写从需求拆解、表结构设计到关键接口和小程序端实现再到部署和避坑完整过一遍给准备做类似项目的同学留一份能直接照着走的参考。先说下什么人适合看这篇计算机相关专业准备做毕设的应届生或者刚学完 SpringBoot 想找个完整全栈练手项目的人。如果你已经能独立写出简单的 CRUD 接口那这篇文章基本能带你把这个项目从头到尾串起来。如果你还停留在跟着教程敲代码的阶段也不怕我会把原理和步骤拆得比较碎你跟着思路走一样能摸清整个项目的骨架。1. 项目整体的需求拆解与方案选型1.1 核心角色与业务流程老师要能创建作业、关联班级、发布出去学生要能看到作业清单、在线提交作业老师要能查看提交列表、在线批改打分最后师生双方都要能看到成绩和反馈。这个流程看起来简单但落到功能上就会拆出一堆细节。角色分成三种管理员、教师、学生。我接触的大多数同类毕设里管理员往往只是用来维护账号和班级的基础数据真正核心的业务逻辑全部落在教师和学生两端。教师端的功能通常包括班级管理、作业管理、提交查看、批改评分、统计汇总学生端则围绕作业列表、详情查看、提交作业、成绩查询展开。这里有一个容易想歪的地方很多人一开始想把系统做成“在线答题”那种模式让作业变成一道道小题在页面上做。但实际上作业布置和批改系统最常见的真实使用场景是支持上传文档、图片这类附件形式的作业。比如英语老师布置一篇作文学生传个 PDF数学老师要求写解题过程学生拍几张照片传上来。所以在需求阶段就要把“附件提交”当成核心能力来设计而不是去做题库系统。1.2 技术选型为什么是这四件套后端用 SpringBoot、ORM 用 MyBatis Plus、数据库用 MySQL、前端用微信小程序原生这套组合我实际做下来觉得比较稳妥。SpringBoot 的理由不用多说自动配置、内嵌 Tomcat、生态成熟一个 jar 包就能跑起来对毕设演示非常友好。MyBatis Plus 能省掉大量单表 CRUD 的 XML 编写代码生成器还能根据表结构把实体和 mapper 直接生成出来这对工期紧张的学生来说是实实在在的助力。MySQL 存作业和成绩这类结构化数据没有任何压力毕设场景基本不需要上更重的数据库。微信小程序选原生框架主要是为了降低复杂度。如果你对 Vue 比较熟可能会想用 uni-app 来做但对于这个题目来说原生暂时足够。而且原生小程序的文档和踩坑资料最全你在网上搜到的问题解决方案大概率就是围绕原生写的。后面如果想让老师用手机拍照批改也不需要额外的 App小程序天然满足了这个使用场景。1.3 功能模块划分与页面流转我习惯把整个系统分割成四个大模块账号与权限、班级作业管理、提交批改链路、统计与通知。账号与权限解决的是“谁是谁”的问题通过微信登录拿到 openid 后和用户表关联再用 token 做会话保持。班级作业管理面向教师端核心是维护班级和学生归属关系、创建作业并发布到指定班级。提交批改链路是真正体现系统价值的模块学生提交附件教师在线查看下载并打分写入分数和评语。统计通知模块属于加分项可以让教师按班级看整体提交率和平均分也可以在作业截止前提醒未提交的学生。页面流转方面学生端从首页进入班级列表再进入某班级的作业列表点进某次作业后看到详情和已提交状态最后进入提交页面。教师端则是在作业详情页能看到全班提交名单逐个进入批改页。这条路径一定要在动手写代码之前想明白否则很容易写着写着发现页面跳转不对。2. 表结构设计与业务状态设计2.1 库表拆分与字段落定我最终设计出来的核心表有六张用户表、班级表、班级学生关联表、作业表、提交表、通知表。下面把每张表的重点字段列一下。用户表id、openid、unionid可选、真实姓名、角色1 管理员/2 教师/3 学生、学号工号、创建时间。openid 是微信生态下的用户唯一标识一定要设置为唯一索引后续登录逻辑全靠它。班级表id、班级名称、年级、班主任 id关联用户表教师、创建时间、状态。这里有个细节班级和教师的关系我直接设计成班主任字段简单直接避免引入额外的关联表。班级学生关联表id、班级 id、学生 id、加入时间。为什么需要这张表而不是在用户表里放一个班级字段因为同一个学生可能同时属于多个班级比如补课场景或者跨班选修用关联表才能正确表达这种多对多关系。而且在毕设答辩时老师看到这张关联表会觉得你懂关系型数据库的基本建模。作业表id、标题、内容描述、附件地址、布置教师 id、发布班级范围这里可以用一对多关联表也可以用逗号分隔的班级 id 字符串、截止时间、创建时间、发布状态。截止时间这个字段很关键提交逻辑要判断当前时间和截止时间的关系。提交表id、作业 id、学生 id、提交内容文本、附件地址、批改状态0 未提交/1 已提交待批改/2 已批改、得分、教师评语、提交时间、批改时间。这张表是系统里数据量最大也是最核心的表。如果功能里还要做成绩统计可以在提交表上直接做聚合查询按作业 id 分组算出平均分和提交率不需要额外建统计表。2.2 作业与提交的状态机设计状态不要乱用布尔值一个字段要能表达出清晰的状态流。作业表我用了一个发布状态字段草稿、已发布、已截止。这个状态在创建时是草稿确认无误后点发布变为已发布过了截止时间则自动标记为已截止。需要注意的是“已截止”并不是由定时任务来实时改的我建议在查询的时候根据当前时间和截止时间动态计算出来或者在查询接口里做一次批量更新避免引入一套定时调度逻辑增加复杂度。提交表的批改状态则设计成四个未提交、已提交待批改、已批改。这里有个经验之谈学生“未提交”的状态不要真的在提交表里存一条记录而是在查询时通过 left join 作业表来推导也就是“作业表有这条作业但提交表里没找到该学生的记录那他就是未提交”。这样能少维护大量无意义的空记录。2.3 权限模型与前端可见性权限这块用最简单的前后端双层控制后端用一个拦截器校验 token再根据角色编码拦截接口前端根据角色不同展示不同入口。比如教师角色能看到“批改”按钮学生角色看到的是“提交”按钮。具体到接口权限我会在控制器方法上做三层约束第一层是是否登录第二层是角色匹配第三层是数据归属校验比如学生只能查看自己在班级里的作业教师只能批改自己布置的作业。第三层很多初学者会漏掉但这是答辩时老师喜欢追问的地方也是真实系统不能忽略的安全底线。3. 后端从零搭建与关键接口实现3.1 项目初始化的几个关键步骤创建 SpringBoot 项目时依赖选这几个就够Spring Web、MyBatis Plus、MySQL Driver、Lombok再加一个 validation 用于参数校验。如果你用的是 Maven记得确认 MyBatis Plus 的版本和 SpringBoot 版本兼容我用的是 SpringBoot 2.7.x 搭配 mybatis-plus-boot-starter 3.5.x实测没有问题。配置文件里有两个地方容易踩坑。第一是 MySQL 的连接串要带上时区参数我建议写 serverTimezoneAsia/Shanghai否则数据库时间会比正常时间少 8 小时甚至直接报错。第二是文件上传的大小限制SpringBoot 默认允许上传 1MB 左右而作业里面经常要传照片所以必须在配置里把上限调大spring: servlet: multipart: max-file-size: 20MB max-request-size: 50MB这两个坑都是那种“不知道的时候查半天知道之后十秒钟解决”的问题。3.2 微信登录的完整链路小程序端用户点击授权登录后前端通过 wx.login() 拿到的临时 code 传给后端后端拿 code 调用微信官方接口换取 openid 和 session_key。换到 openid 后去用户表查一下有没有记录如果没有就自动注册新用户有就直接登录成功。登录成功后后端生成一个自定义 token 返回给前端后续所有请求都带着这个 token。这里有两个重要的安全建议。第一code2session 的调用必须放在后端不能放在小程序端因为接口需要用到 AppSecret这个一旦暴露在小程序包里任何人都能拿到。第二token 不建议直接用 openid 传到前端而是后端生成一段随机字符串存到 Redis 或内存里前端请求时后端反向解析出用户身份。如果毕设没引入 Redis也可以像我用一个哈希表维护有效 token把 token 作为 key、用户信息作为 value逻辑简单但完全够用。GetMapping(/login) public Result login(RequestParam String code) { String url https://api.weixin.qq.com/sns/jscode2session; // 拼接 appid、secret、code、grant_type // 发起 GET 请求解析返回值中的 openid // 根据 openid 查表或注册新用户 // 生成 token放入会话容器 return Result.ok(token); }要注意小程序端的 wx.login 只是获取 code 的入口完整的登录流程还需要用户主动点击授权按钮触发不能从 App 启动时静默完成这是微信小程序的规则限制。3.3 作业布置接口的表单设计教师在发布作业时实际上是同时提交了作业的标题、描述、截止时间和面向班级列表。这里我设计接口参数时用了一个 DTO把基础信息和班级 id 数组放在同一个请求体里。保存时先插入作业主记录拿到作业 id 后再遍历班级列表调用 insert 写入作业班级关联表。这里要特别注意事务的问题。如果先插主记录再插关联记录中间任何一步抛出异常数据库里就会残留半截数据。所以要在 Service 层的这个方法上加 Transactional 注解保证要么全部成功要么全部回滚。另外就是作业附件如果作业本身带一个示例文件那附件就对多份作业共用不需要为每个班级复制一份存储存一份附件地址引用即可。发布状态的改动也藏着一个逻辑已经发布的作业如果学生已经有人提交那作业内容是不允许再修改的否则学生对同样的题目标题提交了不同要求的作业成绩公平性就破坏了。我在编辑接口里加了一个判断作业已有任何一条提交记录时直接拒绝修改请求并返回提示消息。3.4 学生提交与教师批改的并发思考学生提交作业是典型的写操作提交前需要判断三件事情这条作业是否存在、当前时间是否在截止时间之前、该学生是否属于这条作业的可见班级范围。三个条件都满足才允许落库。第一次写提交接口的时候可能不会想太多但实际使用中可能出现同一个学生手滑点了两次提交按钮的情况。如果没有防重措施提交表里就会插入两条记录。解决办法是在提交表上建一个联合唯一索引字段组合为作业 id 加学生 id。这样即使前端请求重复了数据库这一层也能兜住。教师批改的流程相对简单就是把提交表里对应记录的状态改为已批改、写入分数和评语。批改时推荐顺手记录一个批改时间方便后续做统计。有一个产品上的细节值得做进去批改时除了给分还要允许老师输入文本评语甚至可以给学生的附件打标记。评语字段不要设计得太短我用的是 512 长度实际测试中文内容是完全够用的。4. 微信小程序端从零实现4.1 登录态保持与请求封装小程序端我会在 App 启动时检查本地存储里有没有 token如果有直接进入首页如果没有就跳转到登录页。登录页里放一个按钮用户点击后调用 wx.login 拿 code再请求后端接口。后端返回的 token 用微信的同步存储能力 wx.setStorageSync 存起来。所有请求都需要带着 token所以我在项目里封装了一个全局的 request 函数。这个函数基于 wx.request 封装每次调用时自动从本地缓存读取 token加到 header 里。一旦遇到后端返回的 401 状态码说明 token 失效此时前端要清掉本地缓存并引导用户重新登录。这里特别提醒一下wx.request 的 header 里自定义字段名不要用系统关键字我用的是 Authorization 字段属于业界标准做法后端在拦截器里从这个字段取值校验。const request (url, method, data) { return new Promise((resolve, reject) { const token wx.getStorageSync(token); wx.request({ url: BASE_URL url, method: method, data: data, header: { Content-Type: application/json, Authorization: token }, success: (res) { if (res.data.code 401) { wx.removeStorageSync(token); wx.redirectTo({ url: /pages/login/login }); } resolve(res.data); }, fail: reject }); }); };4.2 页面结构与下拉刷新交互学生首页我设计成两段式上半部分是班级列表点击班级后进入班级作业列表作业列表里每一条显示标题、截止时间、提交状态图标。教师首页则直接展示自己发布过的作业卡片点击进入详情。列表页一定要做下拉刷新和触底加载。学生每次进入作业列表时后端返回的提交状态可能已经变了所以不能依赖 switchTab 跳转后的缓存页面必须在 onShow 生命周期里主动刷新。触底加载用 onReachBottom 实现分页拉取这个在小程序端属于标配能力但很多人会忘记在 onReachBottom 里处理页码参数导致翻页后数据重复。4.3 附件上传与预览的实现细节学生提交作业时最核心的交互是选择图片或文件并上传。小程序里选择图片用 wx.chooseMedia选择文件用 wx.chooseMessageFile。选好之后调用 wx.uploadFile 上传到后端上传完成后拿到附件地址再把它和作业 id 一起作为表单数据提交。这里一个非常常见的坑是 wx.uploadFile 的 name 字段必须和后端 RequestParam(file) 的参数名完全一致否则后端接收不到文件。除此之外上传接口的返回格式也要注意wx.uploadFile 的 success 回调里返回的数据是字符串不是 JSON 对象需要手动 JSON.parse 一下。教师批改页面需要预览学生传上来的附件。图片类型的附件直接用 image 组件的 src 指向云存储地址或后端静态资源地址就行。如果是 PDF 或 Word 这类文档小程序原生不提供在线预览能力我的建议是使用官方提供的 openDocument 接口让用户点击后调用微信自带文档打开工具。整体体验虽然不花哨但功能上是完整的。5. 项目踩坑实录与常见问题排查5.1 微信接口返回的 code 失效问题微信登录的 code 是一次性的有效期五分钟而且只能使用一次。很多同学在调试时用同一个 code 反复请求后端发现第一次成功第二次失败这不是后端逻辑出错而是 code 已经被消费掉了。正确的排查方式是每次前端点击登录按钮都重新调用 wx.login 获取新 code不能把 code 写死在测试参数里。还有种情况更容易让人懵后端请求微信接口时返回了 40029 错误码表示 code 无效。这种情况大概率是 appid 和 secret 配置错误或者请求时拼错参数了。建议先在微信群工具里直接测试一遍确认能够拿到 openid再去排查后端代码问题。5.2 文件上传之后访问不到文件上传后前端如果出现 404十有八九是文件保存到了服务器本地某个目录但没有配置静态资源映射。比如我保存文件的路径是 /data/upload配置文件里就必须声明这个目录是静态资源路径否则访问时根本无法命中。如果文件最终要部署到云服务器我更建议用对象存储服务来存放附件。把本地上传逻辑换成上传到对象存储很简单只需要改保存方式数据库里存下对象存储返回的 URL 即可。云存储的好处是文件不会因为服务器重置而丢失而且小程序端加载图片速度更快毕业设计中这样一个细节也很有加分效果。5.3 时区时间比实际慢 8 小时这是几乎每个做 Web 项目的人都会踩的时区坑。MySQL 连接串如果不带 serverTimezone 参数可能默认按系统时区处理也可能按 UTC 处理导致拿到的时间比北京时间慢 8 小时。在连接串里明确写明 serverTimezoneAsia/Shanghai 能解决大部分问题。另外提交表里的截止时间判断我建议在后端统一判断不要依赖前端传入的时间这样即使不同用户手机时间设置不同系统判断也不会被带偏。5.4 分页查询时提交状态显示错误作业列表页显示“已提交/未提交”状态时如果直接用两条 SQL 分别查作业和提交记录很容易因为数据不同步导致状态错乱。我的方案是一条 SQL 完成查询作业列表时把当前学生的提交记录通过 left join 带出来根据提交记录是否为 null 得出状态字段。这样避免了循环查询导致的 N1 问题也不会出现状态不一致的情况。这类查询场景在 MyBatis Plus 里可以直接用自定义 SQL 实现其实并不复杂但对于刚接触的人确实需要花点时间理解 join 的含义。耐心多查几次数据你就知道为了这个正确性所付出的时间完全值得。6. 项目部署与演示阶段的准备工作6.1 后端打包部署的注意事项后端项目完成后用 Maven 的 package 命令打成 jar 包上传到服务器后执行 java -jar 启动即可。部署前记得三点第一数据库连接地址改成服务器上的地址第二微信小程序 AppSecret 在正式发布时不要写在配置里提交到代码仓库可以在服务器环境变量里读取第三如果要让小程序在手机上访问后端地址必须是 HTTPS 且完成备案否则微信会拦截请求。如果暂时没有服务器用本地跑后端加开发者工具调试也能完成毕设答辩。只要把小程序开发者工具里的“不校验合法域名”选项勾上本机的 localhost 接口是可以直接访问的。不过这也只是开发阶段的做法正式上线千万不能依赖这个选项。6.2 演示数据准备与答辩路线答辩演示最怕冷场所以演示数据一定要提前准备好。比如三个班级各十个学生每个班至少有两到三次作业记录其中包含尚未发布的草稿、已截止未提交的、已提交批改的和打过分数的这样评审老师看到的是一个真实有内容的状态。演示路线我建议按“教师创建作业、发布、学生查看提交、教师批改、查看统计”这个顺序走完整闭环。讲到登录时要能解释清楚微信登录的完整流程讲到文件上传时要能说清附件存储方案讲到批改时要能说出状态转换的逻辑。这些点都能体现你是在真正地理解项目而不是只会跟着教程搬代码。6.3 关于扩展功能的建议如果时间充足还可以在原有基础上加两个亮点功能。第一个是“小组协作提交”允许同一个小组的多名学生共同提交一份作业这需要额外设计一个小组表并参加提交表的关联关系。第二个是“作业完成度分析”用图表在小程序里显示学生在某次作业上的得分分布可以用 echarts 小程序版实现。增加一个这类数据分析功能会在答辩时显著提升项目的完整程度与技术含量。我在最初实现这个项目时也觉得一个学生提交、老师打分的小功能有什么好设计的但真的在脑子里把所有逻辑推演一遍后才发现即便是一个“简单”的作业系统仍然有大量值得用心打磨的细节从微信登录的身份映射到提交状态的并发控制再到前端分页加载的一致性处理每一处都在考验你是否有系统化思考的能力。这种能力远比“会写代码”四个字更有价值。如果在开发过程中你也被某个问题卡住了不用急着怀疑是自己能力不够大概率你只是遇到了一个前人也踩过的坑。静下心来看主流程、看核心判断、看数据在每一步是如何流转的问题通常都会迎刃而解。用这份耐心去做完一个项目之后你会发现做毕业设计这件事情确实能让你获得实实在在的成长。