Python+Vue酒店点餐系统毕设:Flask+SQLite+Element UI开箱即用

📅 发布时间:2026/10/18 18:35:18
Python+Vue酒店点餐系统毕设:Flask+SQLite+Element UI开箱即用
简介这是一套面向计算机及相关专业本科生的毕业设计级酒店点餐系统完整实现适用于毕设选题、课程设计、期末大作业及项目实战训练。资源涵盖可直接运行的Python后端源码、VueElement 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分的完整交付物。它用 PythonFlask做后端APIVue 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/loginJWT token 认证、/api/dishes菜品增删查、/api/orders订单状态流转、/api/kitchen厨房待处理列表、/api/report日销售统计。所有接口返回统一 JSON 格式含code200/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_pwdIndexHeader.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/chefdishes菜品信息name, price, category, status0/1 上下架orders主订单表order_no, user_id, status0待接单/1已接单/2已完成/3已取消order_items订单明细关联 orders.id 和 dishes.id含 quantity, remarkkitchen_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-dotenv3.2 数据库初始化运行安装.bat的实质操作双击安装.bat并非黑盒操作其本质是执行以下命令序列echo off echo 正在初始化数据库... python -c import sqlite3; connsqlite3.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; connsqlite3.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 fetchNetwork 中/api/login返回 404原因2-run.bat启动的 Vue 服务8080端口与 Flask5000端口未建立代理或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 charsetutf-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title扫码点餐/title stylebody{font-family: sans-serif; padding: 20px;}/style /head body h2欢迎光临/h2 div idmenu/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 onclickaddToCart(${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, markero) plt.title(近7日销售额趋势) plt.xlabel(日期) plt.ylabel(销售额元) plt.xticks(rotation30) # 转为 base64 图片 img_buffer io.BytesIO() plt.savefig(img_buffer, formatpng, bbox_inchestight) img_buffer.seek(0) img_base64 base64.b64encode(img_buffer.read()).decode() plt.close() return jsonify({code: 200, data: fdata:image/png;base64,{img_base64}})前端在报表页调用此接口img :srcchartUrl即可渲染动态图表。注意需pip install matplotlib且 Windows 下需提前安装vc_redist.x64.exeMatplotlib 依赖。从那以后我每次接手毕设项目都强制走一遍「环境检查→数据库初始化→接口直连验证→前端静态资源重命名→角色权限切换」这五步。哪怕只是帮同学看一眼问题也先让他把这五步截图发我——90% 的“跑不起来”都在第一步环境或第二步数据库上栽跟头。希望帮到你。本文还有配套的精品资源点击获取