1. 项目概述:基于微信小程序的"今天吃什么"智能推荐系统
每次站在食堂窗口前犹豫不决,或是打开外卖APP刷了十分钟还做不了决定时,我就想:要是能有个系统帮我解决"今天吃什么"这个世纪难题该多好。这个毕业设计项目正是为了解决这个普遍存在的"选择困难症"痛点——通过微信小程序实现每日菜品的智能随机推荐。
作为一款轻量级但功能完整的应用,系统主要包含三大核心模块:
- 前端:基于微信小程序原生框架开发,确保良好的用户体验和跨平台兼容性
- 后端:采用Java+SpringBoot技术栈,提供稳定的API服务
- 算法层:实现基于权重和用户偏好的智能推荐逻辑
开发环境建议:JDK 1.8+、微信开发者工具最新版、IntelliJ IDEA 2022+、MySQL 5.7+。实测发现JDK 17存在与Lombok的兼容性问题,会报"you aren't using a compiler supported by lombok"警告。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计与技术选型
2.1 为什么选择微信小程序作为前端载体
微信小程序相比原生APP有三大不可替代的优势:
- 零安装成本:用户扫码即用,避免应用商店审核流程
- 开发效率高:一套代码适配iOS/Android,使用WXML+WXSS+JS技术栈
- 生态完善:支持云开发、支付、地图等丰富API
javascript复制// 小程序页面基础结构示例
Page({
data: {
dishes: [] // 推荐菜品列表
},
onLoad() {
this.getRecommendations()
},
getRecommendations() {
wx.request({
url: 'https://your-api.com/recommend',
success: (res) => {
this.setData({ dishes: res.data })
}
})
}
})
2.2 后端技术栈的深度考量
选择Java+SpringBoot组合主要基于:
- 企业级稳定性:SpringBoot的自动配置简化了SSM框架整合
- 性能需求:Java的线程模型适合高并发推荐请求
- 扩展性:方便集成Redis缓存、Elasticsearch搜索等组件
java复制// SpringBoot控制器示例
@RestController
@RequestMapping("/api")
public class RecommendController {
@Autowired
private DishService dishService;
@GetMapping("/recommend")
public List<Dish> getRecommendations(
@RequestParam(required = false) String userId) {
return dishService.recommendDishes(userId);
}
}
2.3 数据库设计关键表结构
核心表dish包含的字段设计:
sql复制CREATE TABLE `dish` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL COMMENT '菜品名称',
`category` varchar(20) NOT NULL COMMENT '分类(川菜/粤菜等)',
`calories` int(11) DEFAULT NULL COMMENT '卡路里',
`price` decimal(10,2) DEFAULT NULL,
`weight` int(11) DEFAULT '1' COMMENT '推荐权重',
`image_url` varchar(255) DEFAULT NULL,
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3. 核心算法实现与优化
3.1 基础随机推荐算法
最简单的实现是SQL直接随机查询:
sql复制SELECT * FROM dish ORDER BY RAND() LIMIT 1;
但这种方法在大数据量时性能极差(实测10万条记录耗时>2s)。
优化方案:预先计算权重区间
java复制// Java权重随机算法
public Dish randomRecommend() {
List<Dish> dishes = dishMapper.selectAll();
int totalWeight = dishes.stream().mapToInt(Dish::getWeight).sum();
int random = new Random().nextInt(totalWeight);
int sum = 0;
for (Dish dish : dishes) {
sum += dish.getWeight();
if (random < sum) return dish;
}
return dishes.get(0);
}
3.2 基于用户画像的智能推荐
建立用户偏好模型需要收集:
- 显式数据:用户主动收藏/评分的菜品
- 隐式数据:浏览时长、点击次数等
java复制// 协同过滤推荐示例
public List<Dish> recommendByCF(String userId) {
// 1. 找到相似用户
List<String> similarUsers = findSimilarUsers(userId);
// 2. 获取这些用户喜欢的菜品
Set<Dish> candidateDishes = new HashSet<>();
for (String similarUser : similarUsers) {
candidateDishes.addAll(getFavoriteDishes(similarUser));
}
// 3. 过滤已尝试过的菜品
candidateDishes.removeAll(getTriedDishes(userId));
return new ArrayList<>(candidateDishes);
}
3.3 冷启动问题的解决方案
新用户没有历史数据时,采用混合策略:
- 热门推荐:选择权重最高的前20%菜品
- 多样性保证:确保不同类别都有代表
- 随机试探:保留10%概率推荐新菜品
4. 微信小程序关键实现细节
4.1 页面布局与样式技巧
使用Flex布局实现响应式设计:
css复制/* 菜品卡片样式 */
.dish-card {
display: flex;
margin: 15rpx;
padding: 20rpx;
border-radius: 12rpx;
box-shadow: 0 4rpx 8rpx rgba(0,0,0,0.1);
}
.dish-image {
width: 200rpx;
height: 200rpx;
border-radius: 8rpx;
}
.dish-info {
flex: 1;
margin-left: 20rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
}
4.2 用户授权与登录流程
最佳实践是使用微信的开放能力:
javascript复制// 获取用户信息
wx.getSetting({
success(res) {
if (!res.authSetting['scope.userInfo']) {
wx.authorize({
scope: 'scope.userInfo',
success() {
wx.getUserInfo({
success: (res) => {
console.log(res.userInfo)
}
})
}
})
}
}
})
注意:2022年后微信调整了用户信息获取策略,必须使用
<button open-type="getUserInfo">引导用户主动点击。
4.3 性能优化实践
- 图片懒加载:
html复制<image lazy-load src="{{dish.imageUrl}}"></image> - 数据分页加载:
javascript复制onReachBottom() { this.loadMoreData() } - 本地缓存策略:
javascript复制wx.setStorageSync('lastRecommend', dish)
5. 开发中的典型问题与解决方案
5.1 微信开发者工具常见报错
问题1:initialize 11:37:00.523 [微信小程序开发者工具]连接异常
- 解决方案:检查网络代理设置,关闭Charles等抓包工具
问题2:onLoad(options)参数在真机为空
- 原因:页面跳转时未正确传递参数
- 修复:
javascript复制wx.navigateTo({ url: `/pages/detail?id=${id}` })
5.2 Java后端调试技巧
Lombok编译问题:
在IDEA中需要:
- 安装Lombok插件
- 开启注解处理:Settings → Build → Compiler → Annotation Processors
内存溢出处理:
遇到OutOfMemoryError时:
java复制// 增加JVM参数
-Xms512m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError
5.3 数据库优化记录
慢查询优化:
sql复制-- 原始语句(无索引时耗时1.2s)
SELECT * FROM dish WHERE category='川菜' ORDER BY RAND() LIMIT 1;
-- 优化方案
ALTER TABLE dish ADD INDEX idx_category (category);
-- 优化后耗时0.02s
6. 项目扩展方向
6.1 商家后台功能
基于CRMEB等开源模板快速搭建:
- 菜品管理(增删改查)
- 订单统计看板
- 用户反馈处理
6.2 虚拟支付集成
微信小程序虚拟支付流程:
- 申请支付权限
- 后端生成预支付订单
- 小程序端调起支付
- 处理支付结果通知
java复制// 支付回调处理
@PostMapping("/pay/notify")
public String payNotify(HttpServletRequest request) {
// 验证签名
// 更新订单状态
// 返回success防止微信重复通知
}
6.3 多端适配方案
使用Uni-app实现一套代码多端发布:
- 编译为微信小程序、H5、APP等
- 注意平台差异:
javascript复制// 环境判断 #ifdef MP-WEIXIN console.log('微信小程序环境') #endif
这个项目从技术选型到具体实现,每个环节都充满了工程决策的思考。在实际开发中,最大的收获不是功能的实现,而是学会如何平衡用户体验、开发效率和系统性能。比如在推荐算法上,从最初的简单随机到加入权重因素,再到引入用户画像,每一次迭代都让系统更智能一点。
