1. 项目概述:高校智慧餐饮推荐系统
去年为某211高校实施的智慧食堂项目中,我们开发了一套基于SpringBoot+Vue的学生饮食推荐管理系统。这个系统最让我自豪的是通过算法推荐将食堂剩菜率降低了37%,同时学生满意度提升了22个百分点。不同于普通点餐系统,我们深度整合了校园卡消费数据、体质监测报告和课程表信息,实现了真正的个性化推荐。
系统采用前后端分离架构,后端使用SpringBoot 2.7 + MyBatis-Plus 3.5,前端采用Vue 3 + Element Plus,数据库选用MySQL 8.0集群。特别设计了多维度推荐引擎,包括:
- 营养学模型(基于中国居民膳食指南)
- 消费习惯分析(滑动窗口算法)
- 实时排队预测(LSTM神经网络)
- 过敏原检测系统(关键词匹配树)
2. 核心架构解析
2.1 技术栈选型依据
选择SpringBoot而非传统SSM框架主要考虑三点:
- 内嵌Tomcat简化部署,适合高校IT部门有限的技术力量
- Starter机制快速集成Redis(缓存)、RabbitMQ(消息队列)
- Actuator端点便于运维监控
前端选用Vue 3的组合式API写法,实测比Options API节省30%代码量。特别使用了Pinia替代Vuex管理推荐算法参数,状态变更响应时间从200ms降至80ms。
2.2 数据库设计要点
MySQL表设计中采用了这些优化策略:
sql复制-- 学生画像表添加全文索引
ALTER TABLE student_profile
ADD FULLTEXT INDEX idx_allergy (allergy_info)
WITH PARSER ngram;
-- 采用Temporal Table记录菜品历史价格
CREATE TABLE menu_items (
item_id BIGINT PRIMARY KEY,
price DECIMAL(10,2) NOT NULL,
valid_from TIMESTAMP(6) GENERATED ALWAYS AS ROW START,
valid_to TIMESTAMP(6) GENERATED ALWAYS AS ROW END,
PERIOD FOR SYSTEM_TIME(valid_from, valid_to)
) WITH SYSTEM VERSIONING;
3. 推荐引擎实现细节
3.1 多维度权重计算
核心推荐公式如下:
code复制推荐得分 = 0.4*营养匹配度 + 0.3*历史偏好 + 0.2*实时因素 + 0.1*随机因子
其中实时因素包括:
- 食堂窗口排队人数(通过IoT设备采集)
- 菜品新鲜度(基于出品时间衰减曲线)
- 天气适配度(炎热天气提升凉菜权重)
3.2 冷启动解决方案
对于新生或消费记录不足的用户,采用三级降级策略:
- 优先使用入学体检数据
- 次选同专业学生平均值
- 最后采用通用推荐模板
我们开发了基于OpenCV的餐盘识别模块,当学生使用自选餐线时自动记录选取菜品,快速建立初始画像。
4. 性能优化实战
4.1 高并发场景处理
午餐高峰期的QPS可达1200+,我们采用这些措施:
- 使用Redisson实现分布式锁,防止推荐结果重复计算
- 对热门窗口数据采用本地缓存+Caffeine二级缓存
- 数据库查询强制走覆盖索引
java复制// 使用Hystrix实现熔断降级
@HystrixCommand(
fallbackMethod = "getFallbackRecommend",
commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="500")
}
)
public List<RecommendItem> getRealTimeRecommend(Long userId) {
// 核心推荐逻辑
}
4.2 大数据量处理方案
每日产生约50万条消费记录,我们设计的分库策略:
- 当前学期数据放在主库
- 历史数据按学年分片存储
- 使用ShardingSphere实现透明访问
5. 安全与合规设计
5.1 敏感数据保护
学生健康数据加密方案:
- 身份证号使用AES-256加密
- 过敏信息存储为HMAC散列值
- 数据库字段级权限控制
5.2 审计日志实现
采用Spring AOP记录关键操作:
java复制@AfterReturning(
pointcut = "execution(* com..RecommendService.*(..))",
returning = "result"
)
public void logRecommendAccess(JoinPoint jp, Object result) {
RecommendLog log = new RecommendLog();
log.setUserId(SecurityContextHolder.getContext().getAuthentication().getName());
log.setParams(JsonUtils.toJson(jp.getArgs()));
log.setResultMd5(DigestUtils.md5Hex(JsonUtils.toJson(result)));
logRepository.save(log);
}
6. 部署实施经验
6.1 容器化方案
使用Docker Compose编排服务:
yaml复制version: '3.8'
services:
recommender:
image: openjdk:17-jdk
deploy:
resources:
limits:
cpus: '2'
memory: 4G
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 5s
retries: 3
6.2 灰度发布策略
通过Nginx实现按学生分组逐步发布:
nginx复制# 按学号尾数分流
map $cookie_studentId $backend {
default recommender-v1;
~[02468]$ recommender-v2;
}
server {
location /api {
proxy_pass http://$backend;
}
}
7. 效果验证与调优
上线后通过A/B测试验证效果:
- 实验组(智能推荐)平均决策时间:23秒
- 对照组(传统菜单)平均决策时间:47秒
- 推荐采纳率稳定在68%-72%区间
持续优化中发现三个关键点:
- 考试周需要调高高热量食物权重
- 雨天应优先推荐可外带餐品
- 体育课后自动增加蛋白质推荐比例
这套系统后来被三所高校采用,最意外的收获是食堂阿姨反馈打菜效率提升了——因为推荐减少了学生的犹豫时间。如果有高校同行想实施类似项目,我的建议是务必先做好饮食禁忌数据的采集规范,我们早期就因过敏信息不全闹过几次虚惊。