基于flask+bootstrap+echarts+mysql的鱼村小馆订餐后台管理系统

news2024/11/16 21:28:21

📋 个人简介

  • 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜
  • 📝 个人主页:馆主阿牛🔥
  • 🎉 支持我:点赞👍+收藏⭐️+留言📝
  • 📣 系列专栏:项目🍁
  • 💬格言:要成为光,因为有怕黑的人!🔥
    请添加图片描述

目录

    • 📋 个人简介
  • 🍎前言
    • 🍓项目展示
    • 🍓关于项目“鱼村小馆订餐后台管理系统”的说明
    • 🍓项目目录的说明
    • 🍓项目数据库表
    • 🍓项目特点介绍
    • 🍓项目部分代码
    • 🍓项目数据库迁移操作与项目启动操作
    • 🍓源码获取
  • 🍎结语

🍎前言

flask专栏已经很久没更新了,对于这个专栏我设置为付费是因为我对flask项目的搭建是有着自己的一套理解的,而且对于后面的这些项目,我都会放在项目专栏中,也就是说对于这些项目的介绍,我都会放在项目专栏中,感兴趣的可以免费看!最近又在做一个flask项目,后面会将用到的知识总结在这个专栏中,可以说的是这个正在做的项目比前面做的几个绝对要好,静静等待吧!在此之前我要在本篇博客中将之前没有总结的项目“鱼村小馆订餐后台管理系统”总结一下!

🍓项目展示

文末获取源码,这里展示效果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

🍓关于项目“鱼村小馆订餐后台管理系统”的说明

这个项目是十分初级与简单的一个后台管理系统,主要复杂在他的数据库表比较多,因此数据库表之间的关系比较麻烦,并且当时时间有限,我就没有去做这个项目的前台部分,也就是点餐操作,但是作为一个点餐项目的后台系统绝对是没有问题的,可以在此基础上完善前台,至于前台则可以是小程序,可以是网站等都可以,除了数据库表前台程序需要,可以说整个后台完全是独立的!

🍓项目目录的说明

在这里插入图片描述
后台有仪表盘,账号管理,菜品和菜品分类管理,会员管理,财务管理以及统计管理。

🍓项目数据库表

这个项目的数据库表还是比较多的,其中有些关系也要搞明白,像菜品表和菜品分类表的关系,订单表和订单详情表的关系等等,都是数据库学习当中比较普遍的关系,这里我不在多说!
项目的数据库表如下图所示:

在这里插入图片描述
这里放几个model类:

User(管理员):

class User(db.Model):
    __tablename__ = 'user'

    uid = db.Column(db.BigInteger, primary_key=True,comment="用户uid")  # 用户uid
    nickname = db.Column(db.String(100), nullable=False,comment="用户昵称")  # 用户昵称
    mobile = db.Column(db.String(20), nullable=False,comment="手机号码")  # 手机号码
    email = db.Column(db.String(100), nullable=False,comment="邮箱地址")  # 邮箱地址
    sex = db.Column(db.Integer, nullable=False,server_default="1",default=1,comment="性别")  # 1:男 | 2:女
    avatar = db.Column(db.String(64), nullable=False,server_default="avatar.png",default="avatar.png",comment="头像")  # 头像
    login_name = db.Column(db.String(20), nullable=False, unique=True,comment="登录用户名")  # 登录用户名
    login_pwd = db.Column(db.String(32), nullable=False,comment="登录密码")  # 登录密码
    login_salt = db.Column(db.String(32), nullable=False,comment="登录密码的随机密钥")  # 登录密码的随机密钥
    identity = db.Column(db.Integer, nullable=False, server_default="0",default=0,comment="身份") # 1,主管理员 0,管理员
    status = db.Column(db.Integer, nullable=False, server_default="1",default=1,comment="状态")  # 1:有效 | 0:无效
    updated_time = db.Column(db.DateTime, nullable=False,comment="最后一次更新时间")  # 最后一次更新时间
    created_time = db.Column(db.DateTime, nullable=False,comment="插入时间")  # 插入时间

    #建表结构(初始化实例)有效的要使用参数server_default,即"desc 表结构"可以查到默认值;
    # 另外 server_default的值必须是字符串;
    #往表中插入记录默认值有效用参数default。

Member(会员):

