`## 摘要
订餐小程序后台管理系统,是为订餐小程序提供数据接口以及接收其请求数据进行整理和存储,为订餐小程序的功能正常运行提供必要的支持。
在设计本系统之前,通过面向对象分析以及采用UML的工具进行需求分析确定该系统的具体需求,要实现的功能。本系统采用了基于python的flask框架以及MySQL数据库进行设计和开发.
论文主要描述对订餐小程序后台开发系统的全过程。本系统实现了小程序会员管理和后台登陆者管理,菜品详细信息、菜品分类、购物车等功能模块。
关键词:订餐;管理;python;小程序
自2017年微信小程序正式上线,到了现在微信小程序已经形成完善的开发生态和平台,借助于微信平台深入到了人们生活中的各个方面。特别是在人们的衣食住行上。当我们走进餐馆,会发现越来越多的餐馆支持使用微信小程序订单以节省人工,提高效率。但是在使用过程会遇到这样的问题:客户量过大,单纯使用微信小程序提供的云开发功能进行数据的存储,效率极其低下且对数据进行操作不方便。面对这样的情况,设计一个负责处理微信订餐小程序的后台管理系统,有着可视化的操作界面,容量大的服务器,可扩展性高等优点。可以有效提高微信订餐小程序的性能,方便的管理用户数据,了解用户的情况,菜品的信息等。
在微信小程序已经深入人的生活中,人们对此习以为常时,越来越多的店铺会有需求定制自己的小程序。在餐饮行业,已经越来越多的餐馆开始使用小程序来辅助经营。如果单纯聘请人员来进行下单操作,当客流大爆发时,就会人员不够,但是要聘请更多的人也是不合理的,那样成本会大幅度上升。但是使用微信小程序的话,可以解放更多的劳动率,也不会出现记错之类的情况。
基于上面的情况,大概率会有越来越多的餐馆想要使用小程序进行订餐,那么这些小程序肯定需要后台系统的支持。那么我们研究微信订餐小程序后台管理系统,总结出通用的功能以及实现这些功能的逻辑,就能快速实现一个微信订餐小程序后台管理系统,之后就可以模板化,快速定制不同订餐小程序的后台管理系统,给订餐小程序提供高质量的数据处理服务。
本论文的主要组成部分:
内部接口主要是与后台系统有关,涉及到拦截器接口、首页接口、后台用用户管理接口,会员管理接口,菜品管理接口。各个接口的设计都遵循高内聚、低耦合的原则,采用面向对象的思想进行编写。
2.4.1 MySQL定义的二维表
表2.4.2 用户访问记录表
字段名称 类型 长度 主键 备注
id int 11 是
uid bigint 20 uid
referer_url varchar 255 当前访问的refer
target_url varchar 255 访问的url
query_params text 0 get和post参数
ua varchar 255 访问ua
ip varchar 32 访问ip
note varchar 1000 json格式备注字段
created_time timestamp 0
表2.4.2 app错误日表
字段名称 类型 长度 主键 备注
id int 11 是
referer_url varchar 255 当前访问的refer
target_url varchar 255 访问的url
query_params text 0 get和post参数
content longtext 0 日志内容
created_time timestamp 0 插入时间
表2.4.3 食品表
字段名称 类型 长度 主键 备注
id int 11 是
cat_id int 11 分类id
name varchar 100 书籍名称
price decimal 10 售卖金额
main_image varchar 100 主图
summary varchar 10000 描述
stock int 11 库存量
tags varchar 200 tag关键字,以","连接
status tinyint 1 状态 1:有效 0:无效
month_count int 11 月销售数量
total_count int 11 总销售量
view_count int 11 总浏览次数
comment_count int 11 总评论量
updated_time timestamp 0 最后更新时间
created_time timestamp 0 最后插入时间
表2.4.4 食品分类
字段名称 类型 长度 主键 备注
id int 11 是
name varchar 50 类别名称
weight tinyint 4 权重
status tinyint 1 状态 1:有效 0:无效
updated_time timestamp 0 最后一次更新时间
created_time timestamp 0 插入时间
表2.4.5商品销售情况
字段名称 类型 长度 主键 备注
id int 11 是
food_id int 11 商品id
quantity int 11 售卖数量
price decimal 10 售卖金额
member_id int 11 会员id
created_time timestamp 0 售卖时间
表2.4.6数据库存变更表
字段名称 类型 长度 主键 备注
id int 11 是
food_id int 11 商品id
unit int 11 变更多少
total_stock int 11 变更之后总量
note varchar 100 备注字段
created_time datetime 0 插入时间
表 2.4.7 图片表
字段名称 类型 长度 主键 备注
id int 11 是
file_key varchar 60 文件名
created_time timestamp 0 插入时间
表 2.4.8 会员表
字段名称 类型 长度 主键 备注
id int 11 是
nickname varchar 100 会员名
mobile varchar 11 会员手机号码
sex tinyint 1 性别 1:男 2:女
avatar varchar 200 会员头像
salt varchar 32 随机salt
reg_ip varchar 100 注册ip
status tinyint 1 状态 1:有效 0:无效
updated_time timestamp 0 最后一次更新时间
created_time timestamp 0 插入时间
表2.4.9会员收货地址
字段名称 类型 长度 主键 备注
id int 11 是
member_id int 11 会员id
nickname varchar 20 收货人姓名
mobile varchar 11 收货人手机号码
province_id int 11 省id
province_str varchar 50 省名称
city_id int 11 城市id
city_str varchar 50 市名称
area_id int 11 区域id
area_str varchar 50 区域名称
address varchar 100 详细地址
status tinyint 1 是否有效 1:有效 0:无效
is_default tinyint 1 默认地址
updated_time timestamp 0 最后一次更新时间
created_time timestamp 0 插入时间
表2.4.10购物车
字段名称 类型 长度 主键 备注
id int 11 是
member_id bigint 20 会员id
food_id int 11 商品id
quantity int 11 数量
updated_time timestamp 0 最后一次更新时间
created_time timestamp 0 插入时间
表2.4.11第三方登录绑定关系
字段名称 类型 长度 主键 备注
id int 11 是
member_id int 11 会员id
client_type varchar 20 客户端来源类型。qq,weibo,weixin
type tinyint 3 类型 type 1:wechat
openid varchar 80 第三方id
unionid varchar 100
extra text 0 额外字段
updated_time timestamp 0 最后更新时间
created_time timestamp 0 插入时间
表 2.4.12在线购买订单表
字段名称 类型 长度 主键 备注
id int 11 是
order_sn varchar 40 随机订单号
member_id bigint 11 会员id
total_price decimal 10 订单应付金额
yun_price decimal 10 运费金额
pay_price decimal 10 订单实付金额
pay_sn varchar 128 第三方流水号
prepay_id varchar 128 第三方预付id
note text 0 备注信息
status tinyint 4 1:支付完成 0 无效
-1 申请退款 -2 退款中
-9 退款成功 -8 待支付
-7 完成支付待确认
express_status tinyint 4 快递状态,-8 待支付
-7 已付款待发货 1:确认收货 0:失败
express_address_id int 11 快递地址id
express_info varchar 1000 快递信息
comment_status tinyint 1 评论状态
pay_time timestamp 0 付款到账时间
updated_time timestamp 0 最近一次更新时间
created_time timestamp 0 插入时间
表2.4.13订单详情表
字段名称 类型 长度 主键 备注
id int 11 是
pay_order_id int 11 订单id
member_id bigint 11 会员id
quantity int 11 购买数量 默认1份
price decimal 10 商品总价格,售价 * 数量
food_id int 11 美食表id
note text 0 备注信息
status tinyint 1 状态:1:成功 0 失败
updated_time timestamp 0 最近一次更新时间
created_time timestamp 0 插入时间
表2.4.14 用户表(管理员)
字段名称 类型 长度 主键 备注
uid bigint 20 是 用户uid
nickname varchar 100 用户名
mobile varchar 20 手机号码
email varchar 100 邮箱地址
sex tinyint 1 1:男 2:女 0:没填写
avatar varchar 64 头像
login_name varchar 20 登录用户名
login_pwd varchar 32 登录密码
login_salt varchar 32 登录密码的随机加密秘钥
status tinyint 1 1:有效 0:无效
updated_time timestamp 0 最后一次更新时间
created_time timestamp 0 插入时间
表2.4.15 微信分享记录
字段名称 类型 长度 主键 备注
id int 11 是
member_id int 11 会员id
share_url varchar 200 分享的页面url
created_time timestamp 0 创建时间
1、前端:
微信小程序。
2、后端:
Flask,是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 (后台管理系统的网页就是通过这个引擎进行渲染从而可以调用python中传递过来的变量)。
flask-sqlalchemy,通过这个扩展包链接数据库,并建立orm数据库。
mysqlclient,用于操作数据库的包,封装了基于python基本的mysql操作语句,可以
快捷的操作数据库。无需自己在python重复写数据的操作语句。
flask_script,提供了向python插入外部脚本的功能。简单来说,我用这个工具自定
义了运行本系统的命令,并且可以很方便的传入参数。
flask-sqlacodegen,为开发者提供了根据数据库表生成对应的model模型的命令,无
需开发者手动去对照数据库表写model。算是一个代码生成器。
requests,python的第三方库,可以快捷的调用url资源。这里主要用于请求微信生
成需要的信息。
1、系统环境
只要能使用浏览器即可。
2、运行环境
python 3.7.4
mysql 5.7.20
3、代码编辑器
pycharm
这里列出主要的功能实现步骤,一些逻辑类似的就不重复列举。
3.1 后台系统的启动
图 3.1.1 路由编写
3.2 通过flask中的引擎渲染html的操作
图3.2.1 拦截url
图3.2.2 设置网页静态资源的响应
图3.2.3设置 .html 文件可调用 python 方法返回需要的链接
图3.2.4 注入路由
图3.2.5 将方法注入网页模板使用,设置静态资源文件的目录
3.3 ajax 登陆
login.html 改成 form 表单提交,button
图3.3.1
User.py 展现登陆页面和登陆判断,若密码和用户名正确,将返回一个特定的cookie给用户并跳转到首页
图3.3.4
AuthInterceptor.py 拦截器。确保了我们访问的除了登录页以外的页面都需要有我们是登陆了的(通过cookies进行判断)
图3.3.6
图3.3.8
3.4 用户首页信息的展示
AuthInterceptor.py 配置全局变量,flask 自带在对用户进行验证成功后,将用户信息存入到全局变量中
图3.4.1
index.py,将用户信息respons 给网页
图3.4.2
layout_main.html 调用返回 current_user 对象
图3.4.3
可以了解到,layout_main.html 和 其他页面都需要 render_template 进行渲染,就可以考虑对 render_template 进行封装,将 current_user 弄进去,无需每个页面都手动去写
图3.4.4
3.5 账号管理
3.5.1 搜索与首页展示功能
index.js 定义了对应的js操作,用于请求
图3.5.1.1
web\templates\account\index.html 使用了后台传递过来的变量
图3.5.1.2
Account.py 获取传过来的用于搜索的内容
3.5.2 删除与恢复
web\templates\account\index.html
根据后台传递的数据,动态显示删除或恢复
图3.5.2.1
web\static\js\account\index.js
绑定删除和恢复事件
图3.5.2.2
图3.5.2.3
web\controllers\account\Account.py
定义处理请求的后台方法:
图3.5.2.4
3.6通过版本号及时更新静态资源
common\libs\UrlManager.py
图3.6.1
因为 ver 参数变了,而服务器相应给客户端的 url 的 ver 参数跟客户端旧的 url 就不同了,那么浏览器会重新根据最新的 url 去请求新的资源
示例:
图3.6.2
3.7登陆者的访问记录
在创建好 app_access_log 和 app_error_log 两个数据库表后:
在工程目录中,新建 log 文件夹
图 3.7.1
输入如下命令,创建对应的 model 类
flask-sqlacodegen “mysql://root:[email protected]/food_db” --tables app_access_log --outfile “common/models/log/AppAccessLog.py” --flask
flask-sqlacodegen “mysql://root:[email protected]/food_db” --tables app_error_log --outfile “common/models/log/AppErrorLog.py” --flask
图 3.7.2
3.8 错误拦截器
web\interceptor\ErrorInterceptor.py
对错误进行统一处理,并将错误插入到数据库中
图3.8.1
3.9 小程序端登陆功能
3.9.1 获取登陆用户信息
需要一个特定类型的授权按钮:
index.wxml
图3.9.1.1
index.js 写获取登陆用户信息的方法,并将信息发送给后台
图3.9.1.2
web\controllers\api_init_.py
定义用于接收小程序的路由管理:
图3.9.1.3
web\controllers\api\Member.py 小程序会员路由
图3.9.1.4
3.9.2 判断用户是否登陆,使用 openid
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
具体操作还是要看最新文档
第一步:小程序项目 index.js 将获取 临时凭证code, 并回传到开发者服务器
图3.9.2.1
第二步:后台根据小程序回传的 code 调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 和 会话密钥 session_key。
之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。
https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
请求前,先去登陆自己的小程序开发与管理平台,获取 AppID 和 AppSecret
图3.9.2.2
使用命令在项目生成对应model,注意修改 生成文件的 db 是用 自定义的 application 的
flask-sqlacodegen “mysql://root:[email protected]/food_db” --tables member --outfile “common/models/member/Member.py” --flask
flask-sqlacodegen “mysql://root:[email protected]/food_db” --tables oauth_member_bind --outfile “common/models/member/OauthMemberB
ind.py” --flask
web\controllers\api\Member.py 登陆路由详细代码
图3.9.2.5
图3.9.2.7
用户已登录就不重复授权,减少不必要的网络请求,提升响应速度
图3.9.2.8
图3.9.2.9
3.10 小程序菜品分类
使用下面的命令,生成对应的model 文件:
flask-sqlacodegen “mysql://root:[email protected]/food_db” --tables food --outfile “common/models/food/Food.py” --flask
flask-sqlacodegen “mysql://root:[email protected]/food_db” --tables food_cat --outfile “common/models/food/FoodCat.py” --flask
flask-sqlacodegen “mysql://root:[email protected]/food_db” --tables food_sale_change_log --outfile “common/models/food/FoodSaleChangeLog.py” --flask
flask-sqlacodegen “mysql://root:[email protected]/food_db” --tables food_stock_change_log --outfile “common/models/food/FoodStockChangeLog.py” --flask
web\templates\food\cat_set.html 添加和修改的网页文件
图3.10.1
图3.10.2
web\static\js\food\cat_set.js 处理 对应的网页事件
图3.10.3
web\controllers\food\Food.py 处理前端请求的路由
index() 处理首页的请求,显示首页的内容,info() 显示详细内容
图3.10.4
图3.10.5
set() 处理菜品信息的编辑
图3.10.6
图3.10.7
图3.10.8
cat() 菜品信息的展示, catSet() 菜品信息的修改
图3.10.9
图3.10.10
ops() 添加删除美食
图3.10.12
图3.10.13
3.11 小程序首页信息
定义两个路由,用于展示首页信息和进行搜索的功能
图 3.11.1
web\controllers\api_init_.py 将代码加载,以便注册路由
图 3.11.2
mini\pages\food\index.js
图 3.11.4
对应事件:
mini\pages\food\index.js
图 3.11.6
图 3.11.7
对应的搜索路由,后台:
web\controllers\api\Food.py
图 3.11.8
3.12 后台对添加购物车的记录
mini\pages\food\info.js
写加入购物车触发的事件
先创建关于数据库的表,然后生成对应 model
图3.12.2
web\controllers\api\Cart.py 写处理微信购物车的请求
图3.12.3
common\libs\member\CartService.py
封装购物信息的保存过程
图3.12.4
web\controllers\api_init_.py
将上面的路由在这里导入,才能注册
3.13 返回购物车的信息
web\controllers\api\Food.py
foodInfo 方法中添加处理
图 3.13.1
3.14 返回购物车页面的信息
mini\pages\cart\index.js 发送请求:
onShow 方法调用了这个方法,页面一显示就调用
图3.14.1
web\controllers\api\Cart.py 处理上面请求的方法
图3.14.2
是否显示无购物的页面:
mini\pages\cart\index.wxml
对组件进行判断
图3.14.3
3.15 订单请求的处理
先从后台获取,用户加入了购物车的信息:
mini\pages\order\index.js
首先:
页面加载时,就要添加数据
图3.15.1
然后,时请求后台的方法:
图3.15.2
后台处理请求
web\controllers\api\Order.py
图3.15.4
3.16 我的页面信息展示
web\controllers\api\Member.py 向小程序响应首页需要的数据
图 3.16.1
4.5 账户管理
图 4.5
4.6 账号设置
图4.6
4.7 账号信息
图 4.7
4.10美食信息
图 4.10
4.11 美食分类
图 4.11
4.17 我的页面
图 4.17
5.1 总结
这次系统的实现对我来说是一个挑战,刚学完python的基础语法,就边学边做这个系统,由学习基础知识到实现可用的作品。这是对所学知识的一次交代。在实现这个系统的过程中,对所学的python知识有了更深一步的了解。自己所涉及到的知识不过是冰山一角。尽管学习的还不够深入,但也有所收获,学会了更好的规划整个项目,如何将面向对象的思想在项目中实现,对重用性高的代码如何进行合理的封装,如何快速学习新知识,实现项目中如何平衡学习知识会拖慢进度和快速完成项目提高进度(就是合理的取舍)。
5.2 不足之处
在实现这个项目之前,做了一个总的规划,目前来说只能算是完成了三分之二。高估了自己目前的能力。主要是在支付模块这里,缺少必要的知识和条件,因为需要商户凭证才能弄到对应的支付二维码。所以这一部分只能留空了。