SpringBoot+微信小程序+AI智能外卖推荐系统设计与实现全解析
发布时间:2026/9/2 19:52:29 作者:尧图编辑部 阅读量:1,286

很多同学看到“基于SpringBoot微信小程序AI的智能外卖点餐推荐系统”这种题目时第一反应通常是这不就是把外卖系统的增删改查套了个壳吗如果你也这样想那很可能低估了这个课题的价值也容易在答辩时被老师问住。一个真正能拿高分的毕设绝不是靠堆砌“SpringBoot 小程序 AI”三个热门词而是要回答清楚一个问题AI到底在这个系统里解决了什么业务问题推荐逻辑在哪里体现你的系统相比普通的外卖点餐系统增量在哪里这篇文章不会只帮你把项目跑起来而是把整个系统的设计思路、技术选型、核心代码、推荐算法落地、小程序联调以及答辩时最容易被追问的技术点一次讲透。你读完应该能达到三个效果第一能独立把这个项目从零搭起来并跑通第二能说清楚每个模块为什么这么设计第三面对老师关于“AI在哪里”的提问你能给出有深度的回答。1. 为什么“智能外卖点餐推荐系统”值得做先下一个判断外卖点餐系统是后端开发中业务闭环最完整、最适合做毕设的选题之一加上推荐的AI能力后它的技术含量立刻和普通CRUD项目拉开了档次。你可以对比一下两个毕设题目的差异。如果题目是“基于SpringBoot的外卖点餐系统”那么核心工作就是用户管理、商家管理、菜品管理、订单管理、购物车确实偏业务流。但加上“AI推荐”后系统必须回答几个新问题用户打开小程序首页展示哪些菜品依据是什么新用户没有任何行为记录时怎么给他推荐用户浏览、加购、下单后推荐列表如何动态调整推荐结果如何用大模型生成个性化描述而不是单纯的数据库查询这些问题任何一个展开都能变成一个很好的毕业设计亮点。更关键的是这个题目覆盖了当前企业级Java开发的主流技术栈SpringBoot做后端、MyBatis-Plus操作数据库、微信小程序做C端、AI大模型接口做智能增强。一套项目下来简历上能写的内容非常充实。什么样的读者最适合参考这个项目如果你正在准备计算机、软件工程相关专业的毕业设计后端方向为主又希望项目里带一些算法和AI元素那么这篇文章的匹配度非常高。即使你只是想在简历里增加一个完整的全栈项目这个选题也值得做。2. 系统整体架构与核心业务流程2.1 系统角色划分智能外卖点餐推荐系统的用户角色分为三类普通用户、商家管理员、系统管理员。普通用户通过微信小程序完成登录、浏览菜品、查看推荐、加入购物车、下单支付、订单查询、评价等操作。商家管理员在管理后台维护菜品信息、库存和订单状态。系统管理员负责用户管理、商家审核、数据统计等平台级功能。从权限设计来看小程序端是C端用户入口管理后台是B端运营入口两者不共用一套页面但在后端共享同一套用户体系和鉴权机制。2.2 核心业务流程整个系统的核心链路是用户微信授权登录 - 小程序首页请求推荐接口 - 后端获取用户特征 - 推荐引擎计算菜品列表 - 叠加AI个性化描述 - 返回小程序渲染 - 用户加购下单 - 订单状态流转 - 商家接单处理这个链路里有两个关键设计点。第一推荐不是一次性计算而是分层的用户进入首页时触发一次推荐搜索时触发关键词推荐查看菜品详情时触发“相似菜品推荐”。第二AI不是替代推荐算法而是在推荐结果之上做增强比如生成推荐理由、口味标签、搭配建议这样既保证推荐质量可控又让系统体现“智能化”。2.3 技术架构分层系统采用前后端分离架构小程序端和后端通过RESTful API通信管理后台采用Vue或Thymeleaf模板引擎后端整体采用经典分层结构。controller接口层 | service业务层 | |--- 推荐服务基于用户行为 协同过滤 |--- AI服务调用大模型接口做文案增强 | dao数据访问层MyBatis-Plus | databaseMySQL这种分层的价值在毕设答辩时特别容易讲清楚每一层只负责自己的职责推荐逻辑被封装在独立的service中不会污染订单和菜品模块的代码。如果以后想替换推荐算法只需要修改推荐服务实现类其他模块完全不受影响。3. 数据库表结构设计数据库设计是一个毕设项目的骨架。智能外卖点餐系统的核心表包括用户表、商家表、菜品表、分类表、购物车表、订单表、订单明细表、地址表、评价表、用户行为表。3.1 核心表结构说明用户表user保存微信用户的openId、昵称、头像、手机号、性别等基础信息。openId是微信生态下用户的唯一标识设计时必须加唯一索引否则同一用户反复登录会产生多条脏数据。菜品表dish是推荐系统的核心数据源字段包括菜品名称、图片、价格、分类ID、商家ID、月销量、评分、库存、状态。其中月销量和评分是后续推荐算法的重要特征也是冷启动时兜底推荐的主要依据。订单表orders和订单明细表order_detail是典型的父子表关系一个订单对应多条明细。设计时要注意用订单号作为业务主键在支付回调、对账等场景下使用自增主键只作为内部标识。用户行为表user_behavior是推荐系统的关键记录的字段包括用户ID、菜品ID、行为类型浏览、加购、下单、收藏、行为时间。这张表会持续增长建议以用户ID做分表设计并在行为时间上建立索引。3.2 建表SQL示例-- 菜品表 CREATE TABLE dish ( id bigint(20) NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL COMMENT 菜品名称, image varchar(500) DEFAULT NULL COMMENT 菜品图片, price decimal(10,2) NOT NULL COMMENT 价格, category_id bigint(20) DEFAULT NULL COMMENT 分类ID, merchant_id bigint(20) DEFAULT NULL COMMENT 商家ID, month_sales int(11) DEFAULT 0 COMMENT 月销量, rating decimal(3,2) DEFAULT 5.00 COMMENT 评分, status tinyint(4) DEFAULT 1 COMMENT 状态 1上架 0下架, create_time datetime DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_category (category_id), KEY idx_merchant (merchant_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT菜品表; -- 用户行为表 CREATE TABLE user_behavior ( id bigint(20) NOT NULL AUTO_INCREMENT, user_id bigint(20) NOT NULL COMMENT 用户ID, dish_id bigint(20) NOT NULL COMMENT 菜品ID, behavior_type tinyint(4) NOT NULL COMMENT 行为类型 1浏览 2加购 3下单 4收藏, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_user_time (user_id, create_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户行为表;4. SpringBoot后端核心模块实现4.1 项目初始化与依赖配置后端项目使用SpringBoot 2.7.x作为基础框架搭配MyBatis-Plus 3.5.x、MySQL 8.0、Redis可选、Swagger接口文档、Lombok简化开发。dependencies !-- SpringBoot Web -- 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/version /dependency !-- MySQL -- dependency groupIdcom.mysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency !-- Lombok -- dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency /dependencies配置文件中需要特别注意的是数据库连接配置和MyBatis-Plus的日志配置前者关系到项目能否启动后者关系到你是否能方便地查看SQL执行情况。server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/smart_order?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: your_password mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl map-underscore-to-camel-case: true global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 04.2 微信登录接口实现微信小程序登录的核心流程是小程序端调用wx.login获取临时code将code发送到后端后端通过code向微信接口换取openId和session_key然后生成自定义登录态token返回给小程序。// 文件路径src/main/java/com/example/smartorder/controller/AuthController.java RestController RequestMapping(/api/auth) public class AuthController { Autowired private UserService userService; PostMapping(/wx-login) public ResultString wxLogin(RequestBody WxLoginRequest request) { // 1. 使用code调用微信接口获取openId String openId userService.getOpenIdByCode(request.getCode()); // 2. 根据openId查找用户不存在则自动注册 User user userService.findOrCreateUser(openId); // 3. 生成登录token并返回 String token JwtUtil.generateToken(user.getId()); return Result.success(token); } }这里有一个非常常见的坑点如果后端没有正确配置微信小程序的AppId和AppSecret或者请求微信接口时网络不通前端就会提示“获取登录后的微信用户失败”。排查时优先检查后端日志中微信接口返回的errcode常见的40029表示code无效40163表示code已被使用过需要重新调用wx.login。4.3 菜品推荐接口实现推荐接口是整个系统的核心也是毕业设计答辩时老师最关注的部分。推荐策略采用多路召回、统一排序的思路先通过不同策略召回候选菜品再根据规则或模型打分排序最后返回TopN。// 文件路径src/main/java/com/example/smartorder/service/impl/RecommendServiceImpl.java Service public class RecommendServiceImpl implements RecommendService { Autowired private DishMapper dishMapper; Autowired private UserBehaviorMapper behaviorMapper; Autowired private AiService aiService; Override public ListDishVO recommendForUser(Long userId, int size) { // 1. 判断用户是否有行为记录 int behaviorCount behaviorMapper.countByUserId(userId); ListDish candidateDishes; if (behaviorCount 0) { // 2. 冷启动基于热门菜品兜底推荐 candidateDishes dishMapper.selectHotDishes(size); } else { // 3. 有行为数据基于协同过滤思想召回候选菜品 // 先找到相似用户再推荐相似用户喜欢的菜品 ListLong similarUserIds behaviorMapper.findSimilarUserIds(userId); candidateDishes dishMapper.selectDishesByUserPreferences(similarUserIds, size); } // 4. AI生成个性化推荐理由 ListDishVO result new ArrayList(); for (Dish dish : candidateDishes) { DishVO vo DishVO.fromEntity(dish); vo.setRecommendReason(aiService.generateRecommendReason(userId, dish)); result.add(vo); } return result; } }这个实现里有一个设计亮点推荐模块可以自由切换策略。冷启动时使用热门排行榜有行为数据时使用基于物品的协同过滤后期还可以接入基于内容的推荐或向量召回。这种可扩展的架构在答辩时很加分。4.4 协同过滤推荐算法具体实现协同过滤是推荐系统最经典的算法核心思想是“物以类聚人以群分”。在毕业设计场景下不需要实现完整的矩阵分解使用基于物品的协同过滤即可达到演示效果。基于物品的协同过滤分三步走第一步构建用户-菜品交互矩阵。第二步计算菜品之间的相似度常用公式是余弦相似度。第三步根据用户历史喜欢的菜品找出相似度最高的TopN菜品进行推荐。// 文件路径src/main/java/com/example/smartorder/recommend/ItemCFRecommender.java Component public class ItemCFRecommender { /** * 计算两个菜品之间的余弦相似度 */ public double cosineSimilarity(MapLong, Integer userScoresForDishA, MapLong, Integer userScoresForDishB) { SetLong commonUsers new HashSet(userScoresForDishA.keySet()); commonUsers.retainAll(userScoresForDishB.keySet()); if (commonUsers.isEmpty()) { return 0.0; } double dotProduct 0.0; double normA 0.0; double normB 0.0; for (Long userId : commonUsers) { int scoreA userScoresForDishA.get(userId); int scoreB userScoresForDishB.get(userId); dotProduct scoreA * scoreB; } for (Integer score : userScoresForDishA.values()) { normA score * score; } for (Integer score : userScoresForDishB.values()) { normB score * score; } if (normA 0 || normB 0) { return 0.0; } return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB)); } }在真实项目中菜品相似度可以离线计算并缓存到Redis中用户请求推荐时直接读取不必每次实时计算。但在毕业设计中如果数据量不大实时计算完全够用还能展示你对算法的理解。5. AI大模型接入与智能推荐增强5.1 大模型在系统中的定位现在回答一个最关键的问题大模型在这个系统里到底做什么很多毕设项目只是把大模型接口当作聊天机器人接入和业务毫无关联答辩时很容易被质疑。这个项目的正确做法是让AI成为推荐链路中的“文案增强器”和“语义理解器”。具体来说AI大模型承担三个职责第一推荐理由生成。用户看到“为您推荐黄焖鸡米饭”和“为您推荐黄焖鸡米饭因为您最近浏览过川湘菜这道菜口味接近且评分高达4.8分”后者的体验明显更好。前者是推荐算法算出来的后者是AI根据推荐结果生成的。第二搜索意图理解。用户输入“辣一点的”“适合下雨天吃的”“低卡的”这些口语化、非结构化的搜索词传统SQL很难处理但大模型可以将自然语言转换为结构化的查询条件或标签集合。第三菜品描述生成。商家上传菜品时只需填写基础信息AI自动生成诱人的菜品描述和推荐标签。5.2 大模型接口接入示例后端接入大模型一般通过HTTP接口调用这里以OpenAI兼容格式为例实际项目由于网络环境原因你需要根据自己可访问的模型服务地址进行调整。// 文件路径src/main/java/com/example/smartorder/service/impl/AiServiceImpl.java Service public class AiServiceImpl implements AiService { Value(${ai.api-url}) private String apiUrl; Value(${ai.api-key}) private String apiKey; Value(${ai.model}) private String model; Override public String generateRecommendReason(Long userId, Dish dish) { // 构建提示词 String prompt String.format( 你是一个美食推荐助手。用户最近浏览过川湘菜、烧烤类菜品 请为菜品【%s】生成一句20字以内的推荐理由要求口语化、有吸引力不要提及AI。, dish.getName() ); // 调用大模型接口 String result callLlm(prompt); // 如果调用失败返回兜底文案 if (result null || result.isEmpty()) { return String.format(月售%s份好评率%s%%, dish.getMonthSales(), dish.getRating().multiply(BigDecimal.valueOf(20))); } return result; } }大模型接入有一个很重要的工程原则必须设计兜底逻辑。AI接口可能出现超时、限流、返回格式异常等问题不能因为AI挂了整个推荐接口就报错。生成推荐理由失败时就回退到销量和评分组成的模板文案保证主流程的稳定性。另外需要配置AI接口的参数放在application.yml中便于统一管理ai: api-url: https://your-llm-service.example.com/v1/chat/completions api-key: your-api-key model: your-model-name timeout: 50005.3 Prompt设计的实际技巧接入大模型后你会发现真正影响效果的不是模型本身而是Prompt怎么写。推荐理由生成这个场景比较好的Prompt模板是你是一个本地生活美食推荐助手。 背景用户最近浏览过以下菜品[麻辣香锅、烤鱼、小龙虾]。 任务为菜品【毛血旺】生成推荐理由。 要求 1. 30字以内口语化像朋友推荐一样自然。 2. 结合用户最近的浏览偏好解释推荐原因。 3. 不要出现“根据您的浏览记录”“AI推荐”等字样。 4. 如果无法生成只回复“这道菜非常受欢迎”即可。6. 微信小程序端实现6.1 项目结构与页面设计微信小程序端使用原生框架或uni-app开发。如果使用原生项目结构包括pages、components、utils、api四个目录。页面主要包括首页、菜品分类页、购物车页、订单页、我的页面。首页是推荐功能的主要展示位置设计上建议使用“轮播图 推荐菜品瀑布流”的结构。推荐区域上方加一行说明文案比如“智能推荐 · 根据您的口味定制”让用户和评委都能直观感知到推荐功能的存在。6.2 小程序登录与请求封装小程序的request请求需要封装成一个公共模块统一处理token携带、错误提示、状态码判断。// 文件路径miniprogram/utils/request.js const BASE_URL http://localhost:8080; function request(url, method, data) { return new Promise((resolve, reject) { const token wx.getStorageSync(token); wx.request({ url: BASE_URL url, method: method || GET, data: data || {}, header: { Content-Type: application/json, Authorization: token ? Bearer token : }, success: (res) { if (res.data.code 200) { resolve(res.data.data); } else if (res.data.code 401) { wx.navigateTo({ url: /pages/login/login }); } else { wx.showToast({ title: res.data.msg || 请求失败, icon: none }); } }, fail: (err) { wx.showToast({ title: 网络异常请稍后重试, icon: none }); reject(err); } }); }); } module.exports { request };在开发者工具中进行本地调试时有一个容易卡住的地方默认情况下小程序不允许请求http接口必须在“详情 - 本地设置”中勾选“不校验合法域名、web-view业务域名、TLS版本以及HTTPS证书”。如果发布正式版本或真机预览则需要在微信公众平台配置合法域名而且必须是HTTPS。6.3 推荐列表渲染获取推荐菜品列表后小程序端通过wx:for循环渲染。需要注意图片懒加载和加载状态的处理避免弱网环境下页面白屏。!-- 文件路径miniprogram/pages/index/index.wxml -- view classrecommend-section view classsection-title text智能推荐/text text classsubtitle根据你的口味定制/text /view view classdish-grid view classdish-card wx:for{{recommendList}} wx:keyid bindtaphandleDishTap >mvn spring-boot:run或者使用IDE直接运行主启动类。启动成功后控制台会看到SpringBoot的启动日志访问http://localhost:8080/swagger-ui.html可以查看接口文档。第四步打开微信开发者工具导入小程序项目目录修改utils/request.js中的BASE_URL为本机IP加端口。这里要注意如果使用真机调试不能填localhost要填电脑在局域网中的IP地址。7.2 项目部署到服务器如果毕业设计需要演示远程访问可以将后端打包成Jar包部署到云服务器。# 打包 mvn clean package -DskipTests # 部署到服务器 scp target/smart-order-1.0.0.jar rootyour-server:/opt/app/ # 启动 java -jar /opt/app/smart-order-1.0.0.jar --spring.profiles.activeprod生产环境部署时建议使用nohup或systemd管理进程避免SSH断开后进程退出。8. 常见问题与排查思路8.1 问题排查表问题现象可能原因排查方式解决方案小程序请求后端失败开发者工具未关闭域名校验查看工具控制台错误提示详情 - 本地设置 - 勾选不校验合法域名登录报错“获取登录后的微信用户失败”AppId和AppSecret配置错误查看后端日志中微信接口返回的errcode检查application.yml配置或重新获取code后端启动报错数据库连接失败MySQL未启动或账号密码错误查看启动日志的Caused by信息确认MySQL服务状态和配置文件推荐列表为空菜品表中没有上架状态的菜品查询数据库dish表数据在管理后台添加上架菜品AI推荐理由不生效大模型接口超时或返回异常查看AiService日志检查ai.api-url配置确认兜底文案生效订单支付成功后库存未扣减事务未生效检查Service层是否添加Transactional在扣减库存方法上添加事务注解8.2 “小程序获取登录后的微信用户失败”深度排查这个话题在开发者社区检索量很高如果你的项目也遇到这个问题按照下面的顺序排查成功率最高。第一确认code是新的。wx.login获取的code只能使用一次如果前端重复发送同一个code后端第二次调用微信接口时必然报错。检查前端代码中登录逻辑是否在每次点击时都重新调用wx.login。第二确认AppSecret正确。在微信公众平台重置AppSecret后旧Secret立即失效。如果项目代码中硬编码了旧的Secret排查时很难发现建议将AppSecret放到后端配置文件中。第三确认网络环境能访问微信接口。如果后端部署在服务器上需要确认目标地域能正常访问微信的API域名否则请求会超时。如果部署在本地确保开发机网络正常。9. 最佳实践与毕业设计答辩建议9.1 项目代码规范后端代码建议统一使用Result 作为接口返回值包含code、msg、data三个字段。这样做的原因是前端可以根据code统一处理业务异常而不是依赖HTTP状态码。比如登录过期返回401业务失败返回500成功返回200。数据库表设计时统一使用create_time和update_time字段MyBatis-Plus提供了自动填充功能避免在业务代码中手动维护时间字段减少重复代码。9.2 推荐系统的扩展方向如果你的毕业设计想要冲击优秀论文可以在现有基础上增加一个离线推荐计算模块使用定时任务在每天凌晨计算菜品相似度矩阵并存入Redis用户请求时直接读取缓存结果。这会让推荐接口的响应时间从几百毫秒下降到几十毫秒而且更贴近真实工业界的推荐系统架构。还可以考虑引入更丰富的用户特征比如地理位置、价格偏好、口味偏好通过给菜品打标签实现基于内容的推荐与大模型结合做标签提取。9.3 答辩时如何讲清楚“AI在哪里”这是最重要的一个建议。答辩时老师几乎一定会问“你的AI体现在哪里”很多同学的回答是“我接入了大模型接口”这个答案太单薄。更好的回答方式是先讲推荐链路说明冷启动阶段如何用热门策略兜底有行为数据后如何用协同过滤计算相似度再讲AI的定位说明大模型在推荐结果之上做自然语言理解、推荐理由生成、搜索意图解析最后强调AI和推荐算法的分工推荐算法负责“选什么菜”大模型负责“为什么推荐这道菜给你”。这样一个回答下来既展示了算法基础又展示了工程能力还能体现产品思维。另外演示时一定要准备一个“新用户”账号。用新账号登录时首页展示热门推荐然后你手动浏览几个川菜类菜品再刷新推荐列表列表会发生变化。这个前后对比的演示效果比任何口头解释都有说服力。10. 总结智能外卖点餐推荐系统这个题目真正的难点不在于SpringBoot的CRUD也不在于微信小程序的页面开发而在于如何把推荐算法和AI能力自然地嵌入到完整的业务链路中。把推荐分层设计、让AI做文案增强、用冷启动策略解决新用户问题这三个点做到了你的项目就能和普通的外卖管理系统拉开明显差距。下一步建议你先跑通基础流程再逐步加入协同过滤的相似度计算逻辑最后接入大模型接口。每完成一个阶段都用真实数据验证推荐效果。这样项目做完后你对推荐系统的理解会远超“会用框架”的层面答辩时自然更有底气。