宅男在线永久免费观看网直播,亚洲欧洲日产国码无码久久99,野花社区在线观看视频,亚洲人交乣女bbw,一本一本久久a久久精品综合不卡

全部
常見(jiàn)問(wèn)題
產(chǎn)品動(dòng)態(tài)
精選推薦

購(gòu)物車實(shí)現(xiàn)大揭秘:讓你秒懂網(wǎng)購(gòu)背后的技術(shù)!

管理 管理 編輯 刪除

一、購(gòu)物車分析

1、購(gòu)物車需求分析

首先搭建好數(shù)據(jù)庫(kù)
	1、考慮客戶端傳來(lái)的商品數(shù)據(jù)有哪些
	2、考慮添加到購(gòu)物車中商品的信息有哪些
	3、是根據(jù)哪個(gè)字段進(jìn)行查找購(gòu)物車商品

2、購(gòu)物車實(shí)現(xiàn)思路

使用redis存儲(chǔ)購(gòu)物車數(shù)據(jù),每次查看購(gòu)物車的時(shí)候直接從Redis中獲取。

130eb202312121625318623.png

3、表結(jié)構(gòu)分析

1.訂單表參考樣例

CREATE TABLE `tb_order_item` (
  `id` varchar(20) COLLATE utf8_bin NOT NULL COMMENT 'ID',
  `category_id1` int(11) DEFAULT NULL COMMENT '1級(jí)分類',
  `category_id2` int(11) DEFAULT NULL COMMENT '2級(jí)分類',
  `category_id3` int(11) DEFAULT NULL COMMENT '3級(jí)分類',
  `spu_id` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT 'SPU_ID',
  `sku_id` bigint(20) NOT NULL COMMENT 'SKU_ID',
  `order_id` bigint(20) NOT NULL COMMENT '訂單ID',
  `name` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '商品名稱',
  `price` int(20) DEFAULT NULL COMMENT '單價(jià)',
  `num` int(10) DEFAULT NULL COMMENT '數(shù)量',
  `money` int(20) DEFAULT NULL COMMENT '總金額',
  `pay_money` int(11) DEFAULT NULL COMMENT '實(shí)付金額',
  `image` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '圖片地址',
  `weight` int(11) DEFAULT NULL COMMENT '重量',
  `post_fee` int(11) DEFAULT NULL COMMENT '運(yùn)費(fèi)',
  `is_return` char(1) COLLATE utf8_bin DEFAULT NULL COMMENT '是否退貨',
  PRIMARY KEY (`id`),
  KEY `item_id` (`sku_id`),
  KEY `order_id` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

購(gòu)物車詳情表其實(shí)就是訂單詳情表結(jié)構(gòu),只是目前臨時(shí)存儲(chǔ)數(shù)據(jù)到Redis,等用戶下單后才將數(shù)據(jù)從Redis取出存入到MySQL中。

2.折扣表

CREATE TABLE `tb_pref` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `cate_id` int(11) DEFAULT NULL COMMENT '分類ID',
  `buy_money` int(11) DEFAULT NULL COMMENT '消費(fèi)金額',
  `pre_money` int(11) DEFAULT NULL COMMENT '優(yōu)惠金額',
  `start_time` date DEFAULT NULL COMMENT '活動(dòng)開(kāi)始日期',
  `end_time` date DEFAULT NULL COMMENT '活動(dòng)截至日期',
  `type` char(1) DEFAULT NULL COMMENT '類型,1:普通訂單,2:限時(shí)活動(dòng)',
  `state` char(1) DEFAULT NULL COMMENT '狀態(tài),1:有效,0:無(wú)效',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

二、訂單購(gòu)物車微服務(wù)搭建

1、引入依賴
2、通過(guò)逆向工程創(chuàng)建實(shí)體類,server,serverlmp,controller
3、application.yml文件完善配置(eureka、feign、redis、jdbc)

1、添加商品到redis

1.1、實(shí)現(xiàn)思路

(1).用戶添加購(gòu)物車,只需要將要加入購(gòu)物車的商品存入到Redis中即可。一個(gè)用戶可以將多件商品加入購(gòu)物車,存儲(chǔ)到Redis中的數(shù)據(jù)可以采用Hash類型。

(2).選Hash類型可以將用戶的用戶名作為namespace的一部分,將指定商品加入購(gòu)物車,則往對(duì)應(yīng)的namespace中增加一個(gè)key和value,key是商品ID,value是加入購(gòu)物車的商品詳情,如下圖:

5ee76202312121628083720.png

1.2、代碼實(shí)現(xiàn)將數(shù)據(jù)存入redis

1、需要使用feign來(lái)調(diào)用商品服務(wù)的接口來(lái)獲取商品的信息——需要在訂單服務(wù)開(kāi)啟客戶端@EnableFeignClients
2、order服務(wù)的業(yè)務(wù)層添加add(商品數(shù)量,商品id,用戶名)方法來(lái)實(shí)現(xiàn)將商品添加到redis
		a、根據(jù)id查詢庫(kù)存表sku,判斷該商品庫(kù)存數(shù)量和是否上架出售
		b、從sku表中查出來(lái)的信息中獲取spu的id到spu表中查詢商品的其他信息(如銷售價(jià)格,優(yōu)惠)
		c、將查到的兩個(gè)商品對(duì)象,創(chuàng)建一個(gè)實(shí)體類其包含了購(gòu)物車所需的屬性,用這個(gè)實(shí)體類將他們封裝起來(lái)
3、將封裝好的對(duì)象存儲(chǔ)到redis中
1.2.1、feign
  • sku庫(kù)存
/***
 * 根據(jù)ID查詢SKU信息
 * @param id : sku的ID
 */
@GetMapping(value = "/{id}")
public Result<Sku> findById(@PathVariable(value = "id", required = true) Long id);
  • spu商品銷售的信息表
/***
 * 根據(jù)SpuID查詢Spu信息
 * @param id
 * @return
 */
@GetMapping("/{id}")
public Result<Spu> findById(@PathVariable(name = "id") Long id);
1.2.2、業(yè)務(wù)層

添加到redis中數(shù)據(jù)的格式

redisTemplate.boundHashOps().put();
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SkuFeign skuFeign;

    @Autowired
    private SpuFeign spuFeign;


    /***
     * 加入購(gòu)物車
     * @param num:購(gòu)買商品數(shù)量
     * @param id:購(gòu)買ID
     * @param username:購(gòu)買用戶
     * @return
     */
    @Override
    public void add(Integer num, Long id, String username) {
        //查詢SKU
        Result<Sku> resultSku = skuFeign.findById(id);
        if(resultSku!=null && resultSku.isFlag()){
            //獲取SKU
            Sku sku = resultSku.getData();
            //獲取SPU
            Result<Spu> resultSpu = spuFeign.findById(sku.getSpuId());

            //將SKU轉(zhuǎn)換成OrderItem
            OrderItem orderItem = sku2OrderItem(sku,resultSpu.getData(), num);

            /******
             * 購(gòu)物車數(shù)據(jù)存入到Redis
             * namespace = Cart_[username]
             * key=id(sku)
             * value=OrderItem
             */
            redisTemplate.boundHashOps("Cart_"+username).put(id,orderItem);
        }
    }

    /***
     * SKU轉(zhuǎn)成OrderItem
     * @param sku
     * @param num
     * @return
     */
    private OrderItem sku2OrderItem(Sku sku,Spu spu,Integer num){
        OrderItem orderItem = new OrderItem();
        orderItem.setSpuId(sku.getSpuId());
        orderItem.setSkuId(sku.getId());
        orderItem.setName(sku.getName());
        orderItem.setPrice(sku.getPrice());
        orderItem.setNum(num);
        orderItem.setMoney(num*orderItem.getPrice());       //單價(jià)*數(shù)量
        orderItem.setPayMoney(num*orderItem.getPrice());    //實(shí)付金額
        orderItem.setImage(sku.getImage());
        orderItem.setWeight(sku.getWeight()*num);           //重量=單個(gè)重量*數(shù)量

        //分類ID設(shè)置
        orderItem.setCategoryId1(spu.getCategory1Id());
        orderItem.setCategoryId2(spu.getCategory2Id());
        orderItem.setCategoryId3(spu.getCategory3Id());
        return orderItem;
    }
}
1.2.3、控制層
@RestController
@CrossOrigin
@RequestMapping(value = "/cart")
public class CartController {

