[项目构建 十二]babasport 订单的处理原理及代码实现.

上一篇博文我们已经介绍了购物车的原理及实现, 那么购物车再往后就是提交订单了, 订单的实现方式是怎么样的呢? 那么下面就让我们来一起学习下.

提交订单有几个关键点: 
1, 用户必须登录
2, 购物车必须要有购物项
3, 购物车中购物项库存必须小于库存
4, 结算成功, 清理购物车(这个只清理购物车中已经结算的购物项)

接下来我们再来看下订单相关的两张表的设计:
订单表

订单详情表

在这里我们可以发现 订单表和 我们的购物车很像, 订单详情表和我们的购物车中的购物项很像. 明白了这些原理后我们就来看下代码的具体实现.

我们来先写Service层的方法: CartServiceImpl.java

 1 @Autowired
 2     private OrderDao orderDao;
 3     @Autowired
 4     private DetailDao detailDao;
 5     //保存订单
 6     public void insertOrder(Order order, String username){
 7         //订单ID
 8         Long id = jedis.incr("oid");
 9         order.setId(id);
10         //用户id
11         String buyerId = jedis.get(username);
12         order.setBuyerId(Long.parseLong(buyerId));
13         BuyerCart buyerCart = selectBuyerCartFromRedis(username);
14         List<BuyerItem> items = buyerCart.getItems();
15         for (BuyerItem item : items) {
16             item.setSku(selectSkuById(item.getSku().getId()));
17         }
18         //运费, 由运费提供
19         order.setDeliverFee(buyerCart.getFee());
20         //订单总金额, 由购物车提供
21         order.setTotalPrice(buyerCart.getTotalPrice());
22         //订单金额, 由购物车提供
23         order.setOrderPrice(buyerCart.getProductPrice());
24         //支付状态: 0到付  1待付款  2已付款  3待退款  4退款成功  5退款失败
25         if (order.getPaymentWay() == 1) {
26             order.setIsPaiy(0);
27         }else {
28             //我们这里页面上只有 两种选择: 0到付   1待付款
29             order.setIsPaiy(1);
30         }
31         //订单状态: 0提交订单  1仓库配货  2商品出库  3等待收货  4完成   5待退货  6已退货
32         order.setOrderState(0);
33         //订单生成时间
34         order.setCreateDate(new Date());
35         //生成订单
36         orderDao.insertSelective(order);
37
38         //保存订单详情
39         for (BuyerItem item : items) {
40             Detail detail = new Detail();
41             //订单详情表
42             /*
43              * ID:自增长
44              * 订单ID, 商品编号ID, 商品名称, 颜色中文名称, 尺码, 价格, 数量, 购物车中购物项提交数量
45              */
46             detail.setOrderId(id);
47             detail.setProductId(item.getSku().getProductId());
48             detail.setProductName(item.getSku().getProduct().getName());
49             detail.setColor(item.getSku().getColor().getName());
50             detail.setSize(item.getSku().getSize());
51             detail.setPrice(item.getSku().getPrice());
52             detail.setAmount(item.getAmount());
53
54             //保存购物车中购物项
55             detailDao.insertSelective(detail);
56
57             //减库存
58
59             //清空购物车, 这里只写全部删除的方法, 如果删除某个购物项需使用jedis.hdel();
60             jedis.del("buyerCart:" + username);
61         }
62     }

这里 是利用Redis生成主键ID, 我们前面也有对比过Redis生成主键和数据库生成主键 以及UUID的对比, 这里就不再细说了. 
剩下的就是取购物车, 在这里我们可以通过username去取出skuId和购买数量amount, 因为我们在Redis存储的表名就是"buyerCart:"+username就是key是:skuId , value是amount.
剩下的就是将购物车中的内容装配到Order中即可.