class Member(db.Model):
    __tablename__ = 'member'

    id = db.Column(db.Integer, primary_key=True)
    nickname = db.Column(db.String(100), nullable=False,comment="用户昵称")  # 用户昵称
    mobile = db.Column(db.String(20), nullable=False,comment="手机号码")  # 手机号码
    sex = db.Column(db.Integer, nullable=False,server_default="1",default=1,comment="性别")  # 1:男 | 2:女
    avatar = db.Column(db.String(64), nullable=False,server_default="avatar.png",default="avatar.png",comment="头像")  # 头像
    pwd = db.Column(db.String(32), nullable=False,comment="登录密码")  # 登录密码
    salt = db.Column(db.String(32), nullable=False,comment="登录密码的随机密钥")  # 登录密码的随机密钥
    status = db.Column(db.Integer, nullable=False, server_default="1",default=1,comment="状态")  # 1:有效 | 0:无效
    updated_time = db.Column(db.DateTime, nullable=False, comment="最后一次更新时间")  # 最后一次更新时间
    created_time = db.Column(db.DateTime, nullable=False, comment="插入时间")  # 插入时间

    # 与StatDailyMember中的member_id有关
    statMember = db.relationship("StatDailyMember", backref="member")

由于数据库表比较多,这里不再写,model模型都在代码中,后面拿到源码可自己去看!

🍓项目特点介绍

  1. 使用了echarts,更好的展示统计数据
  2. 后台管理员有管理员与主管理员之分,主管理员可以有控制管理员账户的权限,而管理员无控制主管理员的权限
  3. 对于菜品图片的上传采用无刷新上传的方式
  4. 对于分页展示,采用的是自己写的分页操作代码
  5. 项目使用layer.js弹窗组件,效果较好,且对信息修改的校验较完善
  6. 项目使用bootstrap框架,采用自适应的方式,一套代码兼容手机与pc端

🍓项目部分代码

1.以我的经验,app.py文件中要加入以下几行代码:

# 将application目录添加到项目路径,解决views里的文件导入models里的模型类时找不到models模块路径的问题
import sys,os
sys.path.append(os.getcwd() + "/application")
# print(sys.path)

相关说明请看:【flask进阶】手把手带你搭建可扩展的flask项目脚手架

2.项目中分页操作请看:【flask进阶】Flask实现自定义分页(python web通用)

3.项目中用到的无刷新上传图片操作
采用ajax进行图片的无刷新上传,有些参数需要注意:

前端ajax上传图片代码:

$(".wrap_food_edit .upload_pic_wrap input[name=pic]").change(function(){
         var data=new FormData;
         data.append("pic",document.getElementById("upload-pic").files[0]);
         $.ajax({
             url:"/food/upload-pic",
             type:"POST",
             dataType:"JSON",
             data:data,
             contentType: false,
             processData: false,
             success:function(res){
                 if(res.code == -1){
                     common_ops.alert(res.msg)
                 }
                 if(res.code == 200){
                     var html = '<img src="' + res.src + '"/>' + '<span class="fa fa-times-circle del del_image"></span>';
                     //只能上传一张照片
                     if ($(".upload_pic_wrap .pic-each").size() > 0) {
                         wrap_food_edit.deleteFun()
                         $(".upload_pic_wrap").append('<span class="pic-each">' + html + '</span>');
                     } else {
                         $(".upload_pic_wrap").append('<span class="pic-each">' + html + '</span>');
                     }
                     // 当这个图标构建出来后绑定事件
                     wrap_food_edit.deletePic();
                 }
             }
         })
 })

后端上传图片与删除图片的视图操作代码:

@route_food.route("/upload-pic",methods=["POST"])
def uploadPic():
    img_file = request.files.get("pic",None)

    if img_file is None:
        return jsonify({"code":-1,"msg":"上传失败!","src":""})

    # 将图片名按照. 进行切分, 找到最后一个元素,也就是  文件的后缀名
    end_name = img_file.filename.rsplit('.')[-1]

    # 通过文件的后缀名判断 身份为 合法的  图片
    if end_name not in ['jpg', 'png', 'gif', 'jpeg']:
        return jsonify({"code":-1,"msg":"请上传正确的图片文件!","src":""})

    filename = str(uuid1()) + '.' + end_name  # 为了生成一个不重复的文件名

    img_path = app.root_path + "/static/images/food/" + filename   # 将路径和文件名拼接在一起,方便保存文件

    img_file.save(img_path)  # 将图片对象保存到本地

    return jsonify({"code": 200, "msg": "上传成功!", "src": "/static/images/food/" + filename})


@route_food.route("/delete-pic", methods=["POST"])
def deletePic():
    img_path = request.form.get("img_path", None)

    if img_path is None:
        return jsonify({"code": -1, "msg": "删除失败!"})

    root_img_path = app.root_path + img_path
    try:
        os.remove(root_img_path)
    except:
        return jsonify({"code": -1, "msg": "删除失败!"})

    return jsonify({"code": 200, "msg":"删除成功!"})