    @Autowired
    private CartService cartService;

    /***
     * 加入購(gòu)物車
     * @param num:購(gòu)買的數(shù)量
     * @param id:購(gòu)買的商品(SKU)ID
     * @return
     */
    @RequestMapping(value = "/add")
    public Result add(Integer num, Long id){
        //用戶名
        String username="szitheima";
        //將商品加入購(gòu)物車
        cartService.add(num,id,username);
        return new Result(true, StatusCode.OK,"加入購(gòu)物車成功!");
    }
}
注意:此處的用戶名是寫(xiě)死的,如何獲取用戶名成為一個(gè)問(wèn)題

2、從redis中獲取商品數(shù)據(jù)

2.1、思路分析

存入數(shù)據(jù)時(shí)是以hash的形式存儲(chǔ)的,且鍵位“Cart_”+用戶名,值為商品詳情對(duì)象,因此

2.2、業(yè)務(wù)層

redis中拿去數(shù)據(jù)的方法:注入redisTemplate,調(diào)用boundHashOps(鍵值).value()獲取值

/***
 * 查詢用戶購(gòu)物車數(shù)據(jù)
 * @param username
 * @return
 */
@Override
public List<OrderItem> list(String username) {
    //查詢所有購(gòu)物車數(shù)據(jù)
    List<OrderItem> orderItems = redisTemplate.boundHashOps("Cart_"+username).values();
    return orderItems;
}

