ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于SSM+Uniapp的移动课程教学辅助平台开发实战

基于SSM+Uniapp的移动课程教学辅助平台开发实战 做移动课程教学辅助平台这个项目前后折腾了大概两个来月从后端选型到小程序端落地整体走了一遍完整流程。技术栈就是标题里写的这套后端 SSMSpring SpringMVC MyBatis前端管理端用 Vue移动端用 Uniapp 开发微信小程序。这类项目在高校作业、毕设、课程设计里非常常见但绝大多数文章只贴个架构图加一段“系统分为管理员、教师、学生三个角色”的废话真正能指导你把项目跑起来的内容少得可怜。这篇文章我会把整个项目从设计思路到前后端联调再到小程序打包上架的完整链路全部拆开讲。包括为什么选这套技术栈而不是别的、SSM 后端接口怎么设计才方便小程序调用、Uniapp 端有哪些坑是文档里不会写的、以及支付、分享、视频播放这些高频功能怎么做。内容偏实战适合正在做类似课程平台、在线教学类小程序或者拿这个题目做毕业设计想少走弯路的人。1. 项目整体设计与技术选型思路1.1 为什么是 SSM Vue/Uniapp 这套组合先聊选型。很多人看到 SSM 会觉得很老现在都在用 Spring Boot Spring Cloud但在课程教学辅助这类中轻量级场景里SSM 反而是个稳妥的选择。第一Spring Boot 虽然把配置简化到了极致但 SSM 的显式配置能让你更清楚地看到 Spring 容器、SpringMVC 请求链路、MyBatis 持久层各自干了什么。像我们这次用的 XML 配置加注解混搭的方式遇到问题排查时链路非常清晰对刚接触 Java 后端的人来说友好得多。第二SSM 部署要求低。Tomcat 8 加 JDK 8 就能跑一台 2G 内存的小服务器就能撑起一个小型教学平台的日常访问量。如果用 Spring Boot 那一套光组件库和自动配置的开销就会大不少部署环境的灵活性也差一些。前端选 Vue 是因为它的学习曲线平缓而且和小程序端使用 Uniapp 可以保持语法习惯一致——二者都是基于 Vue 生态。管理后台的课程管理、用户管理、数据统计页面直接用 Vue 写不引入太重的前端工程化框架开发效率很高。移动端用 Uniapp 而不用原生小程序看重的是它的一套代码多端编译能力。同样的代码不仅能跑微信小程序之后有需要还能编译成 H5 和 App后续扩展成本很低。而且 Uniapp 对 Vue 开发者几乎没有额外学习成本API 风格也大量保留了 uni.xxx 的语义化写法配合 HBuilderX 开发调试都很顺手。1.2 系统功能模块拆分课程教学辅助平台的核心不是“课程列表 播放视频”这么简单它要服务的角色有三类每类角色的核心诉求不一样。学生端要的功能浏览和选课、在线看课程视频和课件、接收作业并提交、参与签到、在讨论区提问。教师端要的功能创建和维护课程、上传课件与视频、布置和批改作业、发起签到、发布课程公告。管理员端的功能则是基础数据维护包括用户管理、课程审核、数据统计。这三大块的业务逻辑叠在一起就决定了后端需要提供哪些接口、前端需要开发哪些页面。我在设计时画过一张功能脑图大致是这样的维度用户体系注册登录、角色区分、个人信息维护、密码修改课程体系课程创建、分类管理、课件/视频资源上传、课程上下架教学环节作业布置、作业提交、作业批改、成绩记录课堂互动签到打卡、讨论区留言、公告通知管理后台用户管理、课程审核、数据看板每个模块的职责划分清楚之后前后端的接口边界也就自然出来了。不会出现“前端不知道该调哪个接口”“后端不知道该返回什么数据”这种混乱状态。1.3 前后端交互架构设计前后端分离是这套架构的核心思想。微信小程序端和后端之间通过 HTTP 接口通信后端只负责提供 JSON 数据不关心前端是跑在小程序里还是浏览器里。接口设计上我整体采用的是 RESTful 风格资源用名词复数表示动作通过 HTTP 方法区分。比如GET /api/courses 获取课程列表POST /api/courses 创建课程GET /api/courses/{id} 获取课程详情PUT /api/homework/{id}/grade 批改作业这套规范的好处是接口语义清晰前端对接时基本不用看文档猜接口用途看 URL 就能知道是做什么的。数据返回格式我也统一封装了一层使用自定义的 Result 对象{ code: 200, message: 操作成功, data: {} }所有接口都套这个结构前端封装好统一的请求后只需要关注 data 字段。这个看起来很简单但实际开发里能省掉大量在 “判断返回状态” 上重复写的代码。2. 后端 SSM 核心设计与关键实现2.1 SSM 框架整合的配置要点SSM 三方框架的整合是第一步也是最容易出问题的一步。网上很多教程用的配置版本很老照着抄经常会遇到依赖冲突或者配置失效。我这里给出我验证过的一套可行组合JDK 8 Maven 3.6 Spring 5.1.8 MyBatis 3.5.4 MyBatis-Spring 2.0.4。Maven 依赖里需要注意版本之间的兼容性。特别要提醒的是Spring 5 开始使用 jdbc 包而不是传统的 spring-orm 来支持事务所以需要额外引入 spring-jdbc。pom 里还要配置阿里云镜像不然依赖下载能卡到怀疑人生。SSM 整合主要有三个配置文件spring-mvc.xml、spring-mybatis.xml、web.xml。web.xml 里需要配置两件核心事情一个是 ContextLoaderListener 加载 Spring 根容器另一个是 DispatcherServlet 拦截所有请求并加载 SpringMVC 容器。要注意的是SpringMVC 容器只扫描 Controller 包其余 Service、Mapper 一律留给根容器避免重复扫描导致事务失效。spring-mvc.xml 重点配置注解驱动、静态资源映射和视图解析器。如果是前后端分离的模式接口直接返回 JSON不经过视图层。我会在里面放开对静态资源的访问并把 JSON 转换交给 Jackson 处理。spring-mybatis.xml 里要配置数据源、SqlSessionFactory 和 Mapper 扫描。数据源我用的是阿里 Druid配好连接池参数后还需要一并配置事务管理器并把 Service 层的扫描交给 Spring 管理。MyBatis 的 Mapper 接口通过 MapperScannerConfigurer 自动扫描Mapper XML 文件则通过 SqlSessionFactory 的 mapperLocations 属性指定位置。http://druid.apache.org/ 是 Druid 的官方文档建议花十分钟看下连接池各项参数的含义线上环境里这些参数直接影响数据库连接消耗。2.2 身份认证与拦截器设计课程教学平台涉及学生和教师两个主要角色接口不能裸奔必须做登录鉴权。小程序端的登录方案和传统 Web 端不太一样小程序的登录态是依赖微信的 code 换 openid 来建立的。具体流程是小程序端调用 uni.login 获取临时 code把这个 code 传给后端后端再用 code 调用微信的 jscode2session 接口换取 openid根据 openid 去查用户表如果查到就生成一个自定义的 token 返回给前端查不到就自动注册一个新账号再返回 token。token 我选用的是 UUID 随机字符串存到 Redis 里设置过期时间。设计上没直接使用 JWT 的原因是这个项目涉及账号禁用、强制下线、退出登录后 token 立即失效等需求JWT 的无状态特性反而不好处理这种“主动作废”的场景。Redis 方案在课程辅助平台这种量级下完全够用实现也简单很多。后端拦截器负责统一校验 token。我写了一个 TokenInterceptor在 preHandle 方法中从请求头或参数里取出 token去 Redis 中校验存在性和有效性。校验不通过时直接返回 401 状态码和统一错误 JSON前端拿到 401 后自动跳转登录页。拦截器在 SpringMVC 里只需要在配置类里声明即可需要注意放行登录接口、课程列表等不需要鉴权的接口其余接口一律拦截校验。2.3 核心数据库表设计数据库表设计是整个系统的地基表设计得好不好直接决定后面写 SQL 的复杂度和接口的响应速度。我整理出了下面这几张核心表表名核心字段说明sys_userid, username, password, role, avatar用户表角色区分 student/teacher/admincourseid, name, cover, teacher_id, category_id, status课程表status 控制上下架course_resourceid, course_id, title, type, url, duration课程资源表type 区分 video/ppt/dochomeworkid, course_id, title, content, deadline作业表deadline 控制提交截止时间homework_submitid, homework_id, student_id, content, file_url, score作业提交表覆盖多次提交sign_inid, course_id, teacher_id, start_time, end_time签到活动表sign_in_recordid, sign_in_id, student_id, sign_time签到记录表course_commentid, course_id, user_id, content, create_time讨论区留言表用户信息使用了角色字段区分没有把学生和教师拆成两张表。因为绝大多数权限控制逻辑只要拿到 role 字段就能通过前端路由和后端拦截器分别控制拆表反而会让通用的用户信息管理变得复杂。作业表里 dead_line 这个字段设计了截止时间所在的小时级别因为教师布置作业时必须设置截止日期而这些截止时间点可能分布在不同日期甚至不同学期。如果只存一个日期作业查询和筛选会有很多边界问题。签名表都设计了单独的记录表因为一次签到活动需要记录所有签到学生如果放在同一张表里字段冗余会很严重数据量大了以后查询效率也差。3. Uniapp 小程序端开发实战3.1 项目创建与基础配置Uniapp 项目我使用的是 HBuilderX 直接创建选 uni-app 模板。创建完成后第一件事就是配置 manifest.json 里的微信小程序 AppID。这里要用真实的小程序 AppID测试号能跑但部分功能受限支付和登录接口都要求有真实 AppID 才行。pages.json 是页面路由和底部导航的配置核心在 Uniapp 里相当于小程序的 app.json。tabBar 我配了首页、课程、消息、我的四个入口。需要注意 tabBar 页面必须在 pages 数组的第一级列表中声明且页面间跳转要遵循 Uni 的路由规范用 uni.navigateTo 和 uni.switchTab 区分 tab 页面和普通页面的跳转方式。还有一个很容易踩的坑是 pages.json 里每个页面都能配置 navigationBarTitleText如果某几个页面忘记配小程序顶部导航栏的标题就会显示默认的应用名影响整体体验。3.2 请求封装与登录态管理Uniapp 官方提供的 uni.request 是基础 API但实际开发不能直接调用必须在项目里封装一层统一的请求模块。我通常的做法是建立一个 utils/request.js 文件导出封装后的请求函数。// utils/request.js const BASE_URL http://localhost:8080/api function request({ url, method GET, data {} }) { return new Promise((resolve, reject) { uni.request({ url: BASE_URL url, method, data, header: { Content-Type: application/json, Authorization: uni.getStorageSync(token) || }, success: (res) { if (res.data.code 200) { resolve(res.data.data) } else if (res.data.code 401) { uni.navigateTo({ url: /pages/login/login }) } else { uni.showToast({ title: res.data.message, icon: none }) reject(res.data) } }, fail: (err) { uni.showToast({ title: 网络请求失败, icon: none }) reject(err) } }) }) }BASE_URL 的配置在联调阶段要格外注意。在微信开发者工具里真机预览时 localhost 是手机自身连不上开发电脑必须改成开发电脑在局域网里的 IP 地址且要保持手机和电脑在同一网络环境下。微信开发者工具里可以勾选“不校验合法域名”开发阶段很方便但正式发布前必须在微信公众平台配置 request 合法域名。登录流程里Uniapp 获取微信登录 code 用的是 uni.login拿到 code 后调用后端接口换取自定义 token存在 uni.setStorageSync 里。之后所有请求通过请求拦截器自动带上 token退出登录时清除本地存储并跳转登录页。3.3 课程视频播放与 m3u8 处理在线课程的一大核心功能是视频播放。很多课程的视频源是 m3u8 格式的分片流这在浏览器和 App 里处理方式不一样小程序里也有自己的特殊性。微信小程序的基础库对 HLS 的支持是比较完整的video 组件直接设置 src 为 m3u8 地址就能播放不需要额外引入第三方播放器。video :srccurrentVideoUrl controls errorhandleVideoError /video但实际开发中要注意两个问题。第一个是 m3u8 地址如果是 HTTP 协议在微信小程序正式环境会被拦截因为小程序要求所有请求必须走 HTTPS。开发阶段可以在开发者工具里关闭域名校验但上线前必须由后端或运维把视频地址换成 HTTPS 的或者走 CDN 加速。我在这里就吃过亏测试时好好的一上真机就黑屏排查了半天发现是协议问题。第二个问题是视频要支持从上次播放位置续播。我选择了在 video 组件的 timeupdate 事件里定时把当前播放进度保存到后端或者本地缓存用户再次进入课程页时读取进度值通过 video 组件 initial-time 属性实现续播。这个功能虽然小却是课程平台很能提升使用体验的细节。3.4 路由参数获取与页面间传参小程序页面间跳转传参是很基础的场景Uniapp 和原生小程序有一点差别。原生小程序是在 onLoad 的 options 参数里直接拿Uniapp 基于 Vue 语法也需要通过 onLoad 接收但 Vue2 和 Vue3 的组合式 API 写法略有不同。// Vue2 写法 export default { onLoad(options) { console.log(课程ID:, options.id) } } // Vue3 组合式 API 写法 import { onLoad } from dcloudio/uni-app onLoad((options) { console.log(课程ID:, options.id) })这里容易踩的坑是参数长度限制。如果通过 URL 传递超长字符串比如一长串 JSON小程序会直接截断导致解析失败。我处理复杂参数时一般先把对象存到全局变量或者 storage 里跳转时只传一个 id。如果是简单场景要传对象也可以先用 encodeURIComponent 编码后再传接收页再做 decodeURIComponent 解码。另外Uniapp 提供了 getCurrentPages() 方法可以拿到当前页面栈往上一级页面传值也可以借助页面栈实例但一般在接受方行为中管理数据状态更符合 Vue 的数据流习惯不太推荐频繁操作页面栈。3.5 签到功能实现要点签到是课堂互动的常用功能我有两种实现方案。第一种是二维码签到教师端生成二维码学生端扫描后提交签到请求后端记录学生信息和签到时间。二维码内容我设计为携带签到活动 ID 的字符串。学生用 uni.scanCode 扫码后会用正则从内容里提取 ID再请求后端接口完成签到。第二种是打卡签到教师发布签到后学生进入签到页面点击“立即签到”后端记录当前时间和位置信息。位置校验可以用 uni.getLocation 获取经纬度上传后和后端预期的签到地址做距离比对超过设定阈值就提示签到失败。需要注意小程序使用 getLocation 接口必须在 manifest.json 里声明位置权限且在微信后台申请相关权限否则用户在手机上使用时地图和定位将完全不可用。3.6 顶部导航栏与软键盘遮挡问题处理这两个问题属于小程序开发的“高频边角”网上问的人特别多。顶部导航栏高度涉及的坑主要是自定义导航栏场景。如果页面使用自定义导航栏在 pages.json 中设置 navigationStyle: custom那么页面内容会从屏幕顶部开始渲染而状态栏高度和胶囊按钮的位置在不同机型上不一样。我封装了一个获取导航栏高度的工具函数export function getNavBarHeight() { const systemInfo uni.getSystemInfoSync() const menuButton uni.getMenuButtonBoundingClientRect() const statusBarHeight systemInfo.statusBarHeight || 44 const navBarHeight (menuButton.top - statusBarHeight) * 2 menuButton.height return statusBarHeight navBarHeight }这样就能算出“状态栏高度 导航栏高度”的总值页面里通过 padding-top 把内容顶下来。这个方法是兼容性最稳的因为胶囊按钮的位置是微信官方给定的不同机型适配都不会出大问题。软键盘遮挡输入框的问题常见于评论、搜索表单这类页面。Uniapp 的 input 组件有个 adjust-position 属性默认是 true也就是键盘弹出时页面会自动上推。但这个自动上推经常推得不准尤其页面结构比较复杂时容易出现键盘把输入框完全挡住的情况。我的处理方案是把 adjust-position 设置为 false然后监听页面高度变化手动把输入框滚动到可视区域。具体做法input v-modelcomment classcomment-input :adjust-positionfalse focushandleInputFocus blurhandleInputBlur / handleInputFocus() { setTimeout(() { uni.pageScrollTo({ scrollTop: 999999, // 滚动到底部 duration: 100 }) }, 100) }这个方案的原理是键盘弹出后页面可视区高度变小手动滚动到底部把固定在页面底部的输入框顶到键盘上方。实测下来比默认 behavior 稳定很多。4. 前后端联调与常见问题排查4.1 联调环境配置与请求安全前后端联调是整个项目阶段最容易出状况的一环但很多问题根源不在代码而在环境。后端启动后默认监听 8080 端口前端小程序端通过 HTTP 访问。微信开发者工具默认可以访问 localhost但在真机预览时必须改用局域网 IP。我建议项目一开始就在 request.js 里把 BASE_URL 做成可配置的根据环境变量或编译模式切换测试地址和生产地址。HBuilderX 支持自定义环境变量在 manifest.json 的 h5 配置和小程序配置里分别设置不同的 baseUrl 即可。还有一点就是后端接口的跨域问题。小程序端不是浏览器环境理论上不受跨域限制但如果你在开发时用 H5 模式调试就要在 spring-mvc.xml 里配置 CorsFilter 或在 Controller 上加 CrossOrigin 注解。很多人在浏览器里调通了接口一到小程序里就发现请求全部失败卡了半天才意识到是后端跨域配置没做。另一个安全细节是接口的请求体大小限制。小程序端上传作业文件和课程图片默认的 POST 请求体大小可能不够需要在前端封装请求时设置 socket 超时和上传超时参数。如果后端对请求体大小也做了限制还要在 SpringMVC 的 multipart 配置里把 maxFileSize 调大不然大文件上传会直接报错。4.2 微信支付接入的实际过程课程平台如果需要付费课程或者会员功能就绕不开微信支付。微信支付 V3 接口是现在的标准我那年做项目时 V3 协议已经比较成熟了对接流程也相对顺畅但中间依然踩了一个大坑——支付功能被微信限制弹窗提示“由于小程序违规支付功能暂时无法使用”。这个提示基本能说明问题不是代码问题是小程序账号被微信限制了支付能力。常见原因有类目选择不对、涉及虚拟支付但缺少资质或者主体信息审核没通过。这个问题的排查路径不在代码层面而是去微信公众平台查看站内信和违规记录按平台要求整改后提交申诉。所以在项目开始前各功能所涉及的服务类目一定要在微信后台提前配置好同步确定好退款、订单等运营规则否则代码写得再好也白搭。实现上小程序端支付流程是后端调用微信支付的 JSAPI 下单接口拿到支付参数返回给前端前端再调 uni.requestPayment 拉起微信支付。const res await request({ url: /api/pay/order, method: POST, data: { courseId: this.courseId } }) uni.requestPayment({ provider: wxpay, timeStamp: res.timeStamp, nonceStr: res.nonceStr, package: res.package, signType: RSA, // 微信支付 V3 使用 RSA 签名 paySign: res.paySign, success: () { uni.showToast({ title: 支付成功 }) }, fail: (err) { uni.showToast({ title: 支付取消或失败, icon: none }) } })微信支付 V3 和 V2 的区别主要在签名算法。V3 使用的是 RSA-SHA256 签名而且私钥分成了 API 密钥和商户私钥两张开发时要把这两类密钥保存好你部署到正式环境前要重新生成并配置。还有回调地址必须是 HTTPS否则支付成功后后台收不到通知。4.3 Uniapp 打包上架与安卓市场发布Uniapp 项目开发完成后打包发布也是一个独立的流程。小程序端的打包最简单在 HBuilderX 里点“发行 小程序-微信”就会生成一个微信开发者工具能直接导入的项目目录。这个目录就是完整的小程序源码在微信开发者工具里上传版本、提交审核即可。如果你的项目还要上架安卓应用市场就需要做 App 打包。Uniapp 提供了云打包和本地打包两种方式。云打包直接在 HBuilderX 里点击发行云打包填好包名、证书信息大概十分钟就能出安装包。本地打包则需要配置 Android Studio 环境相对麻烦但可控性更好。打包有几个容易踩的坑分享给大家打包前一定要检查 manifest.json 里的 App 模块权限配置比如需要使用地图就得勾选对应模块否则云打包后的 App 里调用地图接口会直接报错应用市场的包名必须是你在开发者后台申请的应用签名信息一致的包名且正式包必须使用正式证书而非测试证书如果小程序在某个安卓市场上架被驳回常见原因是隐私政策不完善或者权限声明不规范我之前就遇到过必须补充“用户隐私保护提示并设置同意/拒绝按钮”的要求。官方推荐的做法是应用启动时弹窗提示个人信息保护指引用户默认是选拒绝的在 HBuilderX 的 manifest.json 里也支持配置强制同意逻辑。代码层面还需要处理用户拒绝隐私协议的场景不能强制要求用户同意只能退出 App这块 Uniapp 社区里也有很成熟的做法建议去查一下再写4.4 常见问题排查实录做联调和测试的时候我把遇到频率最高的几个问题整理成了一张速查表几乎每一个都是真实踩过坑之后的结论。现象可能原因排查方法运行到微信开发者工具没反应HBuilderX 和微信开发者工具的服务端口未开放微信开发者工具设置里开启服务端口关闭代理真机预览请求失败BASE_URL 还是 localhost改为局域网 IP检查手机和电脑是否同一网络上传图片提示网络错误上传域名未配置到合法域名在小程序后台配置 uploadFile 合法域名视频播放黑屏或报错m3u8 地址是 HTTP 协议更换为 HTTPS 地址或用 CDN签到定位不准定位权限没声明或经纬度换算错误manifest 配置位置权限核对经纬度计算逻辑支付拉起失败支付权限未开通签名错误检查商户号和签名密钥排查违规记录自定义导航栏布局错乱未适配不同机型的状态栏高度用 getMenuButtonBoundingClientRect 计算安全区分享到好友后页面空白onShareAppMessage 返回路径错误检查分享 path 参数是否包含正确页面路径这里讲一下 Burp Suite 抓包微信小程序的问题。做接口调试和安全测试时抓包几乎是无法绕过的一步。用 Burp Suite 抓 PC 端微信小程序和手机端小程序原理上都差不多配置代理、安装并信任证书。但因为小程序部分接口走的 HTTPS 且做了证书固定抓包时经常遇到流量能看到但内容解密不了的情况。可行的方案是给微信开发者工具配置代理把请求转发到 Burp 监听的地址上这样在开发阶段就能很方便地看到完整的请求和响应数据。不过这只适用于你自己开发的程序调试抓别人的小程序涉及法律和安全风险不建议这么做。分享功能还有一个容易被忽略的坑onShareAppMessage 如果被全局混入或覆盖会导致自定义分享失效。查问题时要重点看 App.vue 里有没有用 Vue.mixin 对分享方法做了全局注入如果有页面级定义的 onShareAppMessage 可能会被覆盖或者顺序异常。这个排查方向能帮你节省大量时间。5. 小程序端进阶功能与项目扩展建议5.1 使用 ECharts 实现数据可视化课程平台的教师端要看到学生作业提交率、签到率等统计数据这些图表在小程序里也可以实现。Uniapp 集成 ECharts 的方案已经比较成熟比较推荐的方式是通过 renderjs 渲染这样图表在小程序和 H5 端都能用性能也不错。需要注意的问题ECharts 的渲染组件在小程序端通常不能直接使用标准的 npm 包而是要用 uni-echarts 这类封装库或者手动把 echarts.min.js 和 ec-canvas.js 放入组件目录。初始化图表时要在 onReady 生命周期里执行因为此时 DOM 才真正挂载完成如果在 onLoad 里取不到节点会导致画布空白。5.2 Uniapp 自定义分享好友的完整方案课程分享是教学平台一个重要的拉新入口。Uniapp 里自定义分享通过 onShareAppMessage 实现。这个 API 虽然看起来简单但返回对象里的 path 参数如果写错分享出去的海报点击后会直接进入错误页面。我常用的写法是在分享方法里动态拼接页面路径和参数onShareAppMessage() { return { title: 推荐你学习${this.courseName}, path: /pages/course/detail?id${this.courseId}, imageUrl: this.courseCover } }这个函数的返回对象可以被用户手动转发也可以被按钮触发转发。事件触发方式有两种一种是右上角菜单分享一种是用 button 的 open-typeshare。要注意页面里的 button 组件如果同时配置了 open-typeshare 和 click 事件点击的时候两个事件都会被触发逻辑上要处理好避免重复操作。5.3 项目后续扩展方向课程教学辅助平台做完基础功能之后后续想要继续完善可以从下面几个方向去扩展。第一个是增加实时互动能力比如直播课程、课堂连麦这部分可以用微信小程序的 live-player 组件实现但对服务端推流的要求会高很多。第二个方向是接入消息订阅用小程序的消息订阅能力给学生发送作业截止提醒和签到提醒这个不需要用户必须打开小程序触达效果很好。第三个方向是增加数据报表能力把学生的学习时长、作业得分趋势、课程活跃度等数据汇总成报表为教师教学提供数据支持这也是项目做深之后比较有特色的一个方向。如果把项目定位成毕设或者课程设计并且想拿高分强烈建议把消息订阅和 ECharts 数据看板这两个功能做进去。这两个功能在答辩时视觉效果很好而且能展示你处理小程序能力边界问题的能力比单纯讲解 CRUD 接口要加分得多。回到 SSM 这套技术栈本身。它虽然在快速开发效率上比不上 Spring Boot但胜在逻辑透明、依赖清晰对于需要深度理解 Java Web 开发原理的项目来说反而是个优势。把这个项目从零完整做下来你对 Spring 的 IOC/AOP、SpringMVC 的请求链路、MyBatis 的动态 SQL、小程序的完整生命周期都会有一个非常扎实的掌握。这是单纯调用现成脚手架快速出 demo 无法替代的经验积累。最后再分享一个小技巧项目调试阶段尽量多打印后端日志把每个接口的入参和出参都打出来。前端接口联调报错百分之八十的问题都能通过日志定位出来而不是靠猜靠试。我见过太多人明明代码逻辑没问题最后发现是参数名大小写不一致导致的对接失败这种情况有一份清晰的接口日志两分钟就能查出原因。磨刀不误砍柴工日志打好了联调效率能翻倍。
返回列表