接着来看下 Controller层的代码: CartController.java:

 1 //去结算
 2     @RequestMapping(value="/buyer/trueBuy")
 3     public String trueBuy(String[] skuIds, Model model, HttpServletRequest request, HttpServletResponse response){
 4         //1, 购物车必须有商品,
 5         //取出用户名  再取出购物车
 6         String username = sessionProviderService.getAttributterForUsername(RequestUtils.getCSessionId(request, response));
 7         //取出所有购物车
 8         BuyerCart buyerCart = cartService.selectBuyerCartFromRedisBySkuIds(skuIds, username);
 9         List<BuyerItem> items = buyerCart.getItems();
10         if (items.size() > 0) {
11             //购物车中有商品
12             //判断所勾选的商品是否都有货, 如果有一件无货, 那么就刷新页面.
13             Boolean flag = true;
14             //2, 购物车中商品必须有库存 且购买大于库存数量时视为无货. 提示: 购物车原页面不动. 有货改为无货, 加红提醒.
15             for (BuyerItem buyerItem : items) {
16                 //装满购物车的购物项, 当前购物项只有skuId这一个东西, 我们还需要购物项的数量去判断是否有货
17                 buyerItem.setSku(cartService.selectSkuById(buyerItem.getSku().getId()));
18                 //校验库存
19                 if (buyerItem.getAmount() > buyerItem.getSku().getStock()) {
20                     //无货
21                     buyerItem.setIsHave(false);
22                     flag = false;
23                 }
24                 if (!flag) {
25                     //无货, 原页面不动, 有货改成无货, 刷新页面.
26                     model.addAttribute("buyerCart", buyerCart);
27                     return "cart";
28                 }
29             }
30         }else {
31             //购物车没有商品
32             //没有商品: 1>原购物车页面刷新(购物车页面提示没有商品)
33             return "redirect:/shopping/toCart";
34         }
35
36
37         //3, 正常进入下一个页面
38         return "order";
39     }
40
41
42     //提交订单
43     @RequestMapping(value="/buyer/submitOrder")
44     public String submitOrder(Order order, HttpServletRequest request, HttpServletResponse response){
45         String username = sessionProviderService.getAttributterForUsername(RequestUtils.getCSessionId(request, response));
46
47         //保存订单
48         cartService.insertOrder(order, username);
49
50         return "success";
51     }

上一篇 关于购物车的博文我们已经讲过, 对于"/buyer/"这样格式的请求我们的springmvc都会拦截, 拦截的形式 就是判断用户是否登录. 这里我们也不会详细说明.
这里要判断购物项中的数量是否大于库存, 如果大于库存就刷新购物车页面, 且显示该购物项无货状态.
剩下的提交订单  就是保存order到订单表, 这里面也包含保存购物详情到订单详情表.

整体来说订单这一环节还是挺简单的, 这里需注意的是订单表和订单详情表的设计. 但是上面的code做的也有很多不完善的地方, 比如说减库存和 清除购物车的选项. 当然这只是一个练习的项目, 整个项目做到这里也就 完结了, 后期我会将代码以及所有资料都上传到 网上供大家使用, 当然资料里还包含12天的讲解视频.  希望大家能在闲暇之余 一起来学习下.

内容大概就是这么多, 感谢阅读本系列和回复的园友们.

时间: 2024-08-26 08:49:45

[项目构建 十二]babasport 订单的处理原理及代码实现.的相关文章

[项目构建 十五]babasport 项目总结及源码分享.

终于把这个项目自己手动的敲了一遍且总结了其中的知识点, 现在来做一个整体性的总结. 总目录: [项目构建 一]babasport 项目环境搭建. [项目构建 二]babasport SSM 三大框架整合 [项目构建 三]babasport Dubbo的使用及浅析. [项目构建 四]babasport 分页的使用及解析. [项目构建 五]babasport ajax图片上传及FastDFS入门案例. [项目构建 六]babasport Mybatis逆向工程构建项目实例. [项目构建 六]baba

[项目构建 十四]babasport Mycat配置及使用详解.

