淘淘商城第十一天

购物车和订单的实现

购物车的逻辑写在taotao-portal中

分析:

1、添加购物车不需要用户登录。购物车的数据应该放到cookie中。
2、当向购物车添加同一款商品时,购物车中商品的数量增加。
3、购物车中可以删除商品
4、购物车中可以修改商品数量。商品的总价需要重新计算。
5、点击“结算”按钮要求用户登录。

购物车添加商品service.
逻辑:
1、接收商品id
2、从cookie中购物车商品列表
3、从商品列表中查询列表是否存在此商品
4、如果存在商品的数量加上参数中的商品数量
5、如果不存在,调用rest服务,根据商品id获得商品数据。
6、把商品数据添加到列表中
7、把购物车商品列表写入cookie
8、返回TaotaoResult

@Service
public class CartServiceImpl implements CartService {
        
        @Autowired
        private ItemService itemService;
        @Value("${COOKIE_EXPIRE}")
        private Integer COOKIE_EXPIRE;
        
        @Override
        public TaotaoResult addCart(Long itemId, Integer num, HttpServletRequest request,
                        HttpServletResponse response) {
                //1.接收商品id
                //从cookie中获取购物车商品列表
                List<CartItem> itemList = getCartItemList(request);
                //3.从商品列表中查询列表是否存在此商品
                //flag用来判断是否找到对应的产品
                boolean haveFlg = false;
                for(CartItem cartItem : itemList) {
                        //如果商品存在数量相加
                        //4.如果存在商品的数量加上参数中的商品数量
                        if(cartItem.getId().longValue() == itemId) {
                                cartItem.setNum(cartItem.getNum() + num);
                                haveFlg = true;
                                break;
                        }
                }
                //5.如果不存在,调用rest服务,根据商品id获得商品数据
                if(!haveFlg) {
                        TbItem item = itemService.getItemById(itemId);
                        //转换成CartItem
                        CartItem cartItem = new CartItem();
                        cartItem.setId(itemId);
                        cartItem.setNum(num);
                        cartItem.setPrice(item.getPrice());
                        cartItem.setTitle(item.getTitle());
                        //购物车上只会展示一张图片
                        if(StringUtils.isNoneBlank(item.getImage())) {
                                String image = item.getImage();
                                String[] strings = image.split(",");
                                cartItem.setImage(strings[0]);
                        }
                        //添加到购物车商品列表
                        //6.把商品数据添加到列表中
                        itemList.add(cartItem);
                }
                //7.把购物车商品列表写入cookie
                CookieUtils.setCookie(request, response, "TT_CART", JsonUtils.objectToJson(itemList), COOKIE_EXPIRE, true);
                //返回taotaoResult
                return TaotaoResult.ok();
        }
        
        /**
         * 取购物车商品列表
         */
        private List<CartItem> getCartItemList(HttpServletRequest request){
                try {
                        //从cookie中取商品列表
                        String json = CookieUtils.getCookieValue(request, "TT_CART", true);
                        //把json转换成java对象
                        List<CartItem> list = JsonUtils.jsonToList(json, CartItem.class);
                        
                        return list == null?new ArrayList<CartItem>() : list;
                } catch (Exception e) {
                        return new ArrayList<CartItem>();
                }
        }
}

购物车中商品数量的加减按钮,删除商品按钮都是要联系到cookie和redis的操作

删除的controller中重定向,点击删除按钮应该重新跳回购物车url

        @RequestMapping("/cart/delete/{itemId}")
        public String deleteCartItem(@PathVariable Long itemId,
                        HttpServletResponse response, HttpServletRequest request) {
                TaotaoResult result = cartService.deleteCartItem(itemId, request, response);
                return "redirect:/cart/cart.html";
        }

更换设备后购物车信息不能同步
解决方案:当用户登录后,需要把cookie的购物车信息同步到redis

订单实现

搭建taotao-order

1、接收json数据,需要使用@RequestBody注解。对应提交的json数据格式创建一个pojo接收。
需要使用的表:
tb_order 订单表(一)
tb_order_item 订单明细表(多)
tb_order_shipping 物流表(一)

可以使用订单相关的三个表对应的pojo封装一个pojo接收提交的json数据。注意继承。

public class OrderInfo extends TbOrder{
        
        private List<TbOrderItem> orderItems;//明细表
        
        private TbOrderShipping orderShipping;

        public List<TbOrderItem> getOrderItems() {
                return orderItems;
        }

        public void setOrderItems(List<TbOrderItem> orderItems) {
                this.orderItems = orderItems;
        }

        public TbOrderShipping getOrderShipping() {
                return orderShipping;
        }

        public void setOrderShipping(TbOrderShipping orderShipping) {
                this.orderShipping = orderShipping;
        }
        
}

2、接收json数据后,把数据插入到响应的表中。
3、使用redis的incr命令(redis是单线程,不会重复)

接收json报文,插入三张表数据,返回订单号的服务Service

@Service
public class OrderServiceImpl implements OrderService {
        
        @Autowired
        private TbOrderMapper orderMapper;
        @Autowired
        private TbOrderItemMapper orderItemMapper;
        @Autowired
        private TbOrderShippingMapper orderShippingMapper;
        
