• 订单模块


    功能介绍:

    前台功能:

    1.创建订单

    controller层实现:

    传入userId和收货地址shippingId,由后台自动创建订单。

     1     @RequestMapping("create.do")
     2     @ResponseBody
     3     public ServerResponse create(HttpServletRequest request, Integer shippingId) {
     4     //    User user = (User)session.getAttribute(Const.CURRENT_USER);
     5 
     6         String loginToken = CookieUtil.readLoginToken(request);
     7         if(StringUtils.isEmpty(loginToken)) {
     8             return ServerResponse.createByErrorMessage("用户未登录,无法获取当前用户的信息");
     9         }
    10         String userJsonStr = RedisShardedPoolUtil.get(loginToken);
    11         User user = JsonUtil.string2Obj(userJsonStr, User.class);
    12 
    13         if(user ==null){
    14             return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getDesc());
    15         }
    16         //将userId和shippingId传入,创建订单
    17         return iOrderService.createOrder(user.getId(), shippingId);
    18     }
    View Code

    service层实现:

    1)根据userId从购物车表CART中将已勾选的商品取出来,由cartList保存,然后根据这个cartList,由getCartOrderItem()生成订单详情orderItemList。

    2)由订单详情orderItemList可以计算出整个订单的总价,由getOrderTotalPrice()实现。

    3)根据以上计算出来的订单总价、收货地址shipingId、userId生成最后的订单order,由assembleOrder()实现,并持久化到数据库中。

    4)由assembleOrder()生成的订单,是带有最后的订单号的orderNo,所以将这个订单号更新到之前的订单详情orderItemList中,由mybatis的批量插入实现。

    5)根据订单详情orderItemList,去对应的商品表中减库存,由reduceProductStock()实现。

    6)清空当前购物车,由cleanCart()实现。

    7)将生成的最后的订单order和订单详情orderItemList,组合成vo后返回给前台。

     1     public ServerResponse createOrder(Integer userId, Integer shippingId) {
     2         //从购物车中获取数据
     3         //将购物车中已勾选的物品获取出来,这些物品会用来生成订单
     4         List<Cart> cartList = cartMapper.selectCheckedCartByUserId(userId);
     5 
     6         //根据这些物品,即cartList,生成订单详情List
     7         ServerResponse serverResponse = this.getCartOrderItem(userId, cartList);
     8         if(!serverResponse.isSuccess()) {
     9             return serverResponse;
    10         }
    11         List<OrderItem> orderItemList = (List<OrderItem>)serverResponse.getData();
    12         //根据订单详情list,计算订单总价
    13         BigDecimal payment = this.getOrderTotalPrice(orderItemList);
    14 
    15         //生成订单
    16         Order order = this.assembleOrder(userId, shippingId, payment);
    17         if(order == null) {
    18             return ServerResponse.createByErrorMessage("生成订单错误");
    19         }
    20         if(CollectionUtils.isEmpty(orderItemList)) {
    21             return ServerResponse.createByErrorMessage("购物车为空");
    22         }
    23         //将订单号逐一的更新到当前订单详情中,也就是一条订单数据可以对应多条订单详情
    24         for(OrderItem orderItem : orderItemList) {
    25             orderItem.setOrderNo(order.getOrderNo());
    26         }
    27         //mybatis批量插入
    28         //由于订单详情,一次性可能有多个商品,多个订单详情,也就是多条数据,所以这里就要使用一次性批量插入
    29         orderItemMapper.batchInsert(orderItemList);
    30         //生成成功,减少产品的库存
    31         this.reduceProductStock(orderItemList);
    32 
    33         //清空购物车
    34         this.cleanCart(cartList);
    35 
    36         //将订单明细返回给前端,返回给前端
    37         //pojo->vo
    38         //组装vo,传给前端的数据
    39         OrderVo orderVo = assembleOrderVo(order, orderItemList);
    40         return ServerResponse.createBySuccess(orderVo);
    41     }
    View Code

    getCartOrderItem()由购物车勾选状态生成订单详情实现:

    从购物车表中获取productId,然后从product表中获取当前商品的详细信息,校验商品的在售和库存状态,然后组装订单详情,一种商品对应一个订单详情,一个订单详情由orderNo唯一标识,多个订单详情对应一个订单,最后将组装完成的订单详情cartItemList返回。

     1     private ServerResponse getCartOrderItem(Integer userId,List<Cart> cartList){
     2         List<OrderItem> orderItemList = Lists.newArrayList();
     3         if(CollectionUtils.isEmpty(cartList)){
     4             return ServerResponse.createByErrorMessage("购物车为空");
     5         }
     6 
     7         //校验购物车的数据,包括产品的状态和数量
     8         for(Cart cartItem : cartList){
     9             OrderItem orderItem = new OrderItem();
    10             //从购物车中获取productId,然后从product表中获取当前产品的详细信息
    11             Product product = productMapper.selectByPrimaryKey(cartItem.getProductId());
    12             //查看当前产品是否在售
    13             if(Const.ProductStatusEnum.ON_SALE.getCode() != product.getStatus()){
    14                 return ServerResponse.createByErrorMessage("产品"+product.getName()+"不是在线售卖状态");
    15             }
    16 
    17             //校验库存,校验当前产品选购的数量是否超过产品本身库存
    18             if(cartItem.getQuantity() > product.getStock()){
    19                 return ServerResponse.createByErrorMessage("产品"+product.getName()+"库存不足");
    20             }
    21 
    22             //组装订单详情,一种商品,一个订单详情,而订单详情又由orderNo唯一标识,所以可能多种商品有同样的orderNo,而orderNo又对应订单order中的一个订单,也由orderNo唯一标识
    23 
    24             orderItem.setUserId(userId);
    25             orderItem.setProductId(product.getId());
    26             orderItem.setProductName(product.getName());
    27             orderItem.setProductImage(product.getMainImage());
    28             orderItem.setCurrentUnitPrice(product.getPrice());
    29             orderItem.setQuantity(cartItem.getQuantity());
    30             // 这里将当前商品的总价:单价*数量,存进数据表
    31             orderItem.setTotalPrice(BigDecimalUtil.mul(product.getPrice().doubleValue(),cartItem.getQuantity()));
    32             //将当前订单详情加入订单详情List中
    33             orderItemList.add(orderItem);
    34         }
    35         //将订单详情list返回
    36         return ServerResponse.createBySuccess(orderItemList);
    37     }
    View Code

    getOrderTotalPrice()由订单详情计算出整个订单的总价:

    由于在生成订单详情的时候,已经对每种商品单独计算过对应的总价,存储在订单详情中了,所以这里只需要将订单中的所有商品价值相加即可。

    1     private BigDecimal getOrderTotalPrice(List<OrderItem> orderItemList) {
    2         BigDecimal payment = new BigDecimal("0");
    3         //计算当前订单总计,逐一相加
    4         for(OrderItem orderItem : orderItemList) {
    5             payment = BigDecimalUtil.add(payment.doubleValue(), orderItem.getTotalPrice().doubleValue());
    6         }
    7         return payment;
    8     }
    View Code

    assembleOrder()由userId、订单详情、总价组装最后的订单:

    由generateOrderNo()生成订单号,然后添加订单所需要的字段,比如订单号、订单状态、运费、支付类型、订单总价等,然后将订单持久化到数据库中。

     1     private Order assembleOrder(Integer userId, Integer shippingId, BigDecimal payment) {
     2         Order order = new Order();
     3         //生成订单号orderNo,很重要
     4         long orderNo = this.generateOrderNo();
     5         //设置订单号
     6         order.setOrderNo(orderNo);
     7         //设置订单状态
     8         order.setStatus(Const.OrderStatusEnum.NO_PAY.getCode());
     9         //设置运费
    10         order.setPostage(0);
    11         //设置支付类型
    12         order.setPaymentType(Const.PaymentTypeEnum.ONLINE_PAY.getCode());
    13         //设置订单总价
    14         order.setPayment(payment);
    15         order.setUserId(userId);
    16         order.setShippingId(shippingId);
    17 
    18         //将这个订单持久化到数据库中
    19         int rowCount = orderMapper.insert(order);
    20         if(rowCount > 0) {
    21             return order;
    22         }
    23         return null;
    24     }
    View Code

    reduceProductStock()由订单详情去对应的商品表中减库存:

     1     private void reduceProductStock(List<OrderItem> orderItemList) {
     2         //根据订单详情list,逐一针对商品,去product表中减库存
     3         for(OrderItem orderItem : orderItemList) {
     4             //根据productId,从product表中拿到当前商品
     5             Product product = productMapper.selectByPrimaryKey(orderItem.getProductId());
     6             //减库存
     7             product.setStock(product.getStock() - orderItem.getQuantity());
     8             //将库存信息更新到product表中
     9             productMapper.updateByPrimaryKeySelective(product);
    10         }
    11     }
    View Code

    cleanCart()清空购物车:

    1     private void cleanCart(List<Cart> cartList) {
    2         for(Cart cart : cartList) {
    3             //更新cart购物车表
    4             cartMapper.deleteByPrimaryKey(cart.getId());
    5         }
    6     }
    View Code

    2.获取购物车中已经选中的商品信息

    service层实现:

    根据userId从购物车表中,将当前用户选中的商品拿出来,由cartList记录。根据cartList,由getCartOrderItem()得到订单详情orderItemList,从订单详情orderItemList中计算订单总价。最后将订单详情、订单总价等组装成对应的vo对象返回给前端。

     1     public ServerResponse getOrderCartProduct(Integer userId) {
     2         OrderProductVo orderProductVo = new OrderProductVo();
     3         //从购物车中获取数据
     4         //根据userId,从购物车表中,将当前用户选中的商品拿出来
     5         List<Cart> cartList = cartMapper.selectCheckedCartByUserId(userId);
     6         //根据选中的商品list,得到订单详情
     7         ServerResponse serverResponse =  this.getCartOrderItem(userId,cartList);
     8         if(!serverResponse.isSuccess()){
     9             return serverResponse;
    10         }
    11         List<OrderItem> orderItemList =( List<OrderItem> ) serverResponse.getData();
    12 
    13         List<OrderItemVo> orderItemVoList = Lists.newArrayList();
    14         //从订单详情list中,计算订单总价
    15         BigDecimal payment = new BigDecimal("0");
    16         for(OrderItem orderItem : orderItemList){
    17             //计算订单总价
    18             payment = BigDecimalUtil.add(payment.doubleValue(),orderItem.getTotalPrice().doubleValue());
    19             //将订单详情,组装成订单详情vo对象,放在voList中
    20             orderItemVoList.add(assembleOrderItemVo(orderItem));
    21         }
    22         //将订单总价放在orderProductVo中
    23         orderProductVo.setProductTotalPrice(payment);
    24         //将订单详情voList放在orderProductVo中
    25         orderProductVo.setOrderItemVoList(orderItemVoList);
    26         //将图片服务器地址放在orderProductVo中
    27         orderProductVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix"));
    28         //将orderProductVo返回
    29         return ServerResponse.createBySuccess(orderProductVo);
    30     }
    View Code

    3.订单列表

    4.订单详情

    5.取消订单

    controller层实现:

    传入userId,orderNo参数,通过service层实现:

     1     @RequestMapping("cancel.do")
     2     @ResponseBody
     3     public ServerResponse cancel(HttpServletRequest request , Long orderNo) {
     4     //    User user = (User)session.getAttribute(Const.CURRENT_USER);
     5 
     6         String loginToken = CookieUtil.readLoginToken(request);
     7         if(StringUtils.isEmpty(loginToken)) {
     8             return ServerResponse.createByErrorMessage("用户未登录,无法获取当前用户的信息");
     9         }
    10         String userJsonStr = RedisShardedPoolUtil.get(loginToken);
    11         User user = JsonUtil.string2Obj(userJsonStr, User.class);
    12 
    13         if(user ==null){
    14             return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),ResponseCode.NEED_LOGIN.getDesc());
    15         }
    16         return iOrderService.cancel(user.getId(), orderNo);
    17     }
    View Code

    service层实现:

    通过userId,orderNo查到对应的订单,如果订单状态是未付款,则置订单状态为CANCELED,更行到数据库即可。

     1     public ServerResponse<String> cancel(Integer userId, Long orderNo) {
     2         //根据userId和orderNo拿到订单
     3         Order order = orderMapper.selectByUserIdAndOrderNo(userId, orderNo);
     4         if(order == null) {
     5             return ServerResponse.createByErrorMessage("该用户此订单不存在");
     6         }
     7         //判断订单状态
     8         if(order.getStatus() != Const.OrderStatusEnum.NO_PAY.getCode()) {
     9             return ServerResponse.createByErrorMessage("已付款,无法取消订单");
    10         }
    11         Order updateOrder = new Order();
    12         updateOrder.setId(order.getId());
    13         //更新订单状态
    14         updateOrder.setStatus(Const.OrderStatusEnum.CANCELED.getCode());
    15         //将更新状态更新到数据库中
    16         int row = orderMapper.updateByPrimaryKeySelective(updateOrder);
    17         if(row > 0) {
    18             return ServerResponse.createBySuccess();
    19         }
    20         return ServerResponse.createByError();
    21     }
    View Code

    后台功能:

    1.订单列表

    2.订单搜索

    3.订单详情

    4.订单发货

    学习目标:

    1.设计实用、安全、扩展性强大的常量、枚举类

    2.订单号生成规则、订单严谨性判断

    3.POJO和VO之间的实际操练

    4.mybatis批量插入

  • 相关阅读:
    centos 网络开启
    ubuntu server 服务器部署(二) mysql 安装配置手记
    ubuntu server 服务器部署(一) jdk 安装配置手记
    网络管理
    磁盘配额
    创建raid0
    创建raid5
    逻辑卷快照
    LVM(逻辑卷)
    1.计算机基础
  • 原文地址:https://www.cnblogs.com/cing/p/8536242.html
Copyright © 2020-2023  润新知