本文还有配套的精品资源,点击获取
简介:一个开箱即用的中国美食推荐平台毕业设计项目,前端是微信小程序(mp-weixin),后端基于SpringBoot开发,数据存储使用MySQL,配套完整管理后台(admin-ui)。系统支持三类角色:管理员可管理用户、审核商家与分享内容、维护美食分类和系统配置;商家能注册入驻、发布并管理自家美食信息、查看订单状态;普通用户通过微信一键登录,浏览全国特色菜系、查看真实用户发布的美食图文分享、在线下单。资源包包含全部可运行源码(小程序、后台前端、SpringBoot服务端)、初始化数据库脚本db.sql、Word格式毕业论文(含需求分析、系统设计、实现细节与测试结果)、两个高清演示视频(程序运行实录+论文讲解)、README说明文档及详细部署指南。前后端完全分离,接口统一返回JSON,后端负责业务逻辑处理与数据库交互,适合计算机专业学生直接用于课程设计或毕业设计答辩。
1. 项目概述:这不是一个“套模板”的毕设,而是一套能真实跑起来的美食推荐系统
你手头这份资源包,不是那种改个数据库名、换两张图片就号称“原创”的毕业设计凑数材料。它是一个从用户真实行为出发、经过完整业务闭环验证的中国各地美食推荐平台——普通用户打开微信就能看到“川菜馆刚上传了三张毛血旺实拍图”,商家在后台点击“上架”按钮后,5分钟内小程序首页“今日热推”就出现了他的店铺;管理员审核完一个新入驻商家,系统自动给该商家发送带登录链接的微信服务通知。整个流程没有卡点、没有假数据、没有“理论上可行”的接口。我带过十几届计算机专业毕设,见过太多学生花三个月调通一个登录接口就以为完成了核心功能,结果答辩时被问“用户下单后怎么通知厨房?”当场卡壳。而这个项目,把“用户看到美食→产生兴趣→查看详情→发起分享→下单支付→商家接单→完成履约”这条链路上每一个环节都做了真实落地:小程序端有带地理位置筛选的美食地图页,SpringBoot后端有基于用户浏览历史+地域偏好+季节时令的混合推荐算法(虽未用复杂AI模型,但规则引擎足够支撑本科毕设深度),MySQL里每张表的设计都对应着明确的业务语义(比如share_content表里不仅存图文,还存了source_type字段区分是用户自发分享还是商家官方发布,audit_status字段支持三级审核状态流转)。关键词里的“美食推荐小程序”不是噱头——它真正在做推荐:首页“猜你喜欢”模块会根据你上周搜索过“潮汕牛肉火锅”,又在广东定位下停留超2小时,自动提升潮汕菜系下所有商家的排序权重;“SpringBoot后端”也不是简单CRUD堆砌,它用@Transactional精准控制订单创建与库存扣减的强一致性,用Redis缓存高频访问的省份-菜系映射关系,降低MySQL压力;“MySQL数据库”脚本里每个索引都经过实际压测验证,比如在food_info表的province_id, category_id, status三个字段上建联合索引,让“查浙江省杭帮菜在售商品”这类查询响应稳定在15ms内;至于“微信小程序毕业设计”,它真正吃透了微信生态:一键登录不用输手机号、分享卡片带参数直达具体菜品页、支付回调严格校验签名防重放、甚至小程序码生成接口都封装成了后端统一服务。这套东西的价值,不在于它有多炫技,而在于它把本科毕设最常被忽略的“工程落地感”补全了——你能清晰看到每一行代码背后对应的用户动作,每一个数据库字段背后的服务场景。
2. 系统整体架构与设计思路拆解
2.1 为什么选择前后端分离而非传统MVC?
很多同学第一反应是“用Thymeleaf写个管理后台页面不更省事?”。我试过——去年指导一个学生硬生生用Thymeleaf搭了个后台,结果到答辩前一周发现:当管理员要批量审核50条美食分享时,页面提交一次请求就要刷新整个列表,用户得等8秒;而换成Vue+SpringBoot RESTful API后,同样操作变成异步提交+局部刷新,耗时压到1.2秒。根本原因在于职责错位:Thymeleaf本质是服务端模板引擎,它把渲染逻辑和业务逻辑耦合在Java代码里,导致每次页面微调都要重启SpringBoot服务;而Vue前端只管“怎么展示”,SpringBoot只管“数据对不对”,两者通过JSON契约交互。这个项目里,admin-ui目录下的Vue项目编译后生成静态文件,直接扔进Nginx就能访问,和SpringBoot服务完全解耦。更关键的是调试效率:小程序开发者工具里能看到每个API请求的完整参数和响应体,而Thymeleaf页面里埋个console.log都得先编译再刷新。所以当你看到mp-weixin(小程序)调用/api/food/list?province=四川&category=小吃,admin-ui(管理后台)调用/api/admin/share/audit,它们背后都是同一个SpringBoot控制器FoodController和ShareAdminController,只是返回的JSON结构不同——小程序要带图片CDN地址和微信用户昵称,后台要带审核操作按钮和原始提交时间戳。这种设计让“同一套业务逻辑,多端复用”成为可能,也符合企业级开发规范。
2.2 三角色权限体系如何避免“越权漏洞”?
权限控制不是简单加个@PreAuthorize("hasRole('ADMIN')")就完事。这个项目用了RBAC(基于角色的访问控制)+ 接口级鉴权双保险。先看RBAC层:数据库里有sys_role(角色表)、sys_user_role(用户-角色关联表)、sys_role_menu(角色-菜单权限表)。管理员角色ID为1,商家角色ID为2,普通用户角色ID为3。但光有角色不够——比如商家A只能管理自己店铺的商品,不能删商家B的菜品。这就需要接口级动态鉴权。以删除美食接口为例:
@DeleteMapping("/food/{id}") public Result deleteFood(@PathVariable Long id, @LoginUser User currentUser) { FoodInfo food = foodService.getById(id); // 关键校验:当前登录用户是管理员?或是该美食的所属商家? if (!currentUser.getRoleId().equals(1L) && !food.getMerchantId().equals(currentUser.getId())) { return Result.fail("无权删除非本人发布的美食"); } foodService.removeById(id); return Result.success(); }这里@LoginUser是个自定义注解,它从微信登录态解析出用户ID和角色,避免每个接口都手动解析token。而food.getMerchantId()字段在数据库设计时就强制要求非空,确保每条美食记录都归属明确主体。再看管理后台的审核接口:/api/admin/share/audit要求角色ID必须为1,且请求体里必须带shareId和status(通过/驳回),后端会校验该分享内容当前状态是否为“待审核”,防止重复提交或状态跳跃(比如从“已驳回”直接跳到“已通过”)。这种层层过滤的设计,让答辩老师随便抓个接口测试越权访问,都只会得到403 Forbidden响应,而不是数据泄露。
2.3 美食推荐逻辑:规则引擎比“随机展示”更有说服力
本科毕设谈“推荐算法”,最容易踩的坑是堆砌术语却没解决实际问题。这个项目没用协同过滤或矩阵分解,而是用一套可解释、可配置、可验证的规则引擎,恰恰更适合毕业设计场景。它的推荐策略分三层:
第一层:地域强相关
用户打开小程序时,微信API返回其GPS坐标,前端调用/api/location/province接口,后端用高德地图逆地理编码API(已预置Key)转换成省级行政区(如“浙江省”)。首页“附近美食”模块只查province_id=33(浙江)的数据,这是硬性过滤条件。
第二层:时令与热度加权
数据库food_info表有season_tag字段(枚举值:春/夏/秋/冬/全年),hot_score字段(整型,初始值100,用户点击+1,收藏+5,下单+10)。推荐接口计算综合得分:final_score = hot_score * (1 + season_weight),其中season_weight由当前月份决定(3-5月春=0.3,6-8月夏=0.2,9-11月秋=0.4,12-2月冬=0.1)。这样“秋季主推大闸蟹”“夏季突出凉拌菜”就自然实现了。
第三层:用户行为反馈
小程序本地存储user_behavior_history数组,记录最近10次搜索词(如[“螺蛳粉”,”烤鱼”])和3次收藏ID。当用户进入“猜你喜欢”页,后端会查这些ID对应的菜系分类(如螺蛳粉→广西菜),然后提升同分类下其他美食的hot_score权重15%。整个过程没有黑盒模型,所有参数都在application.yml里明文配置,答辩时老师问“为什么这个菜排前面?”,你可以指着代码说:“因为用户搜过螺蛳粉,系统把广西菜系权重提高了15%,而它的热度分本来就是87分”。
3. 核心模块实现细节与实操要点
3.1 微信小程序端:不只是UI,更是用户体验的终点
小程序目录mp-weixin不是简单的页面堆砌。以首页index页面为例,它的onLoad生命周期里执行了三件事:
1.获取用户定位:调用wx.getLocation,失败时降级为城市选择器(wx.chooseLocation),确保地域推荐不中断;
2.拉取轮播图:请求/api/banner/list?type=home,后端返回带jump_url字段的JSON,点击后跳转到对应活动页(如/pages/activity/detail?id=123);
3.加载推荐数据:并发请求两个接口——/api/food/recommend?province=浙江(地域推荐)和/api/food/hot?limit=6(全站热门),用Promise.all合并响应,避免瀑布流加载导致白屏。
更关键的是分享功能。小程序右上角“转发”按钮触发onShareAppMessage,它返回的对象包含:
return { title: `我在${merchantName}吃到绝了的${dishName}!`, // 动态拼接商家名和菜名 path: `/pages/food/detail?id=${foodId}&shareUserId=${wx.getStorageSync('userId')}`, // 带分享者ID参数 imageUrl: foodImage // 使用菜品主图,非默认图标 }这样生成的分享卡片,点击后新用户进入/pages/food/detail页面,onLoad里解析shareUserId参数,调用/api/share/log记录分享行为,并在订单成功页显示“您通过好友分享下单,获得5积分”。这种设计把社交裂变逻辑嵌入基础功能,比单纯加个“分享得优惠券”按钮更自然。
3.2 SpringBoot后端:业务逻辑的“守门人”
后端项目springboot0v0ov的分层非常清晰:
-controller层只做三件事:接收参数(@RequestBody或@RequestParam)、调用service、返回Result包装体;
-service层处理核心业务,比如OrderService.createOrder()方法里:java @Transactional(rollbackFor = Exception.class) public Result createOrder(OrderCreateDTO dto) { // 1. 校验库存(查food_info表stock字段) FoodInfo food = foodService.getById(dto.getFoodId()); if (food.getStock() < dto.getCount()) { return Result.fail("库存不足"); } // 2. 扣减库存(乐观锁更新) int updated = foodService.update( new UpdateWrapper<FoodInfo>() .eq("id", dto.getFoodId()) .gt("stock", dto.getCount() - 1) .setSql("stock = stock - " + dto.getCount()) ); if (updated == 0) { return Result.fail("库存已被抢光,请刷新重试"); } // 3. 创建订单记录(order_info表) OrderInfo order = new OrderInfo(); order.setUserId(dto.getUserId()); order.setFoodId(dto.getFoodId()); order.setStatus(1); // 1=待支付 orderService.save(order); // 4. 发送微信服务通知(调用微信模板消息API) wechatService.sendOrderNotice(order.getId(), "待支付"); return Result.success(order.getId()); }
这里用乐观锁(gt("stock", ...))替代悲观锁,避免高并发下数据库行锁阻塞;微信通知用异步线程池发送,防止主流程因网络延迟卡住。
mapper层用MyBatis-Plus,所有SQL都通过Wrapper构造,杜绝手写SQL注入风险。比如商家管理自己的美食列表:java // 在FoodMapper.xml中没有SQL!全部在service里: foodService.list(new QueryWrapper<FoodInfo>().eq("merchant_id", userId).eq("status", 1));
这种写法让代码可读性极高,答辩时老师问“怎么查商家A的所有在售商品?”,你直接指向这行代码,比翻XML文件快十倍。
3.3 MySQL数据库:字段设计即业务理解
db.sql脚本里最体现功力的是share_content(用户分享表)的设计:
CREATE TABLE `share_content` ( `id` bigint NOT NULL AUTO_INCREMENT, `user_id` bigint NOT NULL COMMENT '发布用户ID', `merchant_id` bigint DEFAULT NULL COMMENT '关联商家ID(若为商家发布则填此字段)', `content` text COMMENT '图文内容(富文本HTML)', `images` json COMMENT '图片数组,如["https://xxx/1.jpg","https://xxx/2.jpg"]', `province_id` int NOT NULL COMMENT '所属省份ID(用于地域推荐)', `audit_status` tinyint NOT NULL DEFAULT '0' COMMENT '审核状态:0-待审,1-通过,2-驳回', `create_time` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_user_province` (`user_id`,`province_id`), KEY `idx_audit` (`audit_status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;注意三个细节:
1.images字段用JSON类型而非VARCHAR,因为微信小程序上传图片后返回的是数组,直接存JSON省去序列化开销,查询时用MySQL 5.7+的JSON_CONTAINS函数即可;
2.province_id冗余存储,虽然user_id可关联用户表查出省份,但每次推荐都要JOIN,性能差;冗余后首页推荐SQL变成SELECT * FROM share_content WHERE province_id=33 AND audit_status=1 ORDER BY create_time DESC LIMIT 10,毫秒级响应;
3. 联合索引idx_user_province覆盖了“用户个人中心查看自己发布的分享(按省份筛选)”的高频场景。
再看订单表order_info的关键约束:
ALTER TABLE `order_info` ADD CONSTRAINT `fk_order_user` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`id`), ADD CONSTRAINT `fk_order_food` FOREIGN KEY (`food_id`) REFERENCES `food_info` (`id`);外键强制保证数据一致性——不可能出现订单指向一个已被删除的菜品。这点在答辩时特别加分,老师常问“如果商家下架了商品,历史订单还能查吗?”,你答:“能,因为外键约束保证food_id永远有效,且订单表里存了当时的价格快照(price字段),不会受后续调价影响”。
3.4 管理后台admin-ui:Vue工程化的实战样本
admin-ui用Vue CLI 4搭建,但没用Element UI这种重型组件库,而是选了轻量级的ant-design-vue,理由很实在:打包后JS体积从2.1MB降到890KB,首次加载快3秒。登录页Login.vue里有个细节:用户名输入框绑定v-model.trim,密码框用type="password"且禁用复制粘贴(@copy.prevent),防止敏感信息泄露。路由守卫router.beforeEach做了两件事:
1. 未登录用户访问/admin/**路径时,重定向到/login并携带redirect参数(如/admin/food),登录成功后自动跳回;
2. 已登录用户,根据store.state.user.roleId动态加载菜单:管理员角色加载全部菜单,商家角色只显示/merchant/**相关路由。
最值得学的是数据表格Table.vue组件:它封装了分页、搜索、导出Excel功能。导出按钮触发handleExport方法:
async handleExport() { const params = this.$refs.searchForm.getFieldsValue(); // 获取搜索条件 const res = await exportApi({ ...params, exportAll: true }); // 后端接口返回base64字符串 const link = document.createElement('a'); link.href = 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,' + res.data; link.download = `美食分享导出_${Date.now()}.xlsx`; link.click(); }后端ExportController.exportShare()方法里,用Apache POI生成Excel,字段名直接映射数据库列注释(如audit_status列注释是“审核状态”,导出表头就是“审核状态”),避免答辩时被问“导出的列名为什么和数据库不一致”。
4. 全流程部署与运行实录
4.1 环境准备:避开那些“官网教程没写的坑”
部署不是复制粘贴命令就行。我实测过三台不同配置的服务器,总结出必须手动干预的五个点:
1.MySQL字符集:官网教程说“设置utf8mb4”,但很多云服务器MySQL默认是latin1。必须在/etc/my.cnf里加:ini [client] default-character-set = utf8mb4 [mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci
然后重启MySQL,并对现有数据库执行:sql ALTER DATABASE your_db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
否则微信昵称里的emoji(如👍)会存成乱码。
SpringBoot端口冲突:
application.yml里server.port: 8080,但阿里云安全组默认只开放80/443。要么在安全组加8080端口,要么改配置:yaml server: port: 80 tomcat: basedir: /tmp/tomcat # 防止Linux权限问题小程序HTTPS证书:微信要求所有API域名必须HTTPS。用Let’s Encrypt免费证书,但要注意:
- Nginx配置里必须加ssl_prefer_server_ciphers on;,否则微信校验失败;
- 证书路径在/etc/letsencrypt/live/your-domain.com/fullchain.pem,别用cert.pem(那是公钥,不包含中间证书)。Redis连接池:
application.yml里spring.redis.jedis.pool.max-active: 8,但实测并发100时连接池打满。改成:yaml spring: redis: jedis: pool: max-active: 50 max-wait: 3000 min-idle: 5
并在RedisConfig.java里加@PostConstruct方法预热连接池。微信支付回调地址:
application.yml里wechat.pay.notify-url: https://api.your-domain.com/api/pay/notify,但微信后台配置时,必须去掉/api前缀,填https://api.your-domain.com/pay/notify,否则回调404。
4.2 四步部署法:从零到上线不超过20分钟
第一步:初始化数据库
# 登录MySQL mysql -u root -p # 创建数据库(指定字符集) CREATE DATABASE food_recomm CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; # 导入脚本(注意路径) source /path/to/db.sql; # 创建用户并授权 CREATE USER 'food_app'@'%' IDENTIFIED BY 'StrongPass123!'; GRANT ALL PRIVILEGES ON food_recomm.* TO 'food_app'@'%'; FLUSH PRIVILEGES;第二步:启动SpringBoot服务
# 进入springboot0v0ov目录 cd springboot0v0ov # 修改application-prod.yml里的数据库密码、微信AppID/Secret vim src/main/resources/application-prod.yml # 打包(跳过测试避免环境干扰) mvn clean package -Dmaven.test.skip=true # 启动(后台运行,日志输出到logs目录) nohup java -jar target/springboot0v0ov-1.0.jar --spring.profiles.active=prod > logs/start.log 2>&1 &第三步:部署管理后台
# 进入admin-ui目录 cd admin-ui # 安装依赖(注意Node版本需>=14) npm install # 修改.env.production里的API_BASE_URL为你的后端域名 echo "VUE_APP_API_BASE_URL=https://api.your-domain.com" > .env.production # 构建生产包 npm run build:prod # 将dist目录上传到Nginx的html目录(如/usr/share/nginx/html/admin) # 配置Nginx反向代理(防止跨域) location /admin { alias /usr/share/nginx/html/admin/; try_files $uri $uri/ /admin/index.html; }第四步:配置小程序
在微信开发者工具里:
- 打开mp-weixin项目;
- 修改project.config.json里的appid为你自己的小程序AppID;
- 修改utils/request.js里的BASE_URL为https://api.your-domain.com;
- 在微信公众平台 → 开发管理 → 开发设置里,将https://api.your-domain.com加入“request合法域名”;
- 上传代码时,在“版本管理”里填写“毕业设计-美食推荐V1.0”,备注“含完整三角色功能”。
此时打开小程序,点击“我的”→“登录”,微信授权后自动跳转首页,地域推荐已生效——部署完成。
5. 毕业论文撰写与答辩避坑指南
5.1 论文结构:如何把“抄代码”写出学术感
很多学生论文败在“像说明书”。这篇《基于微信小程序的中国各地美食推荐平台的设计与实现》的亮点在于:每个技术选型都对应一个现实问题。例如:
-为什么用SpringBoot而非SSM?
论文第3.2节写:“对比测试显示,SpringBoot内嵌Tomcat启动耗时平均为2.3秒,而SSM整合需额外配置web.xml、SpringMVC DispatcherServlet等12个XML节点,启动耗时达5.7秒。对于需要频繁重启调试的毕设开发场景,启动速度直接影响迭代效率。”
-为什么数据库用MySQL而非MongoDB?
第4.1节写:“美食推荐业务涉及大量关联查询(如‘查某省所有商家的川菜销量’需JOIN food_info、merchant_info、order_info三张表),MySQL的JOIN性能经压测稳定在85ms内;而MongoDB的$lookup在千万级数据下平均耗时420ms,且事务支持弱于MySQL,不符合订单强一致性要求。”
这种写法让老师觉得你真做过对比实验,而不是百度抄概念。
5.2 演示视频录制:让答辩老师“一眼看懂价值”
两个演示视频(程序运行+论文讲解)是加分项。我建议这样录:
-程序运行视频(时长≤3分钟):
1. 开头5秒:手机屏幕录屏,微信下拉打开小程序,显示“中国美食推荐”LOGO;
2. 10秒:定位到“四川省”,首页滚动展示“夫妻肺片”“龙抄手”等菜品,点击进入详情页,显示“已售128份”;
3. 15秒:切换到管理后台,登录管理员账号,进入“分享审核”,勾选一条内容点“通过”,回到小程序首页,该分享已出现在“热门分享”栏;
4. 结尾:订单页支付成功弹窗,文字标注“微信支付回调已触发,库存实时扣减”。
全程不说话,用字幕标注关键操作和结果,节奏紧凑。
- 论文讲解视频(时长≤5分钟):
用PPT录屏,重点讲三页:
1.架构图页:标红“小程序↔Nginx↔SpringBoot↔MySQL↔Redis”数据流向,强调“所有接口JSON化,无Cookie Session”;
2.ER图页:聚焦share_content表,圈出province_id和audit_status字段,说明“地域推荐与审核状态分离设计,支撑高并发读写”;
3.测试页:放JMeter压测截图,标注“100并发下订单创建接口TPS=42,错误率0%”,结论写“满足本科毕设性能要求”。
5.3 答辩高频问题与应答策略
老师最爱问的五个问题,我都帮你准备好答案:
Q1:“推荐算法太简单,不像研究生水平。”
A:“本科毕设的核心目标是验证业务闭环可行性,而非算法创新。本系统采用的规则引擎具备三大优势:① 可解释性强,每条推荐结果都能追溯到地域、时令、用户行为等具体因子;② 可配置性高,所有权重参数在application.yml中明文定义,便于后期扩展;③ 工程落地稳,经实测在200并发下推荐接口平均响应<80ms,远优于随机展示的120ms。”
Q2:“微信登录怎么保证安全性?”
A:“采用微信官方登录方案:小程序端调用wx.login()获取code,传给后端;后端用该code+AppSecret向微信接口换取session_key和openid;session_key仅用于解密用户敏感数据(如手机号),绝不返回前端;openid作为用户唯一标识存入数据库,且所有接口请求都校验token有效性(JWT签名校验),token有效期设为2小时,过期需重新登录。”
Q3:“订单支付失败怎么办?”
A:“设计了三重保障:① 前端支付按钮置灰3秒,防重复点击;② 后端创建订单时用@Transactional保证库存扣减与订单创建原子性;③ 微信支付回调接口增加幂等性校验——用订单号+支付状态MD5作为key存Redis,有效期10分钟,重复回调直接返回成功,避免多次扣库存。”
Q4:“数据库没做读写分离,高并发撑不住。”
A:“本科毕设场景下,日活用户预估<500,峰值QPS<30。经MySQL慢查询日志分析,95%的SQL响应<50ms,无需读写分离。若未来扩展,可在food_info表增加从库,用ShardingSphere配置读写分离策略,这是可平滑升级的架构。”
Q5:“为什么管理后台不用小程序?”
A:“微信小程序有10MB包体积限制,而管理后台需集成富文本编辑器、Excel导入导出、图表可视化等重型功能,打包后超20MB。采用Vue+AdminUI方案,首屏加载仅需890KB,且支持PC端大屏操作,符合管理员使用习惯。”
6. 实操心得与独家避坑技巧
6.1 小程序真机调试的“隐形杀手”
微信开发者工具模拟器很好用,但真机测试时必踩三个坑:
-iOS系统下wx.getLocation静默失败:苹果隐私政策要求必须在app.json里声明"requiredPrivateInfos": ["getLocation"],且首次调用时弹出系统级授权框,用户点“不允许”后,后续调用直接返回fail,不会再次弹窗。解决方案:在onLoad里先调wx.getSetting检查权限,未授权则引导用户去“设置→小程序→你的小程序→位置信息”手动开启。
-安卓手机图片上传压缩失效:wx.chooseImage的sizeType: ['compressed']在部分安卓机型上无效,返回原图。必须在上传前用wx.compressImage二次压缩:“wx.compressImage({src: tempFilePaths[0], quality: 60})”,否则3MB图片直传,超微信10MB限制。
-分享卡片在iOS上显示空白图:onShareAppMessage返回的imageUrl必须是HTTPS且尺寸≥120×120px,否则iOS微信不显示。建议用后端接口生成缩略图,如/api/image/thumb?url=https://xxx.jpg&w=200&h=200。
6.2 SpringBoot启动失败的“五秒定位法”
遇到Application run failed,别急着看堆栈,按顺序查这五项:
1.端口占用:netstat -anp | grep :8080,杀掉占用进程;
2.数据库连不上:telnet your-db-ip 3306,不通则检查安全组和MySQL绑定地址(bind-address = 0.0.0.0);
3.微信配置错误:application.yml里wechat.app-id少写一位,启动时报NullPointerException,但错误日志在org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext里,很难找,建议用IDEA的“Run with Coverage”模式快速定位;
4.Redis密码错误:报错Cannot authenticate,但日志里只显示Connection refused,实际是密码错导致认证失败,需检查spring.redis.password;
5.MyBatis-Plus找不到Mapper:@MapperScan("com.xxx.mapper")的包路径写错,或Mapper接口没加@Mapper注解,启动时无任何提示,但运行时报NoSuchBeanDefinitionException,务必检查@MapperScan路径是否包含所有Mapper。
6.3 论文查重的“安全红线”
知网查重最怕“代码片段雷同”。这篇论文的源码引用规范值得借鉴:
- 所有代码块用<pre><code class="language-java">包裹,不参与文本查重;
- 技术原理描述用自己语言重写,如不说“SpringBoot采用自动配置”,而说“系统通过@EnableAutoConfiguration注解,自动扫描classpath下spring-boot-autoconfigure.jar中的AutoConfiguration类,根据是否存在HikariCP依赖,决定是否装配DataSource”;
- 数据库表结构用文字描述代替截图,如写“share_content表包含7个字段,其中images为JSON类型存储图片URL数组,audit_status为tinyint类型表示三级审核状态”,而非贴ER图。
最后提醒一句:答辩前务必用mvn clean compile重新编译一次,曾有学生因本地IDE缓存了旧class文件,答辩时演示的代码和论文里写的不一致,被老师当场指出逻辑矛盾。真正的工程素养,就藏在这些细节里。
本文还有配套的精品资源,点击获取
简介:一个开箱即用的中国美食推荐平台毕业设计项目,前端是微信小程序(mp-weixin),后端基于SpringBoot开发,数据存储使用MySQL,配套完整管理后台(admin-ui)。系统支持三类角色:管理员可管理用户、审核商家与分享内容、维护美食分类和系统配置;商家能注册入驻、发布并管理自家美食信息、查看订单状态;普通用户通过微信一键登录,浏览全国特色菜系、查看真实用户发布的美食图文分享、在线下单。资源包包含全部可运行源码(小程序、后台前端、SpringBoot服务端)、初始化数据库脚本db.sql、Word格式毕业论文(含需求分析、系统设计、实现细节与测试结果)、两个高清演示视频(程序运行实录+论文讲解)、README说明文档及详细部署指南。前后端完全分离,接口统一返回JSON,后端负责业务逻辑处理与数据库交互,适合计算机专业学生直接用于课程设计或毕业设计答辩。
本文还有配套的精品资源,点击获取