订单的处理原理及代码实现(仿京东实现原理)

作者:一枝花算不算浪漫

出处:https://www.cnblogs.com/wang-meng/

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

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

订单详情表

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

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

@Autowired
    private OrderDao orderDao;
    @Autowired
    private DetailDao detailDao;
    //保存订单
    public void insertOrder(Order order, String username){
        //订单ID
        Long id = jedis.incr("oid");
        order.setId(id);
        //用户id
        String buyerId = jedis.get(username);
        order.setBuyerId(Long.parseLong(buyerId));
        BuyerCart buyerCart = selectBuyerCartFromRedis(username);
        List<BuyerItem> items = buyerCart.getItems();
        for (BuyerItem item : items) {
            item.setSku(selectSkuById(item.getSku().getId()));
        }
        //运费, 由运费提供
        order.setDeliverFee(buyerCart.getFee());
        //订单总金额, 由购物车提供
        order.setTotalPrice(buyerCart.getTotalPrice());
        //订单金额, 由购物车提供
        order.setOrderPrice(buyerCart.getProductPrice());
        //支付状态: 0到付  1待付款  2已付款  3待退款  4退款成功  5退款失败 
        if (order.getPaymentWay() == 1) {
            order.setIsPaiy(0);
        }else {
            //我们这里页面上只有 两种选择: 0到付   1待付款
            order.setIsPaiy(1);
        }
        //订单状态: 0提交订单  1仓库配货  2商品出库  3等待收货  4完成   5待退货  6已退货
        order.setOrderState(0);
        //订单生成时间
        order.setCreateDate(new Date());
        //生成订单
        orderDao.insertSelective(order);
        
        //保存订单详情
        for (BuyerItem item : items) {
            Detail detail = new Detail();
            //订单详情表
            /*
             * ID:自增长
             * 订单ID, 商品编号ID, 商品名称, 颜色中文名称, 尺码, 价格, 数量, 购物车中购物项提交数量 
             */
            detail.setOrderId(id);
            detail.setProductId(item.getSku().getProductId());
            detail.setProductName(item.getSku().getProduct().getName());
            detail.setColor(item.getSku().getColor().getName());
            detail.setSize(item.getSku().getSize());
            detail.setPrice(item.getSku().getPrice());
            detail.setAmount(item.getAmount());
            
            //保存购物车中购物项
            detailDao.insertSelective(detail);
            
            //减库存
            
            //清空购物车, 这里只写全部删除的方法, 如果删除某个购物项需使用jedis.hdel();
            jedis.del("buyerCart:" + username);
        }
    }

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

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

//去结算
    @RequestMapping(value="/buyer/trueBuy")
    public String trueBuy(String[] skuIds, Model model, HttpServletRequest request, HttpServletResponse response){
        //1, 购物车必须有商品, 
        //取出用户名  再取出购物车
        String username = sessionProviderService.getAttributterForUsername(RequestUtils.getCSessionId(request, response));
        //取出所有购物车
        BuyerCart buyerCart = cartService.selectBuyerCartFromRedisBySkuIds(skuIds, username);
        List<BuyerItem> items = buyerCart.getItems();
        if (items.size() > 0) {
            //购物车中有商品
            //判断所勾选的商品是否都有货, 如果有一件无货, 那么就刷新页面.
            Boolean flag = true;
            //2, 购物车中商品必须有库存 且购买大于库存数量时视为无货. 提示: 购物车原页面不动. 有货改为无货, 加红提醒.
            for (BuyerItem buyerItem : items) {
                //装满购物车的购物项, 当前购物项只有skuId这一个东西, 我们还需要购物项的数量去判断是否有货
                buyerItem.setSku(cartService.selectSkuById(buyerItem.getSku().getId()));
                //校验库存
                if (buyerItem.getAmount() > buyerItem.getSku().getStock()) {
                    //无货
                    buyerItem.setIsHave(false);
                    flag = false;
                }
                if (!flag) {
                    //无货, 原页面不动, 有货改成无货, 刷新页面.
                    model.addAttribute("buyerCart", buyerCart);
                    return "cart";
                }
            }
        }else {
            //购物车没有商品
            //没有商品: 1>原购物车页面刷新(购物车页面提示没有商品)
            return "redirect:/shopping/toCart";
        }
        
        
        //3, 正常进入下一个页面
        return "order";
    }
    
    
    //提交订单
    @RequestMapping(value="/buyer/submitOrder")
    public String submitOrder(Order order, HttpServletRequest request, HttpServletResponse response){
        String username = sessionProviderService.getAttributterForUsername(RequestUtils.getCSessionId(request, response));
        
        //保存订单
        cartService.insertOrder(order, username);
        
        return "success";
    }