首先我们来看下什么是Mycat:MyCat:开源分布式数据库中间件, 这里定义的很简单, 就是分布式数据库的中间件. 其实Mycat 是可以时mysql进行集群的中间件, 我们可以对mysql来分库分表 来应对日益增长的数据量. 每台机器只存少量数据, 数据总和是分布式的机器上数据量总和. 例如我们一个表中有512条数据(当然实际情况可能有成千上万条数据), 那么现在我们有三台机器装有mysql数据库, 我们想将这些数据按照一定规则的存储在三台机器上, 那么我们设定规则: 表的id%/512 取

马哥学习笔记二十二——高可用集群原理

HA Resource:资源 FailOver:故障转移 FailBack:故障转回 资源粘性:资源是否倾向于留在当前节点 Messaging Layer:集群服务信息层,基于UDP互相传递心跳信息,集群事务信息等 heartbeat(v1,v2,v3) heartbeat v3:heartbeat,pacemaker,cluster-glue corosync cman keepalived ultramonkey CRM:(cluster resource manager)集群资源管理器,统

[项目构建 十]babasport 集群下session共享问题的解决方案.

这一篇博客来讲解下babasport这个项目中使用的Login功能, 当然这里说的只是其中的一些简单的部分, 记录在此 方便以后查阅. 一: 去登录页面首先我们登录需要注意的事项是, 当用户点击登录按钮时,转入登录页面时也要记住之前用户是从哪个页面发送请求过来的, 这样登录成功后还能继续跳回到用户之前浏览的那个页面.我们页面展示显示的登录按钮都是集成在一个common的jsp中, 前台每个页面都是引用的这个jsp, 所以需要在这个common的jsp中直接添加点击登录按钮跳转的页面.这里点击登录

SpringBoot实战项目(十二)--用户批量删除功能实现

页面构建--批量删除功能事件实现 1 <!DOCTYPE html> 2 <html class="x-admin-sm" xmlns:th="http://www.thymeleaf.org"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>欢迎页面-X-admin2.2</title> 6 <header th:replace

Linux netfilter 学习笔记 之十二 ip层netfilter的NAT模块代码分析

本节主要是分析NAT模块相关的hook函数与target函数,主要是理清NAT模块实现的原理等. 1.NAT相关的hook函数分析 NAT模块主要是在NF_IP_PREROUTING.NF_IP_POSTROUTING.NF_IP_LOCAL_OUT.NF_IP_LOCAL_IN四个节点上进行NAT操作,在上一节中我们知道nat表中只有PREROUTING.POSTROUTING.LOCAL_OUT三条链,而没有NF_IP_LOCAL_IN链,所以不能创建在LOCAL_IN hook点的SNAT

第二十二篇:在SOUI中使用代码向窗口中插入子窗口

使用SOUI开发客户端UI程序,通常也推荐使用XML代码来创建窗口,这样创建的窗口使用方便,当窗口大小改变时,内部的子窗口也更容易协同变化. 但是最近不断有网友咨询如何使用代码来创建SOUI子窗口,特此在这里统一解答. 要回答这个问题,首先要了解SOUI窗口创建及布局的流程. 先从swnd.cpp里抄一段创建子窗口的代码: 1 BOOL SWindow::CreateChildren(pugi::xml_node xmlNode) 2 { 3 TestMainThread(); 4 for (p

大项目之网上书城(十二)——完成啦

目录 大项目之网上书城(十二)--完成啦 主要改动 新增代码 1.addCategory.jsp 效果图 2.bookManager.jsp 效果图 3.userManager.jsp 效果图 4.error404.jsp 效果图 5.error500.jsp 效果图 6.errorelse.jsp 效果图 7.web.xml 8.addFenLeiServlet 9.bookDao里的addFenLei 总结 github页面 bookstoreZhang 大项目之网上书城(十二)--完成啦

第十二周学习进度条

周次 第十二周 所花时间 12小时以上 代码量 1500行以上 博客量 1 学到知识点 上周也没学什么新的内容,还是对以前学过知识的运用.除此之外还是学习了一些新的知识的.由于使用到弹窗.所以上网找了一下弹窗组件,有个叫layer的挺好用的,对于它的一些最常用的一些内容学习使用了一下.