🍓项目数据库迁移操作与项目启动操作

1.数据库迁移操作
在项目根目录EatProject的终端下依次运行下列指令:

python manage.py db init
python manage.py db migrate 
python manage.py db upgrade 

依次执行这三条语句后,会在你的数据库中生成项目所需的数据库表。

2.数据库启动操作
在项目根目录EatProject的终端下使用以下指令启动项目:

 python manage.py runserver

🍓源码获取

项目已经上传到gitee,地址在这:
👉https://gitee.com/aniu-666/eat-project
欢迎各位来star!

🍎结语

如果你觉得博主写的还不错的话,可以关注一下当前专栏,博主会更完这个系列的哦!也欢迎订阅博主的其他好的专栏。

🏰系列专栏
👉flask框架快速入门
👉java 小白到高手的蜕变

其他专栏请前往博主主页查看!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/389562.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[1.3.3]计算机系统概述——系统调用

文章目录第一章 计算机系统概述系统调用&#xff08;一&#xff09;什么是系统调用&#xff0c;有何作用&#xff08;二&#xff09;系统调用与库函数的区别&#xff08;三&#xff09;小例子&#xff1a;为什么系统调用是必须的&#xff08;四&#xff09;什么功能要用到系统调…

English Learning - L2-4 英音地道语音语调 双元音 [eɪ] [aɪ] [aʊ] [əʊ] [ɔɪ] 2023.03.2 周四

English Learning - L2-4 英音地道语音语调 双元音 [eɪ] [aɪ] [aʊ] [əʊ] [ɔɪ] 2023.03.2 周四节奏发音对比双元音概述双元音 [eɪ]发音技巧对应单词的发音对应句子的发音双元音 [aɪ]发音技巧对应单词的发音对应句子的发音双元音 [aʊ]发音技巧对应单词的发音对应句子的…

Android kotlin 系列讲解(进阶篇)高级项目架构模式 - MVVM

<<返回总目录 1、MVVM是什么 MVVM是Model-View-ViewModel的缩写&#xff0c;是一种高级项目架构模式。 MVVM架构可以将程序结构主要分成三个部分&#xff1a; Model&#xff1a;数据模型部分&#xff0c;包括从服务端获取的json数据或者从本地获取的数据等等View&…

【GlobalMapper精品教程】056:图像融合(高光谱+全色)操作案例教程

本文讲解GlobalMapperV24.0汉化版图像增强:融合(高光谱+全色)操作案例教程 文章目录 一、图像融合概述二、图像融合案例1. 加载数据2. 图像融合3. 图像导出一、图像融合概述 图像融合是指将不同类型传感器的影像进行融合,既能使图向具有较高的空间分辨率,又具有多光谱的特…

工具篇(五)炫酷排版,尽在LaTeX:让你的文档飞升吧!

作者的话 作为一个文本排版工具&#xff0c;latex一直以来都备受科研工作者、学生和出版社的青睐。但是对于初学者来说&#xff0c;latex的学习曲线可能会有些陡峭。因此&#xff0c;我写这篇博客旨在为初学者提供一个简单易懂的latex教程&#xff0c;让大家能够快速入门并掌握…

C++—输入输出流

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言1. 输入输出流2. 文件的输入输出2.1 写文件2.2 读文件前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 我的电脑为什么从 C 盘开始&#…

Compose 动画 (三) : AnimatedVisibility 从入门到深入

1. AnimatedVisibility 是什么 AnimatedVisibility可以实现Compose组件的显示和隐藏&#xff0c;并且可以指定显示/隐藏时候的动画效果。(EnterTransition/ExitTransition) 和 animateXxxAsState、animateContentSize、Crossfade、AnimatedContent 这几个API一起&#xff0c;都…

一文详解像素、DPI、分辨率之间的关系

像素像素&#xff1a;是指在由一个数字序列表示的图像中的一个最小单位&#xff0c;称为像素。像素可以用一个数表示&#xff0c;比如一个“0.3兆像素”数码相机&#xff0c;它有额定30万像素&#xff1b;也可以用一对数字表示&#xff0c;例如“640x480显示器”&#xff0c;它…

单目标追踪——【相关滤波】C-COT原理与ECO基于C-COT的改进

目录C-COT&#xff1a;Continuous Convolution Operator Tracker文章侧重点连续卷积算子目标追踪框架初始化过滤器&#xff1a;追踪流程ECO文章侧重点因式卷积因子生成采样空间模型模型更新策略论文链接&#xff1a;C-COT&#xff1a;Beyond Correlation Filters: Learning Con…

