Python全栈项目--校园食堂点餐与推荐系统

一、项目简介

校园食堂通常存在高峰排队时间长、菜品信息分散、学生不知道吃什么、食堂窗口难以及时了解用户偏好等问题。本项目以"校园食堂点餐与推荐系统"为主题,实现一个可运行的 Python 全栈应用:学生可以注册登录、浏览菜品、搜索筛选、收藏菜品、加入购物车、提交订单,并根据历史订单与收藏偏好获得推荐菜品。

项目代码位于 project/ 目录,后端使用 FastAPI 提供 REST API,SQLite 保存用户、菜品、订单和收藏数据,前端使用 Vue 3 + Vite 构建交互式单页应用。

二、技术栈

层次 技术 作用
后端框架 FastAPI 提供高性能 RESTful API、自动接口文档
数据库 SQLite 轻量级本地数据存储,适合课程设计和原型项目
ORM SQLAlchemy 定义数据模型并完成数据库操作
数据校验 Pydantic 请求体和响应结构校验
认证鉴权 Passlib + PyJWT 密码哈希、JWT 登录 token、接口保护
前端 Vue 3 + Vite 组件化页面、状态驱动交互、快速开发调试
通信方式 Fetch API 前后端 JSON 数据交互

三、系统架构

系统采用前后端分离架构:

text 复制代码
浏览器 Vue 3 页面
   │  HTTP/JSON + Bearer Token
   ▼
FastAPI 路由层 main.py
   │
   ├── security.py:JWT 生成与解析、密码哈希
   ├── schemas.py:请求/响应模型
   ├── crud.py:业务逻辑
   ├── models.py:SQLAlchemy 数据模型
   ▼
SQLite canteen.db

后端在启动时自动创建数据表并初始化示例菜品。除注册、登录和健康检查外,菜品查询、推荐、收藏、下单、订单查询等核心接口都需要登录 token。

四、功能模块

  1. 用户模块:注册、登录、获取当前用户、退出登录。
  2. 认证模块:密码 bcrypt 哈希存储,登录后签发 JWT,前端请求自动携带 token。
  3. 菜品模块:查看菜品,支持关键词搜索和分类筛选。
  4. 收藏模块:学生可收藏或取消收藏菜品,作为推荐依据之一。
  5. 购物车与订单模块:菜品加入购物车,填写取餐时间,提交订单并扣减库存。
  6. 推荐模块:根据用户常点分类、收藏分类或新用户高评分菜品生成推荐。
  7. 统计模块:展示菜品数量、订单数量、收藏数量、累计消费金额。
  8. 前端交互模块:登录状态保持、鉴权请求封装、响应式页面渲染。

五、数据库/数据模型设计

本项目包含五张核心表:

表名 说明 关键字段
users 用户表 username、email、hashed_password、role
dishes 菜品表 name、window、category、tags、price、stock、rating
orders 订单主表 user_id、pickup_time、status、total_amount
order_items 订单明细表 order_id、dish_id、quantity、unit_price
favorites 收藏表 user_id、dish_id

models.py 中的用户模型示例:

python 复制代码
class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True, index=True)
    username = Column(String(50), unique=True, index=True, nullable=False)
    email = Column(String(120), unique=True, index=True, nullable=False)
    hashed_password = Column(String(255), nullable=False)
    role = Column(String(20), default="student")
    created_at = Column(DateTime, default=datetime.utcnow)

订单采用主从表结构,一个订单可以包含多个菜品明细,便于查询历史订单和统计消费金额。

六、后端接口设计

方法 地址 功能 是否需要登录
GET /api/health 服务健康检查
POST /api/auth/register 用户注册并返回 token
POST /api/auth/login 用户登录并返回 token
GET /api/users/me 当前登录用户信息
GET /api/dishes 菜品列表、搜索、分类筛选
POST /api/dishes 管理员新增菜品
GET /api/recommendations 获取推荐菜品
POST /api/orders 创建订单
GET /api/orders 查看我的订单
POST /api/favorites/{dish_id} 收藏/取消收藏
GET /api/dashboard 首页统计数据

鉴权依赖函数会解析 Bearer token,提取用户名并查询数据库:

python 复制代码
def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security), db: Session = Depends(get_db)):
    payload = decode_access_token(credentials.credentials)
    username = payload.get("sub")
    user = crud.get_user_by_username(db, username)
    if not user:
        raise HTTPException(status_code=401, detail="用户不存在")
    return user

七、前端页面设计

前端采用 Vue 3 单文件组件组织页面,主要页面区域如下:

  • 登录/注册卡片:未登录时展示,注册或登录成功后保存 token。
  • 顶部用户栏:展示当前用户名与退出按钮。
  • 统计卡片:显示菜品数量、订单数量、收藏数量和累计消费。
  • 智能推荐区:展示推荐原因和推荐菜品。
  • 菜品列表区:支持关键词搜索、分类筛选、加入购物车和收藏。
  • 购物车区:展示已选菜品、数量、总价和提交订单按钮。
  • 我的订单区:查看历史订单、状态、取餐时间和菜品明细。

API 封装文件 frontend/src/api.js 负责统一添加鉴权请求头:

