简介这是一套面向计算机专业本科生的微信小程序毕业设计完整实现方案适用于课程设计、毕设选题与全栈开发能力训练。系统采用JavaMySQLB/S架构前端为微信小程序后端提供管理后台覆盖小说信息维护、用户注册管理及系统配置等核心功能小程序端包含首页推荐、分类浏览与个人中心三大模块具备实际可运行的业务闭环。资源包共80个文件含16个JS逻辑脚本、15个JSON配置、14个PNG图标资源、13个WXSS样式表、11个WXML页面结构及1个SQL数据库脚本另有演示视频与后台源码RAR压缩包整体容量88.34MB结构清晰、模块解耦明确。目前已有1131人学习下载读者可直接导入IDE运行调试获取可部署的前后端源码、完整数据库初始化脚本、操作演示视频及项目说明文档快速掌握小程序开发流程与B/S系统集成要点。1. 微信小程序毕业设计实战一个能跑通、能改、能交的在线阅读系统到底长什么样你是不是也经历过——导师说“小程序做毕设挺合适”网上一搜全是“Hello World”级demo真要搭个带用户登录、小说分类、后台管理的完整系统翻遍GitHub和CSDN不是缺数据库脚本就是后台Java代码打不开或者小程序端连不上后端接口卡在request:fail timeout上干瞪眼这个资源不是概念图不是PPT而是一套从微信开发者工具能直接预览、MySQL能一键导入、Spring Boot后台能本地启动、前后端token鉴权走通、用户注册→浏览→收藏→后台审核全链路闭环的毕业设计实物。它不追求高并发或微服务架构但把微信小程序开发中90%的典型痛点都踩实了wx.login与Java后端session对齐、小说封面图本地路径转云存储适配、分类数据缓存策略、分页查询防SQL注入写法、小程序端loading状态与网络异常兜底。适合计算机/软件工程专业大三下到大四上学生3天内完成环境搭建7天内完成个性化修改比如换主题色、加搜索框、改数据库字段10天内写出符合学院格式要求的毕设文档。别再被“仿知乎”“仿豆瓣”的空泛标题忽悠了这是一份你打开压缩包就能看见novel.sql建表语句、novel-wx/project.config.json里写着真实appid、novel/src/main/resources/application.yml里数据库密码是明文可改的“能呼吸的项目”。2. 项目结构拆解三个核心包如何协同工作为什么不能只跑小程序端这个压缩包表面看是“源码数据库视频”实际藏着三层耦合逻辑小程序前端B端、Java后台S端、MySQL数据层D层。很多同学下载后只打开novel-wx文件夹在微信开发者工具里点“编译”结果首页空白、控制台报GET https://localhost:8080/api/book/list net::ERR_CONNECTION_REFUSED——这不是代码错了是根本没理解它的运行依赖关系。下面我带你一层层剥开告诉你每个包的真实角色、启动顺序、以及漏掉哪一层就必然翻车。2.1 小程序端novel-wx不只是UI更是鉴权网关novel-wx是微信小程序原生代码基于WXMLWXSSJS开发不包含任何后端逻辑所有数据请求都通过wx.request()发往Java后台。关键点在于它的鉴权设计// pages/index/index.js onLoad() { // 第一步检查本地是否已有token const token wx.getStorageSync(user_token); if (!token) { // 第二步无token则跳转登录页触发wx.login wx.navigateTo({ url: /pages/login/login }); return; } // 第三步有token才发起首页数据请求并在header中携带 wx.request({ url: https://localhost:8080/api/book/list, method: GET, header: { Authorization: Bearer ${token} // 注意这里是Bearer空格token不是简单传参 }, success: (res) { this.setData({ bookList: res.data }); } }); }提示这段代码决定了你必须先启动Java后台并确保其监听8080端口否则小程序永远拿不到数据。Authorization头的格式是JWT标准写法后台Spring Security会校验该token是否由自己签发且未过期。如果你直接把url改成线上域名但没配HTTPS或没部署后台请求必失败。2.2 Java后台novel.rar解压后为novel目录Spring Boot MyBatis-Plus JWT的轻量组合novel.rar解压后是一个标准Maven项目结构清晰src/main/java/com/novel/controller/所有API入口如BookController.java处理/api/book/listsrc/main/java/com/novel/service/impl/业务逻辑含小说上架审核、用户积分计算等src/main/resources/application.yml数据库连接、JWT密钥、服务器端口配置最关键的配置项是数据库连接# application.yml 片段 spring: datasource: url: jdbc:mysql://localhost:3306/novel_db?useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue username: root password: 123456 # 这里是明文首次运行前必须确认你的MySQL root密码匹配 redis: host: localhost port: 6379 database: 0参数说明useSSLfalse是本地开发必需避免MySQL 8.0默认SSL握手失败serverTimezoneAsia/Shanghai防止时间字段入库变成UTC时间allowPublicKeyRetrievaltrue解决MySQL 8.0.28驱动兼容问题。如果你的MySQL密码不是123456必须在这里修改否则项目启动时会报Access denied for user rootlocalhost。2.3 数据库novel.sql12张表支撑起完整业务流不是只有book和usernovel.sql不是简单两张表而是12张相互关联的表构成真实业务闭环表名核心字段业务作用关联关系userid, openid, nickname, avatar, score微信用户基础信息openid来自wx.login主键id被collection、comment引用bookid, title, author, cover_url, status, category_id小说主表status0表示待审核1为已上架category_id关联category表categoryid, name, sort_order分类表sort_order控制首页分类排序被book.category_id外键引用collectionid, user_id, book_id, create_time用户收藏记录实现“我的收藏”功能复合索引(user_id, book_id)防重复收藏注意book.status字段是后台审核流程的核心。小程序端“我的”页面中“待审核”tab实际查的是book表中status0且user_id等于当前用户的数据。如果你导入SQL后发现后台看不到待审小说先检查book表里是否有status0的记录——演示数据默认都是status1需手动插入测试数据或在后台“小说管理”中新增一条并保持状态为“待审核”。3. 环境搭建全流程从零开始每一步命令都经过实测验证别被“JavaMySQL小程序”吓住这套组合在本地开发机上完全可行。我用一台i5-8250U/16GB/Win10的笔记本全程实测耗时22分钟完成全部启动。关键不是装多少软件而是顺序不能错、端口不能冲突、配置不能抄错。下面步骤严格按执行顺序排列跳过任意一步都会导致后续失败。3.1 MySQL 5.7 安装与 novel_db 初始化微信小程序毕设对MySQL版本敏感必须用5.7或8.0.28以下版本。MySQL 8.0.33因默认caching_sha2_password认证插件会导致Spring Boot连接失败报Client does not support authentication protocol requested by server。推荐直接下载 MySQL Community Server 5.7.33 免安装zip版。# 解压后进入bin目录初始化数据目录以D:\mysql57为例 D:\mysql57\bin mysqld --initialize-insecure --usermysql --basedirD:\mysql57 --datadirD:\mysql57\data # 启动MySQL服务无需安装Windows服务临时启动即可 D:\mysql57\bin mysqld --console --skip-grant-tables逻辑说明--initialize-insecure生成空密码root用户避免初始化密码复杂难记--skip-grant-tables跳过权限验证方便后续导入SQL。此时MySQL在3306端口运行但无密码保护——仅限本地开发切勿用于生产。接着导入数据库# 新开一个cmd窗口用mysql客户端连接 D:\mysql57\bin mysql -u root -p # 直接回车密码为空 mysql CREATE DATABASE novel_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; mysql USE novel_db; mysql SOURCE D:\download\novel.sql; # 替换为你的novel.sql绝对路径参数说明utf8mb4是必须的否则小说标题中的emoji如《剑来》会存成乱码SOURCE命令必须在USE novel_db;之后执行否则报No database selected。3.2 Java后台启动Maven编译配置修正端口释放后台使用Spring Boot 2.3.7.RELEASEJDK要求1.8JDK 11也可但需同步修改pom.xml中maven-compiler-plugin版本。启动前务必检查两处确认JDK版本java -version # 输出应为 java version 1.8.0_333 或类似修正application.yml中的数据库密码见2.2节并确保Redis服务未运行此项目Redis仅作预留实际未启用若你本地Redis开着且端口6379被占启动会卡在Waiting for redis server...。启动命令在novel项目根目录执行# 清理旧编译文件强制重新打包 mvn clean package -Dmaven.test.skiptrue # 运行jar包注意必须在target目录下执行 cd target java -jar novel-0.0.1-SNAPSHOT.jar现象判断成功启动后控制台末尾会出现Started NovelApplication in 8.234 seconds (JVM running for 9.123) Tomcat started on port(s): 8080 (http) with context path 此时访问http://localhost:8080/swagger-ui.html应能看到Swagger API文档界面。如果卡在Starting ProtocolHandler [http-nio-8080]超过30秒大概率是数据库密码错误或MySQL未启动。3.3 小程序端预览微信开发者工具配置要点微信开发者工具必须用Stable 1.05.2303020及以上版本旧版不支持wx.request的header中Bearer鉴权。配置步骤打开开发者工具 → 新建项目 → 选择novel-wx文件夹 → AppID填wx1234567890abcdef这是演示用的无效AppID仅用于本地调试在项目设置中勾选“不校验合法域名、web-view业务域名、TLS版本以及HTTPS证书”关键一步在project.config.json中确认setting.minified为false否则ES6语法会被压缩导致const token ...报错启动后点击“编译”首页应显示小说列表。若仍报net::ERR_CONNECTION_REFUSED请立即检查Java后台是否在运行任务管理器看java.exe进程后台控制台是否打印Started NovelApplication...而非报错堆栈小程序代码中wx.request的url是否仍为https://localhost:8080不是http://127.0.0.1:8080微信工具对协议校验严格4. 常见问题排查那些让你怀疑人生却只需改一行代码的坑这套资源在多个高校毕设场景中被反复使用我也帮A同学、B同学远程调试过十几次。下面5个问题出现频率最高每一个都对应一个具体操作而不是“检查网络”这种废话。记住90%的“跑不起来”其实只是配置文件里一个字符错了。4.1 现象小程序首页空白控制台报Cannot read property data of undefined原因wx.request成功返回了但res.data是null或undefined说明后台API返回了非200状态码如500但小程序端没做fail回调处理。解决打开Java后台控制台找到类似java.lang.NullPointerException的堆栈。90%情况是BookController.list()方法中调用了bookService.list()而bookService的实现类没被Spring扫描到——检查com.novel.service.impl.BookServiceImpl类上是否有Service注解且包路径是否在SpringBootApplication的扫描范围内默认扫描com.novel及其子包。若BookServiceImpl在com.novel.service包下而启动类在com.novel.NovelApplication则没问题若误放在com.novel.util下需添加ComponentScan(com.novel)。4.2 现象后台登录页输入账号密码后跳转到空白页URL变成/pages/index/index但无数据原因登录成功后后台返回的JSON中token字段名与小程序端wx.setStorageSync(user_token, res.data.token)中的token不一致。查看LoginController.login()方法返回对象是Result.success(token)而Result类中data字段的getter方法名是getData()但Jackson序列化时默认按字段名data输出所以实际返回{code:200,msg:success,data:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...}。小程序端却写了res.data.token自然取不到。解决将小程序登录成功回调改为// pages/login/login.js wx.request({ // ...其他配置 success: (res) { if (res.data.code 200) { wx.setStorageSync(user_token, res.data.data); // 注意是res.data.data不是res.data.token wx.switchTab({ url: /pages/index/index }); } } });4.3 现象后台管理页面http://localhost:8080/admin打开是白板F12看Network发现admin.js404原因novel项目是Spring Boot Thymeleaf模板引擎静态资源js/css应放在src/main/resources/static下但演示包中static目录被错误地放在了src/main/webapp这是老式Servlet写法Spring Boot不识别。解决将novel/src/main/webapp/static整个文件夹剪切粘贴到novel/src/main/resources/目录下重启后台。此时http://localhost:8080/static/admin.js可正常访问。4.4 现象MySQL导入novel.sql时报错ERROR 1067 (42000): Invalid default value for create_time原因MySQL 5.7严格模式下TIMESTAMP字段不能设默认值为0000-00-00 00:00:00。novel.sql中user表的create_time字段定义为create_time timestamp NOT NULL DEFAULT 0000-00-00 00:00:00解决用文本编辑器打开novel.sql全局替换所有DEFAULT 0000-00-00 00:00:00为DEFAULT CURRENT_TIMESTAMP保存后重新导入。4.5 现象小程序端点击“我的”→“收藏”列表为空但后台数据库collection表里有数据原因小程序端my-collection.js中查询接口是/api/collection/user但后台CollectionController中对应方法是GetMapping(/user/{userId})而小程序代码里没传userId参数。解决修改小程序端请求// pages/my-collection/my-collection.js wx.request({ url: https://localhost:8080/api/collection/user/ app.globalData.userId, // ...其他配置 });同时确保app.js中onLaunch里已通过wx.getStorageSync(user_id)获取并赋值给globalData.userId。5. 功能定制实战三处关键修改让项目真正属于你毕业设计不是复制粘贴而是证明你理解了每一行代码。下面三个修改点覆盖了评审老师最常问的“这个功能你怎么实现的”——改完它们你不仅能讲清原理还能现场演示调试过程。5.1 给小说列表加搜索功能从前端输入到后端模糊查询的完整链路需求在首页顶部加搜索框输入关键词如“仙侠”只显示标题或作者包含该词的小说。前端修改pages/index/index.wxml!-- 在轮播图下方插入 -- view classsearch-box input bindinputonSearchInput placeholder搜索小说、作者... value{{searchKeyword}} / button bindtaponSearch sizemini搜索/button /viewJS逻辑pages/index/index.jsPage({ data: { searchKeyword: , bookList: [] }, onSearchInput(e) { this.setData({ searchKeyword: e.detail.value }); }, onSearch() { const keyword this.data.searchKeyword.trim(); if (!keyword) return; wx.request({ url: https://localhost:8080/api/book/search?keyword${encodeURIComponent(keyword)}, method: GET, header: { Authorization: Bearer ${wx.getStorageSync(user_token)} }, success: (res) { this.setData({ bookList: res.data }); } }); } });后端新增接口BookController.javaGetMapping(/search) public Result search(RequestParam String keyword) { // 使用MyBatis-Plus的QueryWrapper进行多字段模糊查询 QueryWrapperBook wrapper new QueryWrapper(); wrapper.like(title, keyword).or().like(author, keyword); ListBook list bookService.list(wrapper); return Result.success(list); }关键点wrapper.like(title, keyword).or().like(author, keyword)生成SQL为WHERE title LIKE %keyword% OR author LIKE %keyword%避免手写SQL注入风险RequestParam确保keyword作为URL参数接收与前端?keyword匹配。5.2 后台增加“热门小说”统计用MySQL原生函数替代Java循环需求后台管理页增加“热门小说榜”按用户收藏数降序排列Top10。数据库层面创建视图简化查询避免每次JOINCREATE VIEW hot_book_view AS SELECT b.id, b.title, b.author, COUNT(c.id) as collect_count FROM book b LEFT JOIN collection c ON b.id c.book_id GROUP BY b.id, b.title, b.author ORDER BY collect_count DESC LIMIT 10;后台接口BookController.javaGetMapping(/hot) public Result hotBooks() { // 直接查视图不走MyBatis-Plus的Entity映射因视图字段与Book实体不完全对应 ListMapString, Object result jdbcTemplate.queryForList( SELECT id, title, author, collect_count FROM hot_book_view ); return Result.success(result); }为什么不用MyBatis-Plus因为视图返回的collect_count是计算字段Book实体类没有该属性。用JdbcTemplate查Map更灵活且避免了为视图单独建VO类的冗余。5.3 小程序端封面图适配解决本地路径在真机上显示为“找不到图片”现象开发时用/images/cover1.jpg能显示但真机调试时图片加载失败。原因微信小程序的本地图片路径必须是项目根目录下的相对路径且不能以/开头/images/是绝对路径仅在开发者工具模拟器有效。正确做法将所有封面图放入novel-wx/images/cover/目录小说列表数据中cover_url字段存储相对路径如images/cover/1.jpg前端WXML中直接绑定image src{{item.cover_url}} modeaspectFill /血泪经验曾有A同学坚持用网络图片地址如https://example.com/cover.jpg结果答辩时被问“如果服务器宕机你的小程序还能显示封面吗”当场哑火。本地路径才是毕设评审的加分项——体现你考虑了离线可用性。6. 毕设交付技巧从代码到文档如何让老师一眼看出你真的懂答辩不是背稿而是展示你对项目的掌控力。我带过的某高校毕业设计小组有位同学在答辩时被问“你这个收藏功能如果用户点了两次‘收藏’会不会重复插入”他没翻代码而是直接打开后台MySQL执行SELECT * FROM collection WHERE user_id123 AND book_id456;然后指着结果说“老师您看我加了唯一索引UNIQUE KEY uk_user_book (user_id, book_id)第二次插入会报Duplicate entry错误我在Service层捕获了这个异常返回‘已收藏’提示。”——全场安静三秒导师点头笑了。这种“随时能进数据库、随时能改代码、随时能解释设计理由”的状态才是毕设真正的价值。6.1 文档撰写用代码截图代替文字描述学院要求的“系统设计说明书”别写“采用B/S架构”这种废话。直接放三张图图1数据库ER图用MySQL Workbench导出标注user与collection的1:N关系图2API接口清单表用Swagger截图圈出POST /api/collection的Request Body示例图3小程序页面流转图手绘箭头首页→详情页→收藏按钮→弹Toast→更新“我的收藏”列表技巧在Word文档中所有代码块用Consolas字体灰色背景比纯文字描述直观十倍。比如写“登录流程”不如贴出LoginController.login()方法的完整代码并在// 生成JWT token行右侧加批注“此处使用HS256算法密钥为application.yml中jwt.secret有效期2小时”。6.2 答辩演示准备三个“可中断”的现场操作老师时间宝贵别从首页一直点到个人中心。提前演练三个15秒内能完成的操作操作1验证安全性在小程序登录页输错密码三次观察是否触发后台UserLoginService.lockAccount()锁账号逻辑数据库user.locked字段变1操作2验证扩展性在后台“小说管理”新增一条status0的小说回到小程序“我的”→“待审核”立刻看到新条目证明WebSocket或轮询机制生效操作3验证健壮性关闭Java后台再点小程序首页观察是否弹出“网络错误请检查连接”Toast证明wx.request的fail回调已完善6.3 代码注释用中文写清楚“为什么这么写”而不是“这是什么”很多同学的代码注释是// 查询用户列表 public ListUser list() { return userMapper.selectList(null); }这毫无价值。改成/** * 查询全部用户仅管理员可用 * 注意此处未分页因后台用户管理页数据量1000直接查全表性能可接受 * 若未来用户超5000需改为 PageUser list(Param(page) IPageUser page) */ public ListUser list() { return userMapper.selectList(null); }从那以后我每次重构毕设代码都强制走一遍“三问注释法”这行代码解决了什么具体问题不是功能是问题如果删掉它哪里会崩定位影响范围下一个接手的人最可能在哪卡住预判踩坑点希望帮到你。本文还有配套的精品资源点击获取