【MySQL】表连接

一、为什么要学习 因为不合理的使用连接会导致慢查询 二、什么是连接 参与连接的表叫做 连接表&#xff0c; 连接就是把 各个连接表 进行的组合 &#xff08;笛卡儿积&#xff09;加入结果集并返回 三、连接查询 如何只是对表进行大量的连接&#xff0c;笛卡儿积作用得到的…

ChatGPT会取代程序员么?今天让ChatGPT写了个程序,感觉离失业不远了

文章目录ChatGPT会取代程序员么&#xff1f;今天让ChatGPT写了个程序&#xff0c;感觉离失业不远了问题&#xff1a;保存和ChatGPT的聊天记录对话实录以及吐槽1. 把当前页面转成markdown格式的方法2. 用油猴子可以实现么&#xff1f;3. 编写一段油猴子代码&#xff0c;实现刚才…

Redis十大类型——Set与Zset常见操作

Redis十大类型——Set与Zset常见操作Set命令操作简列基本操作展示删除移动剪切集合运算Zset基本操作简列添加展示反转按分数取值获取分数值删除分数操作下标操作如果我们对Java有所了解&#xff0c;相信大家很容易就明白Set&#xff0c;在Redis中也一样&#xff0c;Set的value值…

4、树(中篇)

前言:前节二叉树只能适用于静态查找,不能实现动态插入、删除等。如何解决以下两个问题: 静态查找与动态查找针对动态查找,数据如何组织?4.1 二叉搜索树 4.1.1 什么是二叉搜索树 二叉搜索树(BST,Binary Search Tree),也称二叉排序树或二叉查找树。 二叉搜索树:一棵…

Linux RS232驱动实验

目录 一、硬件分析 1、 RS232 原理图​编辑 2、RS485 原理图 3、GPS 原理图 二、设备树中添加设备节点 2、添加 uart3 节点 ​编辑 三、移植 minicom 1、移植 ncurses 2、移植 minicom 3、验证 4、minicom配置 四、测试 RS232 收发测试 串口是很常用的一个外设&…

SpringSecurity: 默认添加的15个Filter是怎么添加进去的?

总的流程分为两部分&#xff0c;一是先用Map把configurer收集起来&#xff0c;然后再把maper中所有的configurer应用到HttpSecurity对象。 其中的map位于AbstractConfiguredSecurityBuilder这个类。 private final LinkedHashMap<Class<? extends SecurityConfigurer&l…

信息安全与数学基础-笔记-⑤原根与阶

知识目录原根一些求原根的定理↓ordm(a)ord_m(a)ordm​(a) | ϕ(m)\phi(m)ϕ(m)原根和阶的关系原根 什么是原根&#xff1f; 设 &#xff08;a,m&#xff09; 1, 并且aea^eae 三 1 (mod m) &#xff0c;则我们称&#xff1a;ordmord_mordm​(a) e&#xff0c;ord也叫做群论&am…

React组件性能优化若干问题

react组件的性能优化的核心是减少渲染真实DOM节点的频率&#xff0c;减少Virtual DOM比对的频率。组件卸载前执行清理操作在组件中为window 注册的全局事件&#xff0c;以及定时器&#xff0c;在组件卸载前要清理掉。防止组件卸载后继续执行影响应用性能。import React from re…

分享十个前端Web3D可视化框架附地址

Three.js&#xff1a;Three.js是一个流行的3D库&#xff0c;提供了大量的3D功能&#xff0c;包括基本几何形状、材质、灯光、动画、特效等。它是一个功能强大、易于使用的框架&#xff0c;广泛用于Web3D可视化应用程序的开发。Three.js&#xff1a;https://threejs.org/Babylon…

【强烈建议收藏:MySQL面试必问系列之索引专题】

一.知识回顾 前面的文章我们一起学习了数据库的事务、事务以及并发来的问题、数据库锁机制、数据库中CURD的SQL语句底层执行流程、数据库SQL优化专题&#xff0c;如果你一步一步的跟下来&#xff0c;一定会帮助你建立一个知识体系。接下来我们再一起学习数据库索引专题&#x…

Toponogov 比较定理及其应用

1. Toponogov 比较定理的背景来源 Victor Andreevich Toponogov&#xff08;1930-2004&#xff09; 是苏联数学家&#xff0c;Toponogov 比较定理是他的博士论文题目&#xff0c;在1958年答辩。他证明这个定理是为了用于证明截面曲率假设下的分裂定理和最大直径定理&#xff0…