javascript 复制代码
async function request(path, options = {}) {
  const headers = { 'Content-Type': 'application/json', ...(options.headers || {}) }
  const token = getToken()
  if (token) headers.Authorization = `Bearer ${token}`
  const res = await fetch(`${API_BASE}${path}`, { ...options, headers })
  const data = await res.json().catch(() => ({}))
  if (!res.ok) throw new Error(data.detail || '请求失败')
  return data
}

八、核心代码讲解

1. 密码哈希与 token 生成

security.py 使用 Passlib 对密码进行 bcrypt 哈希,不在数据库中保存明文密码。登录成功后创建 JWT,后续请求通过该 token 访问受保护接口。

python 复制代码
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def get_password_hash(password: str) -> str:
    return pwd_context.hash(password)

def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str:
    to_encode = data.copy()
    expire = datetime.now(timezone.utc) + (expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
    to_encode.update({"exp": expire})
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)

2. 下单逻辑

下单时后端会校验菜品是否存在、是否上架、库存是否充足,然后扣减库存并写入订单明细。

python 复制代码
def create_order(db: Session, user_id: int, order: schemas.OrderCreate):
    db_order = models.Order(user_id=user_id, pickup_time=order.pickup_time)
    total = 0.0
    for item in order.items:
        dish = db.query(models.Dish).filter(models.Dish.id == item.dish_id, models.Dish.is_available == True).first()
        if not dish:
            raise ValueError("菜品不存在或已下架")
        if dish.stock < item.quantity:
            raise ValueError(f"菜品 {dish.name} 库存不足")
        dish.stock -= item.quantity
        total += dish.price * item.quantity
        db_order.items.append(models.OrderItem(dish_id=dish.id, quantity=item.quantity, unit_price=dish.price))
    db_order.total_amount = round(total, 2)
    db.add(db_order)
    db.commit()
    return db_order

3. 推荐策略

推荐模块优先统计用户历史订单和收藏中的菜品分类。如果用户经常购买"轻食",则推荐评分较高的轻食菜品;如果是新用户,则推荐全站高评分菜品。

python 复制代码
if categories:
    top_category = Counter(categories).most_common(1)[0][0]
    dishes = db.query(models.Dish).filter(models.Dish.category == top_category).order_by(desc(models.Dish.rating)).limit(6).all()
    return f"根据你常点的「{top_category}」分类推荐", dishes

4. Vue 购物车状态

前端购物车存储在响应式数组中,用户点击"加入购物车"后自动合并同一菜品数量,总价由计算属性实时生成。

javascript 复制代码
const cart = ref([])
const cartTotal = computed(() => cart.value.reduce((sum, item) => sum + item.dish.price * item.quantity, 0).toFixed(2))

function addToCart(dish) {
  const item = cart.value.find(i => i.dish.id === dish.id)
  if (item) item.quantity += 1
  else cart.value.push({ dish, quantity: 1 })
}

九、部署与运行步骤

1. 运行后端

bash 复制代码
cd project/backend
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

后端默认地址为 http://localhost:8000,接口文档地址为 http://localhost:8000/docs

2. 运行前端

bash 复制代码
cd project/frontend
npm install
npm run dev

前端默认地址为 http://localhost:5173。前端默认请求 http://localhost:8000,如需修改后端地址,可设置 VITE_API_BASE

3. 体验流程

  1. 注册学生账号。
  2. 登录后浏览菜品列表。
  3. 按关键词或分类筛选菜品。
  4. 收藏喜欢的菜品。
  5. 将菜品加入购物车并提交订单。
  6. 再次刷新推荐列表,观察推荐原因变化。

十、项目总结

本项目完整覆盖了 Python 全栈项目中的关键能力:后端接口、数据库建模、认证鉴权、业务逻辑、前端组件化、前后端联调和部署运行说明。与普通 CRUD 项目相比,校园食堂点餐与推荐系统增加了订单明细、库存扣减、收藏偏好和推荐策略,更贴近真实校园业务场景。

后续可继续扩展:管理员菜品管理后台、食堂窗口接单端、在线支付、排队号、营养分析、协同过滤推荐算法、订单评价和消息通知等功能。

项目代码

下载链接

相关推荐
aaPIXa6221 小时前
C++模板元编程:编译期计算Fibonacci数列
java·开发语言·c++
Ulyanov1 小时前
雷达导引头体制演进、技术特点与数学模型
python·雷达电子对抗·导引头
eybk1 小时前
写一个可以编制pdf文件的python程序
开发语言·python·pdf
卷无止境1 小时前
从Python的cryptography库出发,从零开始理解密码学,到构建零信任网络
后端·python
YFJ_mily1 小时前
**Python 实战:写一个论文 PDF 投稿自检工具|附 IPAT 2026 智能光子学会议征稿信息
人工智能·python·pdf·量子计算·论文投稿·智能光子学
三川6981 小时前
Tkinter库的学习记录05-文本框Entry
python
cui_ruicheng2 小时前
Python从入门到实战(八):封装、多态与抽象类
开发语言·python
apihz2 小时前
台风实时与历史详情查询免费 API 接口完整教程
android·开发语言·tcp/ip·dubbo·台风·天气预报
知无不研2 小时前
c语言和c++中的静态关键字
开发语言·c++·静态关键字