1. 项目背景与核心需求
"今天吃什么"这个困扰无数人的日常难题,正是我们这个微信小程序要解决的核心痛点。作为一个基于Java后端和微信小程序前端的美食随机推荐系统,它要解决的是用户在面临选择困难时的决策焦虑。
我去年接手这个毕业设计项目时,发现市面上已有的推荐系统大多存在两个问题:要么推荐过于随机缺乏逻辑,要么过于依赖历史数据导致推荐单一。我们的系统需要在两者间找到平衡点——既保证推荐的多样性,又能根据简单用户偏好进行适度个性化。
从技术架构看,这个系统包含三个关键部分:
- 微信小程序前端:负责用户交互和界面展示
- Java后端:处理推荐逻辑和数据管理
- 数据库:存储菜品信息和用户偏好
提示:选择微信小程序作为载体是因为其无需安装、即用即走的特性特别适合这种轻量级工具型应用,而Java后端的稳定性和成熟的生态体系能够支撑推荐算法的灵活实现。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计与技术选型
2.1 前端技术栈选择
微信小程序原生开发是我们的首选方案,相比uniapp等跨平台框架,原生开发能获得更好的性能和更少的兼容性问题。特别是在处理动画效果时——比如我们的"随机转盘"交互——原生组件的流畅度明显更优。
关键页面结构设计:
javascript复制// pages/index/index.js
Page({
data: {
foodList: [], // 推荐菜品列表
currentFood: null // 当前展示菜品
},
onLoad() {
this.loadFoodData()
},
// 获取推荐数据
loadFoodData() {
wx.request({
url: 'https://your-api-domain.com/api/recommend',
success: (res) => {
this.setData({ foodList: res.data })
}
})
}
})
2.2 后端技术方案
我们采用Spring Boot作为后端框架,主要考虑因素包括:
- 快速开发:适合毕业设计的时间限制
- 内嵌Tomcat:简化部署流程
- 丰富的starter:轻松集成Redis、MySQL等组件
推荐算法的核心实现逻辑:
java复制// FoodRecommendService.java
public List<Food> recommendFood(String userId) {
// 1. 获取用户偏好(如果有)
UserPreference preference = preferenceRepository.findByUserId(userId);
// 2. 基础推荐逻辑
List<Food> allFoods = foodRepository.findAll();
// 3. 简单加权随机算法
return allFoods.stream()
.sorted((a,b) -> {
double random = Math.random();
// 简单示例:给偏好类别更高权重
if(preference != null && a.getCategory().equals(preference.getFavoriteCategory())) {
random *= 2;
}
return Double.compare(random, 0.5);
})
.limit(3)
.collect(Collectors.toList());
}
2.3 数据存储方案
考虑到毕业设计的规模,我们使用MySQL作为主数据库,Redis用于缓存热门推荐。数据库表设计遵循第三范式,主要包含:
- 菜品表(food):id, name, category, ingredients, calories, image_url
- 用户表(user):openid, nickname, avatar
- 用户偏好表(user_preference):user_id, favorite_category, avoid_ingredients
3. 核心功能实现细节
3.1 随机推荐算法优化
最初的纯随机算法虽然实现简单,但用户体验很差——可能出现连续推荐同类菜品的情况。我们通过以下改进提升了推荐质量:
- 类别分布控制:确保连续3次推荐不出现同类别菜品
- 时间权重:早餐/午餐/晚餐时段推荐相应类型的菜品
- 简单个性化:根据用户历史点击记录轻微调整各类别概率
算法优化后的伪代码:
code复制function recommend():
current_time = get_current_time()
time_category = determine_meal_time(current_time)
available_foods = filter_by_time_category(foods, time_category)
if user_has_preferences():
adjust_probabilities_based_on_preferences(available_foods)
selected = []
while len(selected) < 3:
candidate = weighted_random_select(available_foods)
if not violates_diversity_rules(candidate, selected):
selected.append(candidate)
return selected
3.2 微信小程序交互设计
为了让随机推荐过程更有趣味性,我们设计了转盘动画效果。关键实现点:
- 使用CSS动画实现平滑的旋转效果
- 通过wx.createAnimation API控制动画细节
- 在动画结束时触发推荐结果展示
示例代码:
javascript复制// 旋转动画实现
startRotation() {
const animation = wx.createAnimation({
duration: 2000,
timingFunction: 'ease-out'
})
this.animation = animation
animation.rotate(360 * 5).step()
this.setData({
animationData: animation.export()
})
// 动画结束后显示结果
setTimeout(() => {
this.showRecommendResult()
}, 2000)
}
3.3 后端API设计
RESTful API设计遵循以下原则:
- 资源导向:/api/foods, /api/recommendations
- 合理使用HTTP方法:GET获取,POST创建
- 标准化响应格式
主要API端点示例:
code复制GET /api/recommend
参数: userId (可选)
响应:
{
"code": 200,
"data": [
{ "id": 1, "name": "宫保鸡丁", "category": "川菜" },
...
]
}
POST /api/feedback
参数:
{
"userId": "xxx",
"foodId": 1,
"isLike": true
}
响应:
{
"code": 200,
"message": "反馈成功"
}
4. 开发中的关键问题与解决方案
4.1 微信小程序用户标识问题
微信小程序获取用户唯一标识需要通过wx.login获取code,再向开发者服务器交换openid。常见问题包括:
- code过期:code5分钟有效,需要及时处理
- 敏感数据加密:用户手机号等敏感信息需要解密
- 会话管理:需要维护服务器端会话状态
解决方案流程:
code复制小程序端:
wx.login() → 获取code → 发送到服务器
服务器端:
使用code + appid + secret → 向微信接口服务请求
→ 获取openid和session_key
→ 生成自定义登录态(token)返回小程序
后续请求:
小程序携带token → 服务器验证 → 获取用户数据
4.2 推荐结果缓存策略
频繁访问数据库获取推荐结果会影响性能,我们采用二级缓存:
- 本地缓存:小程序端缓存最近推荐结果,减少网络请求
- Redis缓存:服务器端缓存热门推荐和通用推荐
- 缓存失效策略:定时刷新+事件驱动刷新
缓存实现关键代码:
java复制@Cacheable(value = "recommendations", key = "#userId")
public List<Food> getRecommendations(String userId) {
// 数据库查询逻辑
}
// 定时刷新缓存
@Scheduled(fixedRate = 3600000) // 每小时
public void refreshPopularFoodsCache() {
// 刷新逻辑
}
4.3 跨平台兼容性问题
不同手机型号上小程序的表现差异很大,特别是:
- 三星手机video层级问题:video组件总是最上层,会遮挡弹出层
- textarea布局问题:影响父元素margin
- iOS/Android动画性能差异
解决方案:
- 对于video层级问题:使用cover-view替代普通view
- textarea问题:改用padding代替margin
- 动画性能:针对不同平台调整动画参数
5. 项目扩展与优化方向
5.1 个性化推荐增强
当前系统只实现了基础偏好记录,可以考虑:
- 协同过滤:基于相似用户喜好推荐
- 内容分析:分析菜品成分、口味等特征
- 深度学习:使用神经网络建模用户偏好
5.2 社交功能集成
增加社交元素提升用户粘性:
- 分享功能:分享今日推荐到朋友圈
- 好友PK:和朋友一起玩"今天吃什么"
- 社区点评:对推荐菜品进行评价
5.3 商业化可能性
作为毕业设计可能不需要,但实际产品可考虑:
- 商家合作:推荐附近餐厅的对应菜品
- 食材电商:一键购买菜品所需食材
- 会员服务:提供更精准的个性化推荐
在开发这个项目的过程中,我发现最难的不是技术实现,而是在简单随机和过度个性化之间找到平衡点。最终我们采用了一个可调节的权重系统,允许用户通过简单的"喜欢/不喜欢"反馈来微调推荐策略,既不会让用户感到被算法控制,又能逐步改善推荐质量