最完整的购物车实现及原理(仿京东实现原理), 对于"/buyer/"这样格式的请求我们的springmvc都会拦截, 拦截的形式 就是判断用户是否登录. 这里我们也不会详细说明.
这里要判断购物项中的数量是否大于库存, 如果大于库存就刷新购物车页面, 且显示该购物项无货状态.
剩下的提交订单  就是保存order到订单表, 这里面也包含保存购物详情到订单详情表.

推荐作品

  ●  一个蚂蚁程序员,曾经的辛酸面试历程

  ●  程序员提高技术的资源汇总

  ●  MySQL误删数据,再也不用跑路了

  ●  5分钟了解swagger

  ●  Web登录其实没你想的那么简单

  ●  Java程序性能优化之编程技巧总结

  ●  教你理清SpringBoot与SpringMVC的关系

  ●  你知道Java的四种引用类型吗

  ●  如何阅读Java源码 ,阅读java的真实体会

京东数据库设计 Revised on November 25, 2020 Revised on November 25, 2020 京东数据库设计全文共118页,当前为第1页。京东数据库设计 京东数据库设计全文共118页,当前为第1页。 Table of Contents 京东数据库设计全文共118页,当前为第2页。The 'Table of Contents' field needs to be updated! 京东数据库设计全文共118页,当前为第2页。 京东数据库设计全文共118页,当前为第3页。的清单 京东数据库设计全文共118页,当前为第3页。 名称 注释 account_info中信账户管理 中信账户管理 activity_record活动记录信息 活动记录信息 activity_statements 活动结算 活动结算 bace_type bank_settle_detail 第三方支付结算excel 第三方支付结算excel base_consulting_sms咨询 咨询 base_dictionary 物流信息 物流信息 base_jms_listener消息记录 消息记录 base_msg_record基础信息记录 基础信息记录 base_send_message TDK设置 TDK设置 base_sms_config基础邮件配置 基础邮件配置 base_tdk_config基础信息TDK设置 基础信息TDK设置 base_user_favorite用户收藏 base_website_message基础网站消息 基础网站消息 central_purchasing_activites_details集采详情 集采详情 central_purchasing_activites集采活动 集采活动 central_purchasing_enterprise参与集采单位信息 参与集采单位信息 central_purchasing_ref_enterprise集采商品与集采单位关联 集采商品与集采单位关联 central_purchasing_ref_order集采订单关联 集采订单关联 citic_pay_journal 中信支付记录数据交互 中信支付记录数据交互 company_pay_job 存放企业用户自动支付的记录 存放企业用户自动支付的记录 complain 仲裁信息 仲裁信息 contract_info 协议 协议 contract_mat 协议明细 协议明细 contract_order 协议订单 协议订单 contract_payment_term 协议付款合同 协议付款合同 contract_url_show 协议附件地址 协议附件地址 coupon_info优惠券主 优惠券主 coupon_user优惠券与用户的关联 优惠券和所领此优惠券的用户的关联 coupon_using_range优惠券使用范围 优惠券使用范围 date_dic 静态日期 静态日期(广告统计使用) delivery 快递信息 快递信息 delivery_addressbase交货地址 delivery_express_company交付快递公司 delivery_fee_info交付费用信息 delivery_info交付信息 delivery_status订单配送状态 订单配送状态 原注释:发货状态(扫描状态用) delivery_useful_address_info用户地址信息 factorage_journal 第三方支付的手续费记录 第三方支付的手续费记录 field_certification_attachment认证附件 field_certification认证信息 field_identification_audi实地认证审核 实地认证审核 field_identification_picture实地认证图片 实地认证图片 finance_account_info 金融帐号配置 金融帐号配置 finance_withdraw_apply提现申请 finance_withdraw_record提现记录 inquiry_info 询价 询价 inquiry_mat 询价明细 询价明细 inquiry_order 询价订单 询价订单 integral_config 积分配置 积分配置 invoice 发票 发票 invoice_pic 发票对应图片 发票对应图片 item_attr_value_item(属性属性值和商品关系) 属性属性值和商品关系 item_a
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值