博客目录:
......
十一、基于Django+mysql的点餐系统设计-第十一篇(H5手机移动端点餐:购物车操作)
十二、基于Django+mysql点餐系统设计-第十二篇(移动端:会员下单处理)
十三、基于Django+mysql的点餐系统设计-第十三篇(H5点餐:订单的展示)
十四、基于Django+mysql的点餐系统设计-第十四篇(大堂点餐:需求分析和代码逻辑实现梳理、首页展示)
本章源码下载地址:https://github.com/hopeSuceess/testorder/tree/testorder_20220707
从今天开始写大堂点餐模块,大堂点餐和后台员工管理、H5手机移动端点餐一样,贯彻始终的是增删改查。现在分析下大堂点餐模块的需求:1、首先,店员访问系统需要输入账号密码;2、店员或其他人访问系统非登录页面链接,若缓存中没有检测到用户信息,将页面跳转到登录页面;3、大堂点餐页面展示菜品的详情(菜品名称、菜品价格、菜品图片),点击某一餐品可添加到购物车;4、购物车展示在大堂点餐左上角一块区域,可对点过的餐品进行增加、减少、删除和下单;5、下单之后可在"当前订单"、“历史订单”、“无效订单”中查看对应订单;6、店员可退出系统,退出系统后跳转到登录页面。
分析下上面的需求:
1、店员访问系统需要输入账号密码,这里就用到了查询功能,拿着店员输入的账号、密码与数据库去做比对,如果比对正确就跳转到菜品展示页面,不正确就在登录页面校验提示
2、解决需求点二的方法和后台员工管理、H5手机移动端点餐一样,引入登录中间件,判断用户信息的缓存。如果用户首先访问了非登录页面,首先经过中间件校验:如果用户信息在缓存中,放行;在缓存中找不到用户信息,跳转到登陆页面。
3、菜品信息的展示也非常简单,后端直接读取表数据,然后将数据打包渲染到前端,前端再将后端传过来的数据遍历展现到页面。
4、购物车是大堂点餐的重点,当用户点击某一菜品,将菜品id传输到购物车,购物车后端遍历菜品详细信息,通过ajax展现到前端页面。此外,运用购物车上的功能对菜品进行增、减和价格计算,可通过前端代码进行完成。下单的功能是将页面缓存留存的餐品信息插入到支付表、订单表、订单详情表。
5、购物车下单之后,支付表、订单表、订单详情表有了数据,"当前订单"、"历史订单"、"无效订单"通过调用数据库中的数据展示到前端,另外,“当前订单”设置"已完成"、"失效"等按钮,点击后,订单会跳转到"历史订单"、"无效订单"中展示。按钮用到的知识点就一个:针对某一个订单点击按钮,后端获取该订单id后,将该id的状态改为已完成或失效。
6、店员退出系统,后端写代码后简单,直接删除店员的缓存信息就可以。
大堂点餐模块的需求和代码实现逻辑说完了,现在开始板砖搞具体实现了。首先呢,将大堂点餐首页的框架搭起来。此刻,各位想一下怎么实现?哈哈,是不是很简单,框架就是路由控制器和MTV。先看路由控制器,稍微回忆一下:testorder/urls.py下的path('',include('web.urls')), 指的是路径不带任何短链接会跳转到web.urls下寻找匹配的路由;web/urls.py下编写路由path('',index.index, name="index"),指的是路径继续不带短链接,会跳转到index函数下进行逻辑处理,index函数将数据渲染到前端页面,最终在用户页面展示内容。
这次的大堂点餐也按照这个逻辑编写,在web/urls.py定义一个路由
path('web', index.webIndex, name="web_index"), #前台大堂点餐首页
访问路由,会跳转到webIndex函数。在web/views/index.py中编写webIndex函数。这里回忆一下,会员移动端首页是展示某一个店铺的餐品信息,如果没有店铺信息,需要去切换店铺功能模块选择店铺,所以店铺信息的展示处理写到了index函数。但是大堂会员点餐模块在店员登录的时候,需要店员选择店铺,输入账号、密码后才能正常登录到大堂点餐首页,因此将大堂点餐的首页展示信息写到店员登录校验成功后的阶段。好了,这次webIndex函数就没有那么多逻辑要写了,直接承担起渲染跳转的作用就可以了
def webIndex(request):
'''项目前台大堂点餐首页'''
return render(request, "web/index.html")
view层很简单,不代表template层逻辑简单。在templates/web/index.html中可以规划下页眉和购物车
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>点餐系统</title>
<link rel="stylesheet" href="{% static 'web/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'web/css/common.css' %}">
<style type="text/css">
body{min-height:2000px;padding-top:70px;}
.navbar-default{background-color:#ff8800;border-color:#e7e7e7;}
.navbar-default .navbar-brand{color:#fff;}
.navbar-default .navbar-nav > li > a,.navbar-default .navbar-nav > li > a:visited {
color: #fff;
width:100px;
font-size:14px;
text-align:center;
}
.navbar-default .navbar-nav > .active > a,.navbar-default .navbar-nav > .active > a:visited,.navbar-default .navbar-nav li a:hover,.navbar-default .navbar-nav > .active > a:hover,.navbar-default .navbar-nav li a:active {
color:#fff;
background-color: #FF4500;
width:100px;
font-size:14px;
text-align:center;
}
table tr td{font-size:11px;}
table tr td.price{color:red;}
table tr td.num span{color:red;padding:0px 5px}
table tr td.num i{border-width:0px;background-color:#ddd;}
div.shoplist div.bn{font-size:12px;line-height:25px;}
div.shoplist div.bn span.price{color:red;}
</style>
</head>
<body>
<!-- 页头导航开始 -->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">
<span class="glyphicon glyphicon-cutlery" aria-hidden="true"></span> <span style="font-weight:bold;">田老师红烧肉</span><span style="font-size:14px;">(朝阳将台路店)</span></a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="">堂吃点餐</a></li>
<li><a href="">当前订单</a></li>
<li><a href="">历史订单</a></li>
<li><a href="">无效订单</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="../navbar/">
<span class="glyphicon glyphicon-user" aria-hidden="true"> {{request.session.webuser.nickname}}</a></li>
<li><a href="{% url 'web_delweb' %}">退出</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<!-- 页头导航结束 -->
<!-- 页面主体开始 -->
<div class="container">
<div class="col-md-4">
<div class="panel panel-warning">
<div class="panel-heading"><span class="glyphicon glyphicon-shopping-cart" aria-hidden="true"></span> 购 物 车</div>
<table class="table table-striped">
<tr>
<th width="30">序</th>
<th>菜品</th>
<th width="72">数量</th>
<th width="45">单价</th>
<th>删除</th>
</tr>
{% for product in request.session.cartlist.values %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ product.name }}</td>
<td class="num"><i onclick="window.location=''" class="btn btn-default btn-xs"> - </i>
<span>{{product.num}}</span><i onclick="window.location=''" class="btn btn-default btn-xs"> + </i></td>
<td class="price">{{ product.price }}</td>
<td><a href="" class="btn btn-danger btn-xs" role="button">删除</a></td>
</tr>
{% endfor %}
</table>
<li class="list-group-item">
<b>购买方式: </b>
<input type="radio" name="ptype" checked value="1"> 堂吃
<input type="radio" name="ptype" value="2"> 打包
</li>
<li class="list-group-item">
<b>支付方式: </b>
<input type="radio" name="bank" checked value="1"> 现金
<input type="radio" name="bank" value="2"> 支付宝
<input type="radio" name="bank" value="3"> 微信
</li>
<div class="panel-footer" style="height:50px">
<div style="width:120px;float:left;margin:5px 0px;">合计:¥<span style="color:red;font-weight:bold;">{{ request.session.total_money }}</span> 元</div>
<button type="submit" onclick="dosubmit()" class="btn btn-warning" style="width:130px;float:right">结 算</button>
<button type="button" onclick="window.location=''" class="btn btn-danger" style="width: 60px;float: right">清空</button>
</div>
</div>
</div>
</div>
<!-- 页面主体结束 -->
<script src="{% static 'web/js/jquery.min.js' %}"></script>
<script src="{% static 'web/js/bootstrap.min.js' %}"></script>
<script>
//执行订单处理(下订单)
function dosubmit(){
//判断购物车中是否没有菜品
if($("table.table-striped tr").length == 1){
alert("购物车中没有菜品选择!");
return;
}
//询问是否提交订单
if(!window.confirm("确定要进行结算吗?")){
return;
}
//获取要提交的数据
var ptype = $("input[name='ptype']:checked").val();
var bank = $("input[name='bank']:checked").val();
//执行ajax提交订单
$.ajax({
type:"get",
url:"",
dataType:"text",
data:{ptype:ptype,bank:bank},
success:function(res){
if(res == "Y"){
alert("订单添加成功!");
window.location.href = "";
}else{
alert("订单处理失败!");
}
}
});
}
</script>
</body>
</html>
好了,现在启动工程,访问http://127.0.0.1:8000/web/,得到如下页面
搞定,下一篇讲一下压轴的功能之一:登录并完善大堂点餐首页。