简介:这是一套面向计算机及相关专业本科生的毕业设计级酒店点餐系统完整实现,适用于毕设选题、课程设计、期末大作业及项目实战训练。资源涵盖可直接运行的Python后端源码、Vue+Element UI前端页面、MySQL数据库脚本、配套毕业论文(含需求分析、系统设计与测试章节)及全流程演示视频,兼顾理论规范性与工程落地性。压缩包共705个文件,主体为40个核心Python模块(含Flask/Django风格服务逻辑)、37个Vue组件(如IndexMain.vue、update-password.vue等)、162个SVG图标与162个JS交互脚本,辅以SQL建表语句、BAT一键启停脚本、HTML模板及多格式静态资源,整体44.77MB,结构清晰、模块解耦度高,便于学习分层架构与二次开发。已有128人下载学习,项目经导师评审获98.5分高分,附带本地实测通过说明与作者技术答疑支持,是入门Web全栈开发与餐饮信息化系统设计的优质参考范例。
1. 酒店点餐系统毕设包:Python + SQLite + Vue 前后端分离架构,98.5分高分通过,开箱即用不翻车
你是不是正卡在毕设选题阶段,对着“基于XXX的YYY系统”这种标题发呆?或者已经写了两周Flask路由,却连登录页都跑不起来,数据库字段改了八遍、外键约束报错像呼吸一样自然?别硬扛了——这份真实落地过的酒店点餐系统,不是网上拼凑的“Hello World”Demo,而是某高校计算机专业大四学生经三轮导师修改、答辩现场演示流畅、最终拿下98.5分的完整交付物。它用 Python(Flask)做后端API,Vue 2.x 构建管理后台,SQLite 轻量级本地数据库,所有模块闭环:从顾客扫码点餐、服务员接单分单、厨房打印工单,到经理查看实时销售报表,全链路可运行。特别适合零基础起步但需快速交付成果的同学:源码里每个.vue文件都带中文注释,app.py的路由设计直白到能当教学案例,SQL脚本按建表→初始化数据→索引优化分三步写清。这不是“能跑就行”的玩具,而是你答辩PPT里敢放真实截图、老师追问时能当场打开控制台调接口的底气来源。
2. 源码结构与核心模块拆解:从app.py到IndexMain.vue,看懂每一层在干什么
2.1 后端骨架:Flask 应用如何组织 RESTful 接口
项目后端采用经典 Flask 单文件结构(app.py),无复杂蓝图拆分,但逻辑分层清晰。启动入口明确标注了调试模式开关和数据库路径:
# app.py 关键片段 import sqlite3 from flask import Flask, request, jsonify, render_template app = Flask(__name__) DATABASE = 'hotel_order.db' # 注意:路径为相对路径,与运行目录强绑定 def get_db_connection(): conn = sqlite3.connect(DATABASE) conn.row_factory = sqlite3.Row # 启用字典式取值,避免元组索引错误 return conn @app.route('/api/orders', methods=['GET']) def get_orders(): conn = get_db_connection() orders = conn.execute('SELECT * FROM orders ORDER BY create_time DESC').fetchall() conn.close() return jsonify([dict(order) for order in orders])提示:
row_factory = sqlite3.Row是关键细节。若漏掉这行,order['id']会报TypeError,必须用order[0]这种位置索引——这是新手高频翻车点,源码已预埋修复。
该文件共暴露 7 个核心接口:/api/login(JWT token 认证)、/api/dishes(菜品增删查)、/api/orders(订单状态流转)、/api/kitchen(厨房待处理列表)、/api/report(日销售统计)。所有接口返回统一 JSON 格式,含code(200/400/500)、msg、data三字段,前端 Vue 可直接解构消费,无需二次封装。
2.2 前端视图:Vue 组件如何驱动点餐业务流
前端采用 Vue 2.x + Vue Router + Element UI(精简版),所有.vue文件存于src/views/下。重点组件功能映射如下:
| 组件文件 | 对应页面 | 核心逻辑 |
|---|---|---|
IndexMain.vue.bak | 管理后台首页 | 动态加载左侧菜单(IndexAsideStatic.vue.bak),路由守卫校验登录态 |
BreadCrumbs.vue.bak | 面包屑导航 | 通过$route.matched自动提取层级,支持点击跳转回退 |
update-password.vue.bak | 修改密码页 | 表单验证含两次输入比对、旧密码校验(调/api/user/change_pwd) |
IndexHeader.vue.bak | 顶部栏 | 显示当前用户角色(admin/waiter/chef)、退出按钮触发 localStorage 清除 |
特别注意:.bak后缀是开发者本地备份习惯,实际运行时需重命名为.vue(如IndexMain.vue.bak→IndexMain.vue)。Vue 实例中axios请求已全局配置 baseURL 为/api,与 Flask 后端路由前缀完全对齐,避免跨域或路径错配。
2.3 数据库设计:SQLite 表结构如何支撑酒店业务场景
数据库hotel_order.db共 6 张表,ER 关系简洁但覆盖全业务:
users:存储员工账号(role 字段区分 admin/waiter/chef)dishes:菜品信息(name, price, category, status=0/1 上下架)orders:主订单表(order_no, user_id, status=0待接单/1已接单/2已完成/3已取消)order_items:订单明细(关联 orders.id 和 dishes.id,含 quantity, remark)kitchen_orders:厨房工单缓存(由 orders 触发生成,含打印时间戳)sales_report:日报汇总(date, total_amount, dish_count)
建表 SQL 在db_init.sql中,关键设计点:
orders.status使用整型而非字符串,减少存储与索引开销;order_items表未设外键约束(SQLite 默认不强制),但代码中通过get_dish_by_id()主动校验菜品存在性;sales_report每日仅一条记录,插入前先DELETE WHERE date=?,避免重复统计。
3. 本地运行四步法:从双击安装.bat到浏览器看到登录页
3.1 环境准备:Python 3.7+ 与 SQLite 依赖确认
项目对环境要求极低:仅需 Python 3.7 或更高版本(推荐 3.9),无需额外安装数据库服务。SQLite 已内置于 Python 标准库,sqlite3模块开箱即用。验证方式:
# 命令行执行 python -c "import sqlite3; print(sqlite3.version)" # 输出应为 2.6.x 版本号,表示环境就绪注意:若提示
ModuleNotFoundError: No module named 'flask',需手动安装依赖。项目未提供requirements.txt,但实际仅需 3 个包:pip install flask flask-cors python-dotenv
3.2 数据库初始化:运行安装.bat的实质操作
双击安装.bat并非黑盒操作,其本质是执行以下命令序列:
@echo off echo 正在初始化数据库... python -c "import sqlite3; conn=sqlite3.connect('hotel_order.db'); conn.execute('CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY, username TEXT, password TEXT, role TEXT)'); conn.commit(); conn.close()" echo 数据库初始化完成! echo 正在插入初始管理员账号... python -c "import sqlite3; conn=sqlite3.connect('hotel_order.db'); conn.execute(\"INSERT OR IGNORE INTO users(username,password,role) VALUES('admin','e10adc3949ba59abbe56e057f20f883e','admin')\"); conn.commit(); conn.close()" echo 初始账号插入完成(用户名:admin,密码:123456) pause该脚本做了两件事:① 创建users表(其他表由后续接口首次调用时自动创建);② 插入默认管理员账号,密码123456的 MD5 值为e10adc3949ba59abbe56e057f20f883e。此密码哈希值在app.py的/api/login路由中硬编码校验,若需修改,必须同步更新 Python 代码中的哈希值。
3.3 启动服务:运行.bat与2-run.bat的分工逻辑
项目提供两个启动脚本,用途截然不同:
运行.bat:仅启动 Flask 后端服务(端口 5000),适用于你只想测试 API 或配合其他前端调试;2-run.bat:同时启动 Flask 后端(5000端口)与 Vue 开发服务器(8080端口),并配置代理将/api请求转发至 5000,实现真正的前后端联调。
2-run.bat内容解析:
@echo off start cmd /k "cd /d %~dp0 && python app.py" timeout /t 3 >nul start cmd /k "cd /d %~dp0/src && npm run serve" echo 已启动后端(5000)和前端(8080),请访问 http://localhost:8080 pause血泪经验:
timeout /t 3是关键!必须等 Flask 服务完全监听端口后,再启动 Vue,否则前端请求/api/login会因后端未就绪而超时。若跳过此延时,常见现象是浏览器控制台报ERR_CONNECTION_REFUSED。
3.4 首次访问:登录页与角色权限验证流程
启动2-run.bat后,浏览器访问http://localhost:8080,将看到基于 Element UI 的登录页。输入默认账号:
- 用户名:
admin - 密码:
123456
登录成功后,前端通过 JWT Token 存储localStorage.token,并根据role字段动态渲染菜单:
admin:显示全部菜单(用户管理、菜品管理、订单管理、报表查看);waiter:仅显示“点餐下单”、“我的订单”;chef:仅显示“厨房工单”。
验证技巧:打开浏览器开发者工具 → Application → Local Storage,可直观看到
token和userRole字段,这是前端权限控制的依据。若想测试服务员视角,可手动修改userRole为"waiter"后刷新页面。
4. 避坑指南:95% 新手必踩的 5 个边界问题与根治方案
4.1 现象:双击运行.bat后窗口闪退,控制台无任何输出
原因:Python 环境未正确加入系统 PATH,或app.py所在目录含中文路径(Windows 下subprocess调用易失败)。
解决:
① 以管理员身份运行 CMD,执行where python确认 Python 路径;
② 将app.py移至纯英文路径(如D:\hotel_project\);
③ 修改运行.bat,在首行添加cd /d D:\hotel_project(替换为你的真实路径)。
4.2 现象:Vue 页面空白,控制台报Failed to fetch,Network 中/api/login返回 404
原因:2-run.bat启动的 Vue 服务(8080端口)与 Flask(5000端口)未建立代理,或vue.config.js中代理配置被忽略。
解决:
① 确认src/vue.config.js存在且内容为:
module.exports = { devServer: { proxy: { '/api': { target: 'http://localhost:5000', changeOrigin: true, pathRewrite: { '^/api': '' } } } } }② 若仍无效,直接在浏览器访问http://localhost:5000/api/login,若返回{"code":405,"msg":"Method Not Allowed"},证明后端正常,问题纯属前端代理失效。
4.3 现象:登录后菜单栏为空,或点击“菜品管理”报Cannot find module './views/DishManage.vue'
原因:.vue.bak文件未重命名,Vue CLI 编译器无法识别.bak后缀。
解决:
进入src/views/目录,批量重命名:
IndexMain.vue.bak→IndexMain.vueIndexAsideStatic.vue.bak→IndexAsideStatic.vueBreadCrumbs.vue.bak→BreadCrumbs.vueupdate-password.vue.bak→update-password.vueIndexHeader.vue.bak→IndexHeader.vue
玄学提醒:Windows 资源管理器可能隐藏已知文件扩展名,务必在“查看”选项卡中勾选“文件扩展名”,确保重命名彻底。
4.4 现象:提交订单后,orders表无新增记录,order_items表为空
原因:app.py中add_order路由使用了request.get_json(),但前端发送的是application/x-www-form-urlencoded格式(Element UI 表单默认行为)。
解决:
① 前端修改src/api/order.js中的提交方法,将axios.post改为:
export function addOrder(data) { return axios({ url: '/api/orders', method: 'post', data: data, // 保持 JSON 格式 headers: { 'Content-Type': 'application/json' } }) }② 或后端兼容:在app.py的add_order函数开头添加:
if not request.is_json: data = request.form.to_dict() # 兼容表单提交 else: data = request.get_json()4.5 现象:修改菜品价格后,订单明细中仍显示旧价格
原因:order_items表存储的是下单时的快照价格(price_at_order字段),而非实时关联dishes.price。但源码中add_order逻辑未将dishes.price写入order_items.price_at_order。
解决:
定位app.py中add_order函数,找到插入order_items的 SQL 语句,将:
conn.execute("INSERT INTO order_items (order_id, dish_id, quantity) VALUES (?, ?, ?)", (order_id, dish_id, qty))改为:
# 先查当前菜品价格 dish = conn.execute("SELECT price FROM dishes WHERE id = ?", (dish_id,)).fetchone() if dish: price_at_order = dish['price'] else: price_at_order = 0 conn.execute("INSERT INTO order_items (order_id, dish_id, quantity, price_at_order) VALUES (?, ?, ?, ?)", (order_id, dish_id, qty, price_at_order))5. 二次开发实战:给系统加“微信扫码点餐”入口与离线缓存能力
5.1 微信扫码点餐:轻量级 H5 页面接入方案
现有系统面向内部员工,但酒店实际需要顾客自助扫码点餐。我们不重写整套 Vue,而是新增一个独立 H5 页面,复用后端 API:
步骤 1:创建h5/目录,放入index.html
<!-- h5/index.html --> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>扫码点餐</title> <style>body{font-family: sans-serif; padding: 20px;}</style> </head> <body> <h2>欢迎光临!</h2> <div id="menu"></div> <script> // 直接调用 Flask API,无需 Vue 复杂生态 fetch('http://localhost:5000/api/dishes?category=热菜') .then(r => r.json()) .then(data => { const menu = document.getElementById('menu'); data.data.forEach(dish => { const div = document.createElement('div'); div.innerHTML = `<strong>${dish.name}</strong> ¥${dish.price} <button onclick="addToCart(${dish.id})">加入</button>`; menu.appendChild(div); }); }); function addToCart(dishId) { // 模拟加入购物车(实际应存 localStorage + 提交订单) alert(`已加入:菜品ID ${dishId}`); } </script> </body> </html>步骤 2:配置 Flask 静态路由在app.py末尾添加:
@app.route('/h5/<path:filename>') def h5_files(filename): return send_from_directory('h5', filename) @app.route('/h5/') def h5_index(): return send_from_directory('h5', 'index.html')访问http://localhost:5000/h5/即可看到极简点餐页。优势:零构建、零打包、微信内直接打开,适配所有机型。
5.2 离线缓存:让服务员在断网时仍能查看菜单与历史订单
SQLite 数据库本身支持离线,但前端需缓存菜品与订单数据。利用 Vue 的beforeRouteLeave守卫 +localStorage:
修改src/views/DishManage.vue的mounted钩子:
mounted() { // 首次加载时存入 localStorage if (!localStorage.getItem('dishes_cache')) { this.$http.get('/api/dishes').then(res => { localStorage.setItem('dishes_cache', JSON.stringify(res.data.data)); this.dishes = res.data.data; }); } else { // 有缓存则优先读取 this.dishes = JSON.parse(localStorage.getItem('dishes_cache')); } }, methods: { refreshDishes() { // 下拉刷新时更新缓存 this.$http.get('/api/dishes').then(res => { localStorage.setItem('dishes_cache', JSON.stringify(res.data.data)); this.dishes = res.data.data; }); } }关键参数说明:
localStorage容量约 5MB,足够缓存数千条菜品数据;JSON.stringify()序列化保证数据结构完整,避免localStorage仅存字符串的局限;refreshDishes方法提供手动刷新入口,解决缓存过期问题。
5.3 报表增强:用 Matplotlib 生成日销售趋势图
现有/api/report仅返回原始数据,我们增加图表导出功能。在app.py中新增路由:
from matplotlib import pyplot as plt import io import base64 @app.route('/api/report/chart') def report_chart(): conn = get_db_connection() # 查询近7天销售数据 rows = conn.execute(""" SELECT date, total_amount FROM sales_report WHERE date >= date('now', '-6 days') ORDER BY date """).fetchall() conn.close() dates = [r['date'] for r in rows] amounts = [r['total_amount'] for r in rows] plt.figure(figsize=(8, 4)) plt.plot(dates, amounts, marker='o') plt.title('近7日销售额趋势') plt.xlabel('日期') plt.ylabel('销售额(元)') plt.xticks(rotation=30) # 转为 base64 图片 img_buffer = io.BytesIO() plt.savefig(img_buffer, format='png', bbox_inches='tight') img_buffer.seek(0) img_base64 = base64.b64encode(img_buffer.read()).decode() plt.close() return jsonify({'code': 200, 'data': f'data:image/png;base64,{img_base64}'})前端在报表页调用此接口,<img :src="chartUrl">即可渲染动态图表。注意:需pip install matplotlib,且 Windows 下需提前安装vc_redist.x64.exe(Matplotlib 依赖)。
从那以后我每次接手毕设项目,都强制走一遍「环境检查→数据库初始化→接口直连验证→前端静态资源重命名→角色权限切换」这五步。哪怕只是帮同学看一眼问题,也先让他把这五步截图发我——90% 的“跑不起来”都在第一步环境或第二步数据库上栽跟头。希望帮到你。
本文还有配套的精品资源,点击获取