        @Autowired
        private JedisClient jedisClient;
        
        @Value("${REDIS_ORDER_GEN_KEY}")
        private String REDIS_ORDER_GEN_KEY;
        @Value("${ORDER_ID_BEGIN}")
        private String ORDER_ID_BEGIN;
        @Value("${REDIS_ORDER_DETAIL_GEN_KEY}")
        private String REDIS_ORDER_DETAIL_GEN_KEY;
        
        @Override
        public TaotaoResult createOrder(OrderInfo orderInfo) {
                //一、插入订单表
                //1.接收数据OrderInfo
                //2.生成订单号
                //取订单号
                String id = jedisClient.get(REDIS_ORDER_GEN_KEY);
                if(StringUtils.isBlank(id)) {
                        //如果订单号生成key不存在设置初始值
                        jedisClient.set(REDIS_ORDER_GEN_KEY, ORDER_ID_BEGIN);
                }
                Long orderId = jedisClient.incr(REDIS_ORDER_GEN_KEY);
                //3.补全字段
                orderInfo.setOrderId(orderId.toString());
                //状态:1.未付款2.已付款3.未发货4.已发货5.交易成功6.交易关闭
                orderInfo.setStatus(1);
                Date date = new Date();
                orderInfo.setCreateTime(date);
                orderInfo.setUpdateTime(date);
                //4.插入订单表
               orderMapper.insert(orderInfo);
               //二、插入订单明细
               //2.补全字段
               List<TbOrderItem> orderItems = orderInfo.getOrderItems();
               for(TbOrderItem orderItem : orderItems) {
                       //1.生成订单明细id,使用redis的incr命令生成
                       Long detailId = jedisClient.incr(REDIS_ORDER_DETAIL_GEN_KEY);
                       orderItem.setId(detailId.toString());
                       //订单号
                       orderItem.setOrderId(orderId.toString());
                       //3.插入数据
                       orderItemMapper.insert(orderItem);
               }
               //三、插入物流表
               TbOrderShipping orderShipping = orderInfo.getOrderShipping();
               //1.补全字段
               orderShipping.setOrderId(orderId.toString());
               orderShipping.setCreated(date);
               orderShipping.setUpdated(date);
               //2.插入数据
               orderShippingMapper.insert(orderShipping);
               //返回TaotaoResult包装订单号
               
                return TaotaoResult.ok(orderId);
        }

}

对应的controller,注意@RequestBody

@Controller
public class OrderController {

    @Autowired
    private OrderService orderService;
    
    @RequestMapping(value="/order/create", method=RequestMethod.POST)
    @ResponseBody
    public TaotaoResult createOrder(@RequestBody OrderInfo orderInfo) {
        try {
            TaotaoResult result = orderService.createOrder(orderInfo);
            return result;
            
        } catch (Exception e) {
            e.printStackTrace();
            return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));
        }
    }
}

taotao-portal的处理
点击提交订单按钮要确认登录,并且token中有需要的用户信息
拦截器的request和最后的request是同一个,所以可以把用户信息放在request中

图片1.png

在订单确认页面点击“提交订单按钮”进行提交订单的处理。把表单的内容提交给taotao-portal的后台,后台调用taotao-order发布的服务生成订单。展示订单提交成功页面,并且展示订单号。

taotao-portal中调用taotao-order的service

@Service
public class OrderServiceImpl implements OrderService {
        
        @Value("${ORDER_BASE_URL}")
        private String ORDER_BASE_URL;
        @Value("${ORDER_CREATE_URL}")
        private String ORDER_CREATE_URL;
        
        @Override
        public String createOrder(OrderInfo orderInfo) {
                // 把OrderInfo转换成json
                String json = JsonUtils.objectToJson(orderInfo);
                //提交订单数据
                String jsonResult = HttpClientUtils.doPostJson(ORDER_BASE_URL+ORDER_CREATE_URL, json);
                //转换成java对象
                TaotaoResult taotaoResult = TaotaoResult.format(jsonResult);
                //取订单号
                String orderId = taotaoResult.getData().toString();
                return orderId;
        }

}

Controller接收提交的订单信息,使用OrderInfo接收。调用Service创建订单,跳转到成功页面,并且把订单号传递给页面。

Controller

        @RequestMapping(value="/create",method=RequestMethod.POST)
        public String createOrder(OrderInfo orderInfo, Model model,HttpServletRequest request) {
                //取用户信息
                TbUser user = (TbUser) request.getAttribute("user");
                //补全orderInfo的属性
                orderInfo.setUserId(user.getId());
                orderInfo.setBuyerNick(user.getUsername());
                //调用服务
                String orderId = orderService.createOrder(orderInfo);
                //把订单号传递给页面
                model.addAttribute("orderId",orderId);
                model.addAttribute("payment",orderInfo.getPayment());
                DateTime dateTime = new DateTime();
                dateTime = dateTime.plusDays(3);
                model.addAttribute("date",dateTime.toString("yyyy-MM-dd"));
                //返回逻辑视图
                return "success";
        }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容