1. 校园外卖系统的技术选型与架构设计
校园外卖点餐系统需要同时满足学生用户的高并发访问和商家的高效管理需求。我们采用Python+Django作为后端服务框架,uniapp构建微信小程序前端,这种技术组合在校园场景中具有独特优势。
后端选择Python主要基于三个考量:首先,Python生态中有成熟的协同过滤算法实现库(如Surprise、LightFM),便于快速搭建推荐系统;其次,Django框架自带Admin后台,可快速构建商家管理界面;最后,Python的异步任务框架(Celery)能有效处理高峰期的订单队列。实测数据显示,在4核8G服务器上,Django+Redis的组合可以稳定支撑每秒300+的订单请求。
前端采用uniapp则解决了多端适配问题。通过一套代码可同时发布到微信小程序、H5和App(如需后续扩展)。我们在开发中发现,uniapp的编译到小程序平台时,需要特别注意以下配置:
javascript复制// manifest.json 关键配置
{
"mp-weixin": {
"appid": "wx你的小程序ID",
"setting": {
"urlCheck": false // 关闭域名校验方便调试
},
"usingComponents": true
}
}
数据库设计采用MySQL作为主存储,Redis缓存热门商家和菜品数据。核心表包括:
- 用户表(user_profile):存储学生偏好标签
- 商家表(merchant):包含地理位置geo字段
- 订单表(order):关联用户ID和商家ID
- 评分表(rating):记录用户对商家的评分(1-5星)
特别注意:校园场景必须添加教学楼/宿舍楼的位置字段,这是后续推荐算法的重要特征。我们在字段设计中增加了
building_nearby数组字段存储附近500米内的主要建筑。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 协同过滤推荐系统的实现细节
校园外卖的推荐场景与传统电商不同,具有明显的时空特征。我们采用混合协同过滤算法,结合了以下维度:
- 用户基础属性(年级、专业、宿舍位置)
- 历史订单数据(下单时段、常点品类)
- 实时地理位置(当前所在教学楼)
- 商家特征(品类、配送范围、评分)
算法实现主要分为三个步骤:
2.1 数据预处理
使用Python的pandas进行数据清洗:
python复制def preprocess_orders(raw_df):
# 过滤测试订单
df = raw_df[raw_df['status'] != 'test']
# 转换时间特征
df['hour'] = pd.to_datetime(df['create_time']).dt.hour
# 添加用餐时段标签
df['time_slot'] = df['hour'].apply(
lambda x: 'breakfast' if 6<=x<9 else 'lunch' if 11<=x<13 else 'dinner')
return df
2.2 相似度计算
采用改进的余弦相似度算法,加入地理位置权重:
python复制from sklearn.metrics.pairwise import cosine_similarity
def geo_weighted_similarity(user1, user2, max_dist=2000):
base_sim = cosine_similarity([user1['features'], user2['features']])[0][1]
dist = haversine(user1['location'], user2['location'])
return base_sim * (1 - dist/max_dist) if dist < max_dist else 0
2.3 推荐生成
结合基于用户和基于物品的协同过滤:
python复制def hybrid_recommend(user_id, n=10):
# 获取相似用户
similar_users = find_topk_similar_users(user_id)
# 合并相似用户的订单
candidate_merchants = merge_orders(similar_users)
# 加入地理位置过滤
nearby_merchants = filter_by_distance(candidate_merchants, current_loc)
# 最终按评分排序
return sorted(nearby_merchants, key=lambda x: x['rating'], reverse=True)[:n]
实测中发现三个关键优化点:
- 冷启动问题:对新用户采用"热门商家+距离优先"的兜底策略
- 时段敏感性:午餐时段优先推荐出餐快的商家,夜宵时段显示营业到更晚的店铺
- 实时反馈:用户取消订单会立即降低对应商家在推荐列表的权重
3. Uniapp微信小程序的性能优化
校园场景下,学生通常在课间集中访问系统,这对小程序性能提出挑战。我们通过以下措施确保流畅体验:
3.1 分包加载策略
将商家列表、菜单详情等非核心功能拆分为子包:
javascript复制// pages.json
{
"subPackages": [{
"root": "package-merchant",
"pages": [
"merchant/list",
"merchant/detail"
]
}]
}
3.2 数据缓存机制
利用uniapp的存储API缓存商家数据:
javascript复制// 获取商家列表时优先读取缓存
async function getMerchants() {
try {
const cached = uni.getStorageSync('merchant_cache')
if (cached && Date.now() - cached.timestamp < 3600000) {
return cached.data
}
const freshData = await api.fetchMerchants()
uni.setStorageSync('merchant_cache', {
timestamp: Date.now(),
data: freshData
})
return freshData
} catch (e) {
console.error('Cache failed:', e)
return api.fetchMerchants() // 降级方案
}
}
3.3 渲染性能优化
针对长列表使用虚拟滚动:
html复制<template>
<uv-list
:data="foodList"
:height="scrollHeight"
:item-size="itemHeight"
@scroll="handleScroll"
>
<template #default="{ item }">
<food-item :data="item" />
</template>
</uv-list>
</template>
我们在华为P30上测试发现,优化后页面加载时间从2.3s降至0.8s,滚动帧率稳定在60fps。特别要注意的是,微信小程序环境与H5的差异:
- 小程序没有DOM API,不能直接操作节点
- setData调用频率过高会导致明显卡顿
- 图片资源需要提前压缩到500KB以内
4. 商家协同管理的关键实现
商家端功能需要特别考虑校园场景的特殊需求:
4.1 订单聚合视图
python复制# Django Admin定制
class OrderAdmin(admin.ModelAdmin):
list_display = ('id', 'short_items', 'building', 'status')
list_filter = ('time_slot', 'building')
def short_items(self, obj):
return ", ".join([i.name[:5] for i in obj.items.all()[:3]])
short_items.short_description = '商品简略'
4.2 智能接单策略
根据商家产能自动调节接单量:
python复制def auto_accept_orders(merchant_id):
merchant = Merchant.objects.get(pk=merchant_id)
current_orders = Order.objects.filter(
merchant=merchant,
status='pending'
).count()
max_capacity = merchant.max_parallel_orders
prep_time = merchant.avg_prep_time
if current_orders >= max_capacity:
return False
elif prep_time > 30 and current_orders >= max_capacity * 0.7:
return False
return True
4.3 营业状态联动
课表数据同步商家营业时间:
python复制# 课表同步任务
@periodic_task(run_every=crontab(hour=2, minute=30))
def sync_schedule():
term_start = get_current_term_start()
for merchant in Merchant.objects.filter(campus='main'):
if merchant.near_classroom:
merchant.open_time = '11:30' # 下课前30分钟
merchant.save()
我们在实际部署中发现几个典型问题:
- 食堂商家在课间10分钟会集中收到大量订单,需要特殊处理队列
- 校外商家需要明确标注配送时间差异
- 节假日模式需要单独配置营业时间
5. 部署与监控方案
系统采用Docker-compose部署,核心服务包括:
yaml复制version: '3'
services:
web:
image: django:4.2
ports: ["8000:8000"]
depends_on: [redis, db]
celery:
build: .
command: celery -A core worker -l info
redis:
image: redis:alpine
db:
image: postgres:13
volumes:
- pgdata:/var/lib/postgresql/data
监控方面采用Prometheus+Grafana组合,重点监控指标:
- 推荐算法响应时间(P99<200ms)
- 订单创建成功率(>99.5%)
- 商家接单平均延迟(<90s)
日志分析中发现两个需要优化的点:
- 上午3-4点定期任务会导致短暂性能下降
- 考试周期间订单模式与平时差异显著,需要动态调整推荐策略
针对校园网络特点,我们还实现了弱网优化方案:
- 订单提交采用指数退避重试
- 关键接口支持增量更新
- 本地持久化未提交的订单草稿
