ARTICLE DETAIL

资讯详情

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

微信小程序+Java后端:校园服务平台毕业设计实战指南

微信小程序+Java后端:校园服务平台毕业设计实战指南 简介这是一套面向高校计算机相关专业学生的毕业设计/课程设计完整方案主题为微信小程序结合Java后端的校园服务平台适合正在准备毕设、需要可运行项目参考或想练习前后端分离开发的学习者。资源包共1112个文件约27.76MB涵盖小程序端wxml、wxss、js与vue页面文件Java后端源码以及sql数据库脚本、json配置、png与svg图片素材和mp4演示视频结构完整、层次清晰。功能上区分管理员、卖家与用户三类角色管理员负责用户、校园公告、卖家、二手商品、订单信息与发货等后台管理卖家可发布维护二手商品并处理订单发货用户可注册登录、浏览公告、查询购买商品并管理个人订单。随包附演示视频与说明文档便于快速理解业务流程、对照源码梳理数据库设计与接口逻辑也可作为二次开发或答辩演示的基础模板。目前已有140人学习下载。1. 校园服务平台从零到一为什么微信小程序加 Java 后端是毕业设计里最稳的那条路每年到了三四月实验室里总有一批人对着选题发愁。想做点看得见摸得着的东西又怕技术栈太偏、资料太少、答辩时被老师问穿。我带过几届本科毕设也帮不少同学救过火最后发现一个规律微信小程序 Java 后端这套组合是计算机毕业设计里容错率最高的方案没有之一。原因很实在——小程序端有官方开发者工具兜底Java 后端有 Spring Boot 生态托底两边都有海量可查的公开资料你踩的坑大概率别人已经踩过并写了博客。这篇笔记要拆解的就是标题里那个.rar压缩包背后代表的完整工程一个校园服务平台前端跑在微信小程序里后端用 Java 写接口中间连着 MySQL 数据库最后交付源码、演示视频、说明文档和数据库脚本。我会按真实开发顺序把环境搭建、接口设计、数据库建模、联调排错、部署验收这几个环节讲透。适合正在做毕设、需要一套能跑通、能答辩、能写进论文的系统的人。读完你至少知道每一步该敲什么命令、参数怎么配、哪里最容易翻车。2. 技术选型与工程骨架为什么是 Spring Boot 而不是 Servlet2.1 小程序端与 Java 后端的职责边界先把架构说清楚不然后面写代码容易乱。校园服务平台通常包含这些模块用户登录与身份认证、校园资讯浏览、失物招领发布、二手交易信息、活动报名、消息通知。这些功能里小程序负责展示和交互Java 后端负责业务逻辑和数据持久化两边通过 HTTPS 接口通信。小程序端的优势在于免安装、即用即走学生用户不需要下载 App扫码或搜索就能进入。但小程序有包体积限制主包不能超过 2MB所以图片、视频这类静态资源必须放后端或对象存储不能塞进小程序工程里。Java 后端的优势在于生态成熟Spring Boot 把 Tomcat 内嵌了打成一个 jar 包就能跑不需要单独装 Web 服务器这对毕设部署来说省了太多事。我一般会这样划分小程序端只做三件事——收集用户输入、调用接口、渲染返回数据。所有校验逻辑、权限判断、数据组装都放后端。这样做的好处是答辩时老师问“你的业务逻辑在哪”你可以明确指向后端 Service 层而不是含糊地说“前后端都有”。2.2 用 Spring Initializr 生成后端骨架不要手动建 Maven 工程容易漏依赖。直接用 Spring Initializr 生成选好依赖再下载。下面是核心依赖的pom.xml片段我保留了毕设最常用的几个!-- Spring Boot Web提供 REST 接口能力 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- MyBatis-Plus简化数据库操作毕设够用 -- dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency !-- MySQL 驱动 -- dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope /dependency !-- JWT做登录令牌比 Session 更适合小程序 -- dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt-api/artifactId version0.11.5/version /dependency这里解释几个关键选择。MyBatis-Plus 而不是原生 MyBatis是因为它自带BaseMapper单表增删改查不用写 XML毕设时间紧能省一半代码量。JWT 而不是 Session是因为小程序没有浏览器 Cookie 机制用 Token 放在请求头里更自然后端也不用维护会话状态重启服务不影响已登录用户。数据库连接配置写在application.yml里几个参数必须改spring: datasource: url: jdbc:mysql://localhost:3306/campus_service?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 你的密码 driver-class-name: com.mysql.cj.jdbc.DriverserverTimezone必须设成Asia/Shanghai否则插入时间会差 8 小时这个坑我见过太多人踩。characterEncodingutf8保证中文不乱码少了这个参数失物招领里的物品描述可能变成问号。2.3 小程序工程的目录结构与请求封装小程序端用原生开发就行不需要上 uni-app 或 Taro毕设答辩时原生代码更直观。目录结构建议这样组织miniprogram/ ├── pages/ # 页面目录 │ ├── index/ # 首页 │ ├── login/ # 登录页 │ └── publish/ # 发布页 ├── utils/ │ └── request.js # 请求封装 ├── app.js └── app.json请求封装是必须做的不然每个页面都写一遍wx.request改接口地址时会疯掉。下面是一个带 Token 自动携带和错误统一处理的封装// utils/request.js const BASE_URL http://localhost:8080/api; function request(options) { return new Promise((resolve, reject) { wx.request({ url: BASE_URL options.url, method: options.method || GET, data: options.data || {}, header: { Content-Type: application/json, // 从本地缓存取 Token登录后存入 Authorization: wx.getStorageSync(token) || }, success(res) { if (res.statusCode 200) { resolve(res.data); } else if (res.statusCode 401) { // Token 过期跳回登录页 wx.navigateTo({ url: /pages/login/login }); reject(res.data); } else { wx.showToast({ title: res.data.msg || 请求失败, icon: none }); reject(res.data); } }, fail(err) { wx.showToast({ title: 网络异常, icon: none }); reject(err); } }); }); } module.exports { request };这段代码的逻辑是所有请求走同一个函数自动拼接基础地址、自动带 Token、自动处理 401 和网络错误。参数说明——BASE_URL在开发阶段指向本机 8080 端口上线后改成服务器域名Authorization头里放 JWT后端拦截器会校验。注意小程序正式发布要求接口必须是 HTTPS 且域名已备案但毕设演示阶段可以在开发者工具里勾选“不校验合法域名”来用 HTTP 调试。3. 数据库建模与接口设计把 ER 图变成能跑的 SQL3.1 校园服务平台的核心表结构数据库设计是毕设的重头戏答辩老师最爱问“你这几张表什么关系”。校园服务平台至少需要这几张表用户表、资讯表、失物招领表、二手物品表、活动表、报名记录表。下面给出用户表和失物招领表的建表 SQL其他表结构类似-- 用户表存微信 openid 和基本信息 CREATE TABLE user ( id BIGINT NOT NULL AUTO_INCREMENT COMMENT 主键, openid VARCHAR(64) NOT NULL COMMENT 微信唯一标识, nickname VARCHAR(64) DEFAULT NULL COMMENT 昵称, avatar VARCHAR(255) DEFAULT NULL COMMENT 头像地址, phone VARCHAR(20) DEFAULT NULL COMMENT 手机号, role TINYINT DEFAULT 0 COMMENT 0学生 1管理员, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_openid (openid) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表; -- 失物招领表type 区分失物和招领 CREATE TABLE lost_found ( id BIGINT NOT NULL AUTO_INCREMENT, user_id BIGINT NOT NULL COMMENT 发布人, type TINYINT NOT NULL COMMENT 0失物 1招领, title VARCHAR(100) NOT NULL, description TEXT, images VARCHAR(1000) COMMENT 图片URL逗号分隔, status TINYINT DEFAULT 0 COMMENT 0进行中 1已完成, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_user_id (user_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT失物招领表;几个设计要点。openid加了唯一索引因为一个微信用户只能对应一条记录重复插入会报错这比在代码里查重更可靠。images字段用逗号分隔存多个图片 URL毕设阶段够用不用单独建图片表省事。role字段区分学生和管理员管理员可以删除违规帖子这个权限控制在后端拦截器里做。3.2 微信登录接口的实现与手机号获取微信小程序的登录流程是毕设里最容易卡住的地方。核心逻辑是小程序调wx.login拿到临时 code传给后端后端拿 code 去微信服务器换 openid再生成 JWT 返回给小程序。下面是后端换 openid 的代码// 调用微信接口换取 openid public String getOpenid(String code) { String url https://api.weixin.qq.com/sns/jscode2session ?appid appId secret appSecret js_code code grant_typeauthorization_code; // 用 RestTemplate 发 GET 请求 ResponseEntityString response restTemplate.getForEntity(url, String.class); JSONObject json JSON.parseObject(response.getBody()); // 返回 openid如果失败会返回 errcode return json.getString(openid); }参数说明——appId和appSecret在小程序管理后台的“开发设置”里拿不要硬编码在代码里建议放配置文件。code只能用一次五分钟内有效所以不能缓存复用。如果返回的openid为空先检查errcode常见的是 40029code 无效和 45011频率限制。获取手机号是另一个高频需求。小程序端用button open-typegetPhoneNumber触发回调里拿到加密的encryptedData和iv传给后端解密。后端用 AES 解密密钥是session_key这个值在换 openid 时一起返回必须存在服务端不能下发到小程序。解密代码网上很多核心是AES/CBC/PKCS5Padding模式这里不展开但提醒一句session_key会过期解密失败先重新登录。3.3 接口规范与统一返回格式后端接口返回格式必须统一不然小程序端处理起来很乱。我一般用这个结构{ code: 200, msg: success, data: {} }code为 200 表示成功401 表示未登录500 表示服务器错误。data里放具体业务数据列表接口就放数组详情接口就放对象。后端用一个Result类包装public class ResultT { private Integer code; private String msg; private T data; // 静态工厂方法方便调用 public static T ResultT success(T data) { ResultT r new Result(); r.code 200; r.msg success; r.data data; return r; } public static T ResultT error(Integer code, String msg) { ResultT r new Result(); r.code code; r.msg msg; return r; } }这样 Controller 里只需要return Result.success(list)代码干净。小程序端request.js里判断res.data.code 200再取data逻辑一致。4. 前后端联调与部署从本机跑通到服务器上线4.1 本地联调的三个关键配置本地联调阶段小程序开发者工具和后端 IDEA 同时开着最容易出的问题是请求发不出去。三个配置必须检查第一小程序开发者工具右上角“详情”里勾选“不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书”。不勾这个http://localhost:8080的请求会被拦截。第二后端application.yml里配置跨域。虽然小程序请求不受浏览器同源策略限制但如果你用浏览器测试接口跨域会报错。加一个配置类Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) .allowedMethods(GET, POST, PUT, DELETE) .allowCredentials(true) .maxAge(3600); } }第三后端端口别用 80本地容易冲突。8080 是默认值如果被占用在application.yml里改server.port。4.2 用宝塔面板部署 Spring Boot 项目毕设演示通常需要外网访问把后端部署到云服务器是常见做法。用宝塔面板可以少敲很多命令。步骤是先在服务器上装宝塔然后在软件商店装 MySQL 和 Java 项目管理器。接着把本地打好的 jar 包上传到服务器在 Java 项目管理器里添加项目选 jar 包路径填启动端口点启动。数据库导入用宝塔的 phpMyAdmin新建一个库把本地导出的.sql文件导入。注意本地和服务器上的数据库名、用户名、密码要一致不一致就改application.yml再重新打包。小程序端的BASE_URL改成服务器地址比如https://你的域名/api。域名需要在小程序管理后台的“开发设置”里配置为 request 合法域名且必须是 HTTPS。毕设阶段如果没有域名可以用服务器 IP 加端口但小程序正式版不支持 IP所以演示时用开发者工具的“不校验域名”选项。4.3 演示视频的录制与说明文档的整理演示视频不是随便录屏就行。答辩老师看视频的时间有限你要在 3 到 5 分钟内展示完整流程登录、浏览资讯、发布失物招领、查看报名记录、管理员删除帖子。录制前把数据库清空用真实数据走一遍避免出现“暂无数据”的尴尬。说明文档一般包括项目简介、技术栈、环境要求、部署步骤、接口清单、数据库表说明。接口清单用表格列出来比大段文字清楚。数据库表说明把每张表的字段、类型、含义列出来答辩时老师翻文档就能看懂。5. 避坑与排查那些让我熬夜的常见问题5.1 小程序请求返回 400 或 401现象小程序端调用接口返回 400 Bad Request 或 401 Unauthorized。原因400 通常是请求参数格式不对比如后端要 JSON你传了表单或者日期格式不匹配。401 是 Token 没带或已过期。解决先看后端控制台有没有异常堆栈400 多半是HttpMessageNotReadableException。检查wx.request的header里Content-Type是不是application/jsondata是不是对象而不是字符串。401 就检查Authorization头有没有取到 TokenToken 是不是在登录后存进了wx.setStorageSync。5.2 数据库插入中文变成问号现象失物招领的标题在数据库里显示为???。原因数据库、表、连接三处的字符集不一致。常见的是建库时用了latin1或者 JDBC URL 里没写characterEncodingutf8。解决建库语句用CREATE DATABASE campus_service DEFAULT CHARSET utf8mb4;建表也用utf8mb4。JDBC URL 加上useUnicodetruecharacterEncodingutf8。已经建好的表用ALTER TABLE lost_found CONVERT TO CHARACTER SET utf8mb4;转换。5.3 时间字段差 8 小时现象小程序端显示发布时间是 8 小时前。原因MySQL 时区是 UTCJava 取出来按 UTC 解析但实际是北京时间。解决JDBC URL 加serverTimezoneAsia/Shanghai。如果还不对在实体类的日期字段上加JsonFormat(pattern yyyy-MM-dd HH:mm:ss, timezone GMT8)。5.4 图片上传后小程序显示不出来现象发布失物招领时上传了图片列表里图片裂开。原因图片存在服务器本地磁盘但小程序访问的 URL 是http://localhost:8080/upload/xxx.jpg真机上 localhost 指向手机自己。解决后端把图片存到服务器某个目录通过静态资源映射暴露出去返回的 URL 用服务器公网地址。或者用对象存储毕设阶段用服务器本地存储加 Nginx 静态代理就行。5.5 打包后 jar 运行报数据库连接失败现象本地 IDEA 跑得好好的打成 jar 放到服务器上启动就报Access denied或Communications link failure。原因服务器上的 MySQL 没启动或者用户名密码不对或者防火墙没放行 3306 端口。解决先在服务器上用mysql -u root -p能登录确认密码。然后检查application.yml里的密码和服务器一致。最后确认宝塔安全组和服务器防火墙都放行了 3306。如果 MySQL 只允许 localhost 连接要改用户权限host为%。6. 进阶技巧让毕设从及格变成优秀6.1 用拦截器做统一权限校验基础版是在每个 Controller 方法里判断 Token代码重复且容易漏。进阶做法是写一个HandlerInterceptor在preHandle里统一校验 Token把用户信息塞进ThreadLocalController 里直接取。这样管理员接口只需要加一个AdminOnly注解拦截器里判断角色即可。代码量减少答辩时也显得有设计感。6.2 分页查询用 MyBatis-Plus 的 Page 对象列表接口一定要分页不然数据多了小程序卡死。MyBatis-Plus 的分页很简单PageLostFound page new Page(pageNum, pageSize); LambdaQueryWrapperLostFound wrapper new LambdaQueryWrapper(); wrapper.eq(LostFound::getType, type) .orderByDesc(LostFound::getCreateTime); PageLostFound result lostFoundMapper.selectPage(page, wrapper);pageNum从 1 开始pageSize建议 10 到 20。返回的result.getRecords()是当前页数据result.getTotal()是总条数小程序端做上拉加载时用得到。6.3 用定时任务清理过期数据失物招领和二手物品有“已完成”状态但时间久了数据会堆积。加一个Scheduled定时任务每天凌晨把 30 天前已完成的数据归档或删除。这个功能写进论文的“系统优化”章节比单纯增删改查有亮点。Scheduled(cron 0 0 3 * * ?) // 每天凌晨3点执行 public void cleanExpiredData() { LocalDateTime thirtyDaysAgo LocalDateTime.now().minusDays(30); lostFoundMapper.delete(new LambdaQueryWrapperLostFound() .eq(LostFound::getStatus, 1) .lt(LostFound::getCreateTime, thirtyDaysAgo)); }cron表达式六位分别代表秒、分、时、日、月、周。0 0 3 * * ?就是每天 3 点整。注意启动类上要加EnableScheduling注解否则定时任务不生效。6.4 答辩前必做的三项检查第一把数据库里的测试数据清掉重新录入一批看起来真实的校园数据比如“图书馆三楼捡到黑色钱包”“周六下午篮球赛报名”。第二把小程序开发者工具里的“不校验域名”取消勾选确认正式域名下所有接口都能通。第三录一遍完整演示视频自己看一遍把卡顿和报错的地方修掉。我自己的习惯是答辩前一天晚上把整个流程走三遍每遍都换不同角色登录学生发帖、管理员删帖、游客浏览确保没有遗漏。这个方案从技术栈到部署都不算难难的是细节的耐心。希望帮到你。本文还有配套的精品资源点击获取
返回列表