草庐IT

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

馆主阿牛 2023-04-09 原文

📋 个人简介

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

目录

🍎前言

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 小白到高手的蜕变

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

有关基于flask+bootstrap+echarts+mysql的鱼村小馆订餐后台管理系统的更多相关文章

  1. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  2. ruby - 将 Bootstrap Less 添加到 Sinatra - 2

    我有一个ModularSinatra应用程序,我正在尝试将Bootstrap添加到应用程序中。get'/bootstrap/application.css'doless:"bootstrap/bootstrap"end我在views/bootstrap中有所有less文件,包括bootstrap.less。我收到这个错误:Less::ParseErrorat/bootstrap/application.css'reset.less'wasn'tfound.Bootstrap.less的第一行是://CSSReset@import"reset.less";我尝试了所有不同的路径格式,但它

  3. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  4. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  5. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  6. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  7. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  8. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  9. ruby - 如何在 ruby​​ 中运行后台线程? - 2

    我是ruby​​的新手,我认为重新构建一个我用C#编写的简单聊天程序是个好主意。我正在使用Ruby2.0.0MRI(Matz的Ruby实现)。问题是我想在服务器运行时为简单的服务器命令提供I/O。这是从示例中获取的服务器。我添加了使用gets()获取输入的命令方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程。require'socket'#Getsocketsfromstdlibserver=TCPServer.open(2000)#Sockettolistenonport2000defcommandsx=1whilex==1exitProgram=gets.chomp

  10. ruby - (Ruby || Python) 窗口管理器 - 2

    我想用这两种语言中的任何一种(最好是ruby​​)制作一个窗口管理器。老实说,除了我需要加载某种X模块外,我不知道从哪里开始。因此,如果有人有线索,如果您能指出正确的方向,那就太好了。谢谢 最佳答案 XCB,X的下一代API使用XML格式定义X协议(protocol),并使用脚本生成特定语言绑定(bind)。它在概念上与SWIG类似,只是它描述的不是CAPI,而是X协议(protocol)。目前,C和Python存在绑定(bind)。理论上,Ruby端口只是编写一个从XML协议(protocol)定义语言到Ruby的翻译器的问题。生

随机推荐