3、存在的問(wèn)題

3.1、商品數(shù)量正負(fù)問(wèn)題

我們發(fā)現(xiàn)個(gè)問(wèn)題,就是用戶將商品加入購(gòu)物車,無(wú)論數(shù)量是正負(fù),都會(huì)執(zhí)行添加購(gòu)物車,如果數(shù)量<=0,應(yīng)該移除該商品的。

  • 修改方法
  • 只需在添加商品到購(gòu)物車的方法中增加一條判斷邏輯商品數(shù)量為負(fù)便return
注意:在判斷為負(fù)時(shí),若redis存在該值,則需redisTemplate.boundHashOps(“Cart_”+username).delete(id);刪除redis中的記錄,這樣便在查詢購(gòu)物車列表時(shí)不會(huì)出現(xiàn)該數(shù)據(jù)

3.2、數(shù)據(jù)精度丟失問(wèn)題

SkuId是Long類型,在頁(yè)面輸出的時(shí)候會(huì)存在精度丟失問(wèn)題,我們只需要在OrderItem的SkuId上加上字符串序列化類型(即@JsonSerialize)就可以了,代碼如下

bb2d1202312121631213659.png

三、用戶身份識(shí)別

請(qǐng)登錄后查看

CRMEB-慕白寒窗雪 最后編輯于2023-12-12 16:32:38

快捷回復(fù)
回復(fù)
回復(fù)
回復(fù)({{post_count}}) {{!is_user ? '我的回復(fù)' :'全部回復(fù)'}}
排序 默認(rèn)正序 回復(fù)倒序 點(diǎn)贊倒序

{{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level || item.bbs_level }}

作者 管理員 企業(yè)

{{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推薦': '推薦'}}
{{item.is_suggest == 1? '取消推薦': '推薦'}}
沙發(fā) 板凳 地板 {{item.floor}}#
{{item.user_info.title || '暫無(wú)簡(jiǎn)介'}}
附件

{{itemf.name}}

{{item.created_at}}  {{item.ip_address}}
打賞
已打賞¥{{item.reward_price}}
{{item.like_count}}
{{item.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)

{{itemc.user_info.nickname}}

{{itemc.user_name}}

回復(fù) {{itemc.comment_user_info.nickname}}

附件

{{itemf.name}}

{{itemc.created_at}}
打賞
已打賞¥{{itemc.reward_price}}
{{itemc.like_count}}
{{itemc.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)
查看更多
打賞
已打賞¥{{reward_price}}
1692
{{like_count}}
{{collect_count}}
添加回復(fù) ({{post_count}})

相關(guān)推薦

快速安全登錄

使用微信掃碼登錄
{{item.label}} 加精
{{item.label}} {{item.label}} 板塊推薦 常見(jiàn)問(wèn)題 產(chǎn)品動(dòng)態(tài) 精選推薦 首頁(yè)頭條 首頁(yè)動(dòng)態(tài) 首頁(yè)推薦
取 消 確 定
回復(fù)
回復(fù)
問(wèn)題:
問(wèn)題自動(dòng)獲取的帖子內(nèi)容,不準(zhǔn)確時(shí)需要手動(dòng)修改. [獲取答案]
答案:
提交
bug 需求 取 消 確 定
打賞金額
當(dāng)前余額:¥{{rewardUserInfo.reward_price}}
{{item.price}}元
請(qǐng)輸入 0.1-{{reward_max_price}} 范圍內(nèi)的數(shù)值
打賞成功
¥{{price}}
完成 確認(rèn)打賞

微信登錄/注冊(cè)

切換手機(jī)號(hào)登錄

{{ bind_phone ? '綁定手機(jī)' : '手機(jī)登錄'}}

{{codeText}}
切換微信登錄/注冊(cè)
暫不綁定
CRMEB客服

CRMEB咨詢熱線 咨詢熱線

400-8888-794

微信掃碼咨詢

CRMEB開(kāi)源商城下載 源碼下載 CRMEB幫助文檔 幫助文檔
返回頂部 返回頂部
CRMEB客服