资讯动态

微信小程序+Python+MySQL校园外卖系统实战指南

发布时间:2026/10/13 19:57:44 来源:尧图企业网站定制
简介这是一份面向高校数据库课程设计与全栈开发初学者的微信小程序校园外卖系统实战项目聚焦数据库建模、前后端协同与小程序UI交互三大核心能力训练。资源包含完整可运行的小程序前端WXML/WXSS/JS/JSON、Python后端逻辑含SQL脚本、商家与学生双角色业务流程及配套数据库设计说明适用于课程设计答辩、小组项目参考或小程序数据库综合实践。压缩包共123个文件涵盖22个JS逻辑文件、19个WXSS样式文件、18个WXML页面结构文件、21个JSON配置文件、2个SQL建表与初始化脚本、2个Python服务脚本以及商品与界面截图等辅助素材整体仅2.37MB轻量易部署。已有280人学习下载内容结构清晰模块划分明确——从用户下单、商家管理商品与订单、配送员接单履约到评价反馈完整覆盖校园外卖闭环业务附带地址管理、订单状态机、评分体系等典型功能实现细节便于理解真实场景下的数据流与权限控制设计。1. 这不是“小程序Python”拼凑作业它是一套可跑通的校园外卖闭环系统含微信端交互、后端逻辑与数据库设计三件套你拿到的这个压缩包基于JavaScriptpython的微信小程序校园外卖系统数据库课程设计.zip表面看是课程设计作业实则是少有的、把「微信小程序前端JavaScript」「Python后端服务」「MySQL/SQLite数据库建模与CRUD」三者真正串起来跑通的轻量级生产级范例。它不依赖云开发、不走微信云托管而是用 Python 写 REST APIFlask 或 FastAPI 常见用微信小程序原生框架调用数据库设计覆盖用户、商户、菜品、订单、评价五大核心实体且包含外键约束、索引优化、事务回滚等课程设计关键得分点。很多同学卡在“小程序发请求但 Python 接不到”“数据库建了但增删改查总报错”“登录态传不进后端”——这恰恰说明它不是玩具 demo而是暴露真实链路断点的教学载体。适合数据库课设需要交源码报告演示视频的同学也适合想用最小成本验证“小程序PythonMySQL”技术栈可行性的初学者。别被标题里的“课程设计”误导——只要把app.js里baseUrl指向你的本地 Python 服务改两行配置就能在真机上完成从浏览餐厅→下单→支付模拟→查看订单全流程。2. 拆包即运行从解压到本地启动小程序Python服务的最小闭环2.1 解压后目录结构解析识别哪部分是前端、哪部分是后端、哪部分是数据库脚本拿到.zip文件后先解压推荐用 7-Zip 或系统自带解压工具避免 macOS 自带归档工具解压乱码。典型目录结构如下实际以你解压后为准但大体一致wechat-campus-food/ ├── frontend/ # 微信小程序源码含 project.config.json │ ├── app.js # 全局逻辑含 baseUrl 配置 │ ├── pages/ │ │ ├── index/index.js # 首页逻辑发起 GET /api/restaurants 请求 │ │ └── order/order.js # 下单页POST /api/orders │ └── utils/request.js # 封装 wx.request处理 token、错误统一提示 ├── backend/ # Python 后端服务常见为 Flask │ ├── app.py # 主程序含路由定义 │ ├── models.py # ORM 模型SQLAlchemy 或原生 sqlite3 │ ├── requirements.txt # 依赖列表必含 flask, flask-sqlalchemy, python-dotenv │ └── config.py # 数据库连接配置如 sqlite:///db.sqlite3 ├── database/ # 数据库初始化脚本 │ ├── init_db.sql # CREATE TABLE 语句含外键、NOT NULL 约束 │ └── sample_data.sql # INSERT 示例数据3家餐厅、10道菜、5个用户 └── README.md # 关键启动说明常被忽略但极其重要提示frontend/下必须有project.config.json这是微信开发者工具识别项目的依据backend/下必须有requirements.txt否则 pip install 会漏依赖database/下的.sql文件是课程设计得分核心——它体现你对范式、约束、索引的理解不是随便写的CREATE TABLE user(id INT)。2.2 微信小程序端用开发者工具打开并修改请求地址打开微信开发者工具v1.06.2308010 及以上选择「导入项目」→ 选中frontend/目录 → AppID 填*测试号即可。关键一步修改请求域名。打开frontend/utils/request.js找到类似代码// utils/request.js const BASE_URL https://api.example.com; // ← 这行必须改 // 改为你的本地 Python 服务地址例如 const BASE_URL http://127.0.0.1:5000; // Flask 默认端口 // 或 const BASE_URL http://localhost:8000; // FastAPI 默认端口参数说明127.0.0.1比localhost更可靠某些系统 DNS 解析异常端口号必须与后端app.py中app.run(portxxx)一致微信小程序调试器默认禁用http请求需在开发者工具右上角「详情」→「本地设置」→ 勾选「不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书」——这是新手第一大翻车点不勾此项所有请求 0 响应。2.3 Python 后端用 pip 安装依赖并启动服务Flask 示例进入backend/目录执行# 创建虚拟环境强烈建议避免污染全局 Python python -m venv venv source venv/bin/activate # Linux/macOS # venv\Scripts\activate.bat # Windows # 安装依赖requirements.txt 必须存在 pip install -r requirements.txt # 初始化数据库执行 init_db.sql 和 sample_data.sql python init_db.py # 此脚本通常由作者提供内含 sqlite3.executescript() # 若无 init_db.py则手动执行 # sqlite3 db.sqlite3 database/init_db.sql # sqlite3 db.sqlite3 database/sample_data.sql # 启动服务 python app.pyapp.py典型内容Flask# backend/app.py from flask import Flask, jsonify, request from models import db, User, Restaurant, Dish, Order # models.py 定义 ORM 模型 import os app Flask(__name__) app.config[SQLALCHEMY_DATABASE_URI] os.getenv(DATABASE_URL, sqlite:///db.sqlite3) app.config[SQLALCHEMY_TRACK_MODIFICATIONS] False db.init_app(app) app.route(/api/restaurants, methods[GET]) def get_restaurants(): restaurants Restaurant.query.all() return jsonify([{ id: r.id, name: r.name, address: r.address, rating: r.rating } for r in restaurants]) if __name__ __main__: app.run(host0.0.0.0, port5000, debugTrue) # host0.0.0.0 允许局域网访问逻辑说明host0.0.0.0是关键——让手机真机扫码调试时能访问到你的电脑服务需同一 WiFidebugTrue开启热重载改代码自动重启但上线必须关掉models.py中Restaurant类必须映射restaurants表字段名与init_db.sql严格一致大小写敏感若用 SQLitedb.sqlite3文件会自动生成在backend/目录下确保该目录有写权限。2.4 数据库初始化手动生成.sqlite3文件并验证表结构即使init_db.py存在也建议手动验证数据库是否建好。打开终端进入backend/目录# 启动 sqlite3 命令行 sqlite3 db.sqlite3 # 查看所有表 .tables # 应输出dishes orders restaurants users ... # 查看 restaurants 表结构验证外键、NOT NULL .schema restaurants # 输出应类似 # CREATE TABLE restaurants ( # id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, # name TEXT NOT NULL, # address TEXT NOT NULL, # rating REAL DEFAULT 0.0, # created_at DATETIME DEFAULT CURRENT_TIMESTAMP # ); # 查询示例数据 SELECT id, name FROM restaurants LIMIT 3; # 应返回 3 行餐厅名称证明 sample_data.sql 已生效 .quit参数说明.tables是 SQLite 内置命令非 SQL 语句前面带点.schema 表名显示建表语句重点检查NOT NULL、FOREIGN KEY是否存在课程设计硬性要求SELECT验证数据可读避免因编码问题如 SQL 文件保存为 UTF-8-BOM导致插入失败若.schema报错no such table说明init_db.sql未执行成功需检查路径或手动粘贴执行。3. 数据库设计落地从 ER 图到五张表的字段级实现与约束细节3.1 核心五张表 ER 关系与主外键设计逻辑该系统数据库设计遵循第三范式3NF消除冗余明确职责。ER 关系如下文字描述无需画图users表存储学生/管理员信息主键idrole字段区分student/admin/merchantrestaurants表商户信息主键iduser_id外键关联users.id一个商户对应一个注册用户dishes表菜品主键idrestaurant_id外键关联restaurants.idprice为DECIMAL(10,2)精确到分orders表订单主表主键iduser_id下单人、restaurant_id所属餐厅、statuspending/confirmed/delivered/cancelledorder_items表关联表记录订单明细复合主键(order_id, dish_id)外键分别指向orders.id和dishes.id含quantity字段。为什么这样设计restaurants.user_id外键保证商户必须是已注册用户避免空商户dishes.restaurant_id外键确保菜品归属明确删除餐厅时自动清空其菜品ON DELETE CASCADEorder_items单独成表而非在orders中加dish_ids TEXT字段支持同一订单多菜品、不同数量且便于统计销量SELECT dish_id, SUM(quantity) FROM order_items GROUP BY dish_idstatus用字符串枚举而非数字提高可读性课程设计报告中可直接截图说明。3.2init_db.sql关键字段与约束逐行解读以 MySQL 兼容语法为例以下是database/init_db.sql中restaurants表的典型建表语句SQLite 语法略有差异但核心约束一致-- database/init_db.sql CREATE TABLE IF NOT EXISTS restaurants ( id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(100) NOT NULL, address VARCHAR(255) NOT NULL, phone VARCHAR(20), rating DECIMAL(3,2) DEFAULT 0.0 CHECK (rating 0 AND rating 5.0), user_id INTEGER NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE );参数说明VARCHAR(100)餐厅名一般不超过 100 字符过长浪费空间DECIMAL(3,2)3总位数2小数位支持4.99这类评分比FLOAT更精确CHECK约束强制评分在 0~5数据库层校验比应用层更可靠ON UPDATE CURRENT_TIMESTAMPSQLite 不支持需在 Python 更新时手动赋值ON DELETE CASCADE删除用户时自动删其餐厅避免孤儿数据——这是课程设计高分点务必在报告中强调。3.3sample_data.sql的数据构造技巧用 INSERT VALUES 批量插入且可读sample_data.sql不应是导出的乱码 SQL而是人工编写的清晰插入语句-- database/sample_data.sql INSERT INTO users (username, password_hash, role, real_name, phone) VALUES (zhangsan, $2b$12$..., student, 张三, 13800138000), (lisi, $2b$12$..., merchant, 李四, 13900139000); INSERT INTO restaurants (name, address, phone, user_id) VALUES (清真兰州拉面, 学生活动中心B座1楼, 13500135000, 2); INSERT INTO dishes (name, price, description, restaurant_id) VALUES (牛肉面, 12.50, 汤清肉烂辣子香, 1), (凉皮, 8.00, Q弹爽滑秘制酱料, 1);逻辑说明password_hash是 bcrypt 加密后的密文非明文123456体现安全性意识user_id值2对应lisi确保餐厅归属正确每条INSERT后换行方便调试时注释某行单独执行描述字段description为后续小程序展示菜品详情预留非冗余字段。3.4 数据库同步与备份用 SQLite 原生命令实现一键导出/导入课程设计验收时老师可能要求提供数据库文件。SQLite 无需额外工具用命令行即可# 导出当前数据库为 SQL 脚本含表结构和数据 sqlite3 db.sqlite3 .dump backup_20240601.sql # 从 SQL 脚本重建数据库清空原库重新执行 sqlite3 new_db.sqlite3 backup_20240601.sql # 验证新库数据 sqlite3 new_db.sqlite3 SELECT COUNT(*) FROM restaurants; # 应返回与原库相同数字参数说明.dump输出的是可执行的 SQL包含CREATE TABLE和INSERT比直接复制.sqlite3文件更安全避免文件锁、权限问题backup_20240601.sql命名含日期方便版本管理导入时new_db.sqlite3是全新文件不会覆盖原库降低误操作风险。4. 前后端联调避坑那些让你卡住 3 小时却只因一行配置的致命问题4.1 现象小程序wx.request返回fail控制台无错误Network 面板显示Failed to load resource原因微信开发者工具未开启「不校验合法域名」或BASE_URL写成https://localhost:5000HTTPS 协议但本地 HTTP 服务。解决确认开发者工具右上角「详情」→「本地设置」→ 勾选「不校验合法域名...」检查utils/request.js中BASE_URL协议为http且端口与 Python 服务一致在浏览器访问http://127.0.0.1:5000/api/restaurants若返回 JSON 则后端正常问题在小程序配置。4.2 现象Python 后端报错sqlite3.OperationalError: no such table: users原因init_db.py未执行或app.py中数据库路径指向错误位置如sqlite:///../db.sqlite3但实际在同级目录。解决进入backend/目录执行ls -la | grep sqlite3确认db.sqlite3文件存在检查config.py或app.py中SQLALCHEMY_DATABASE_URI路径用绝对路径更稳妥import os basedir os.path.abspath(os.path.dirname(__file__)) app.config[SQLALCHEMY_DATABASE_URI] fsqlite:///{os.path.join(basedir, db.sqlite3)}4.3 现象下单成功但数据库orders表无数据order_items为空原因orders表status字段设为NOT NULL但 Python 代码插入时未传status值触发数据库拒绝。解决查看models.py中Order类定义确认status有默认值status db.Column(db.String(20), nullableFalse, defaultpending)或在app.py创建订单时显式赋值new_order Order(user_iduser_id, restaurant_idrest_id, statuspending)4.4 现象小程序登录后后续请求 Header 中Authorization丢失后端request.headers.get(Authorization)为 None原因utils/request.js中未在每次请求头中携带 token或wx.setStorageSync(token, res.data.token)后未在请求拦截器中读取。解决确保utils/request.js的request函数包含 tokenconst token wx.getStorageSync(token); if (token) { header[Authorization] Bearer ${token}; }登录接口返回的res.data.token必须是后端生成的 JWT 或 session ID不能是前端随机字符串。4.5 现象flask-sqlalchemy报错AttributeError: NoneType object has no attribute query原因db实例未通过db.init_app(app)初始化或models.py在app创建前被导入。解决确保app.py中db.init_app(app)在app Flask(__name__)之后、路由定义之前models.py中不要直接db SQLAlchemy()而应from flask_sqlalchemy import SQLAlchemy; db SQLAlchemy()延迟绑定。5. 进阶验证用 Postman SQLite Browser 独立验证 API 与数据一致性5.1 用 Postman 绕过小程序直测 Python API 的健壮性Postman 是验证后端逻辑的黄金标准避免前端干扰。新建 Collection按以下顺序测试请求方法URLBodyJSON预期响应GEThttp://127.0.0.1:5000/api/restaurants—返回[{id:1,name:兰州拉面,...}]POSThttp://127.0.0.1:5000/api/login{username:zhangsan,password:123456}返回{token:eyJhbGciOi...}POSThttp://127.0.0.1:5000/api/orders{restaurant_id:1,items:[{dish_id:1,quantity:2}]}返回{order_id:101,status:pending}操作要点在 POST/api/orders的 Headers 中添加Authorization: Bearer your_tokenBody 选raw→JSON确保 JSON 格式合法用在线 JSON 校验器预检每次请求后立即用 SQLite Browser 查看数据库变化确认orders表新增记录、order_items表关联正确。5.2 用 DB Browser for SQLite 可视化查数据比命令行更直观下载 DB Browser for SQLite 免费开源打开backend/db.sqlite3Browse Data 标签页点击orders表看到刚用 Postman 创建的订单Execute SQL 标签页运行复杂查询如-- 查看某餐厅今日订单总数及平均金额 SELECT COUNT(*) as order_count, AVG(total_amount) as avg_amount FROM orders o JOIN restaurants r ON o.restaurant_id r.id WHERE r.name 清真兰州拉面 AND DATE(o.created_at) DATE(now);Pragma 标签页检查PRAGMA table_info(restaurants)确认user_id列pk为 0非主键、notnull为 1非空约束生效。为什么用 GUI 工具新手对 SQL 语法不熟GUI 点击即可查表、改数据降低试错成本可直接双击单元格编辑数据快速修复测试数据错误如把status从pendng改为pending导出为 CSV 功能方便课程设计报告附上「订单数据样例表」。5.3 小程序真机调试用同一 WiFi 让手机访问电脑服务的实操细节微信开发者工具的「预览」二维码仅限局域网访问。真机调试步骤电脑和手机连同一 WiFi如TP-LINK_XXXX电脑终端执行ipconfigWindows或ifconfigmacOS/Linux找到 IPv4 地址如192.168.1.102修改小程序utils/request.js中BASE_URL为http://192.168.1.102:5000重启 Python 服务确保app.run(host0.0.0.0, port5000)手机微信扫码「预览」二维码加载成功即表示跨设备通信正常。血泪经验部分路由器开启「AP 隔离」会阻止手机访问电脑需在路由器后台关闭Windows 防火墙可能拦截5000端口临时关闭防火墙或添加入站规则手机浏览器访问http://192.168.1.102:5000/api/restaurants若返回 JSON 则网络通畅问题必在小程序代码。5.4 数据库性能边界测试当订单量超 10 万行时哪些索引能救命课程设计虽小但提前埋下性能意识是工程师素养。对高频查询字段加索引-- 在 orders 表的 restaurant_id 和 status 上建复合索引查某餐厅待处理订单 CREATE INDEX idx_orders_rest_status ON orders(restaurant_id, status); -- 在 order_items 表的 order_id 上建索引查订单明细 CREATE INDEX idx_order_items_order ON order_items(order_id); -- 在 dishes 表的 restaurant_id 上建索引查某餐厅所有菜品 CREATE INDEX idx_dishes_rest ON dishes(restaurant_id);参数说明idx_前缀是命名规范表明这是索引复合索引(restaurant_id, status)比单列索引更高效因为查询条件通常是WHERE restaurant_id1 AND statuspendingSQLite 中EXPLAIN QUERY PLAN SELECT ...可查看是否命中索引返回SEARCH TABLE orders USING INDEX idx_orders_rest_status即成功。我带过三届数据库课设最常看到的不是代码写错而是学生把init_db.sql当摆设建表没外键、没 NOT NULL、没索引最后答辩被老师一句“你这数据库设计不符合基本范式”直接问懵。所以我的习惯是解压后第一件事不是跑代码而是用 SQLite Browser 打开db.sqlite3点开每个表的Structure逐行核对字段类型、约束、索引——这 5 分钟省下后面 5 小时 debug。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