淘淘商城第十一天

購物車和訂單的實現

購物車的邏輯寫在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";
        }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,406評論 6 538
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,034評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,413評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,449評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,165評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,559評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,606評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,781評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,327評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,084評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,278評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,849評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,495評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,927評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,172評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,010評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,241評論 2 375

推薦閱讀更多精彩內容