1. 一文搞懂大廠商品中心設(shè)計(jì)!

        共 30104字,需瀏覽 61分鐘

         ·

        2024-05-07 23:18


        點(diǎn)擊下方“JavaEdge”,選擇“設(shè)為星標(biāo)

        第一時(shí)間關(guān)注技術(shù)干貨!

        免責(zé)聲明~

        任何文章不要過(guò)度深思!

        萬(wàn)事萬(wàn)物都經(jīng)不起審視,因?yàn)槭郎蠜](méi)有同樣的成長(zhǎng)環(huán)境,也沒(méi)有同樣的認(rèn)知水平,更「沒(méi)有適用于所有人的解決方案」;

        不要急著評(píng)判文章列出的觀點(diǎn),只需代入其中,適度審視一番自己即可,能「跳脫出來(lái)從外人的角度看看現(xiàn)在的自己處在什么樣的階段」才不為俗人。

        怎么想、怎么做,全在乎自己「不斷實(shí)踐中尋找適合自己的大道」

        1 雪花算法使用

        IdWorker idWorker=new IdWorker(1,1);
        for(int i=0;i<10000;i++){
            long id = idWorker.nextId();
            System.out.println(id);
        }

        配置分布式ID生成器

        • 將IdWorker.java拷貝到util包
        • 在工程的resources下新增applicationContext-service.xml
        <!‐‐雪花ID生成器‐‐>
        <bean id="idWorker" class="com.qingcheng.util.IdWorker">
            <constructor‐arg index="0" value="1"></constructor‐arg>
            <constructor‐arg index="1" value="1"></constructor‐arg>
        </bean>

        2 新增和修改商品

        2.1 表結(jié)構(gòu)

        t_spu 表

        字段名稱 字段含義 字段類型 字段長(zhǎng)度 備注
        id 主鍵 VARCHAR

        sn 貨號(hào) VARCHAR

        name SPU名 VARCHAR

        caption 副標(biāo)題 VARCHAR

        brand_id 品牌ID INT

        category1_id 一級(jí)分類 INT

        category2_id 二級(jí)分類 INT

        category3_id 三級(jí)分類 INT

        template_id 模板ID INT

        freight_id 運(yùn)費(fèi)模板id INT

        image 圖片 VARCHAR

        images 圖片列表 VARCHAR

        sale_service 售后服務(wù) VARCHAR

        introduction 介紹 TEXT

        spec_items 規(guī)格列表 VARCHAR

        para_items 參數(shù)列表 VARCHAR

        sale_num 銷(xiāo)量 INT

        comment_num 評(píng)論數(shù) INT

        is_marketable 是否上架 CHAR

        is_enable_spec 是否啟用規(guī)格 CHAR

        is_delete 是否刪除 CHAR

        status 審核狀態(tài) CHAR

        t_sku 表

        字段名稱 字段含義 字段類型 字段長(zhǎng)度 備注
        id 商品id VARCHAR

        sn 商品條碼 VARCHAR

        name SKU名稱 VARCHAR

        price 價(jià)格(分) INT

        num 庫(kù)存數(shù)量 INT

        alert_num 庫(kù)存預(yù)警數(shù)量 INT

        image 商品圖片 VARCHAR

        images 商品圖片列表 VARCHAR

        weight 重量(克) INT

        create_time 創(chuàng)建時(shí)間 DATETIME

        update_time 更新時(shí)間 DATETIME

        spu_id SPUID VARCHAR

        category_id 類目ID INT

        category_name 類目名稱 VARCHAR

        brand_name 品牌名稱 VARCHAR

        spec 規(guī)格 VARCHAR

        sale_num 銷(xiāo)量 INT

        comment_num 評(píng)論數(shù) INT

        status 商品狀態(tài) 1-正常,2-下架,3-刪除 CHAR

        2.2 需求與實(shí)現(xiàn)

        2.2.1 需求分析

        詳見(jiàn)靜態(tài)原型。

        2.2.2 實(shí)現(xiàn)思路

        前端傳遞給后端的數(shù)據(jù)格式:

        {
            "spu": {
                "name""這個(gè)是商品名稱",
                "caption""這個(gè)是副標(biāo)題",
                "brandId"12,
                "category1Id"558,
                "category2Id"559,
                "category3Id"560,
                "freightId"10,
                "image""",
                "images"",http://www.qingcheng.com/image/2.jpg",
                "introduction""這個(gè)是商品詳情,html代碼",
                "paraItems": {
                    "出廠年份""2019",
                    "贈(zèng)品""充電器"
                },
                "saleService""七天包退,閃電退貨",
                "sn""020102331",
                "specItems": {
                    "顏色": [
                        "紅",
                        "綠"
                    ],
                    "機(jī)身內(nèi)存": [
                        "64G",
                        "8G"
                    ]
                },
                "templateId"42
            },
            "skuList": [
                {
                    "sn""10192010292",
                    "num"100,
                    "alertNum"20,
                    "price"900000,
                    "spec": {
                        "顏色""紅",
                        "機(jī)身內(nèi)存""64G"
                    },
                    "image""",
                    "images"",http://www.qingcheng.com/image/2.jpg",
                    "status""1",
                    "weight"130
                },
                {
                    "sn""10192010293",
                    "num"100,
                    "alertNum"20,
                    "price"600000,
                    "spec": {
                        "顏色""綠",
                        "機(jī)身內(nèi)存""8G"
                    },
                    "image""",
                    "images"",http://www.qingcheng.com/image/2.jpg",
                    "status""1",
                    "weight"130
                }
            ]
        }

        2.3 代碼實(shí)現(xiàn)

        2.3.1 SPU與SKU列表的保存

        /**
        * 商品組合實(shí)體類 
        */

        public class Goods implements Serializable {

            private Spu spu;

            private List<Sku> skuList;
        }

        SpuServiceImpl新增方法:

        @Autowired
        private SkuMapper skuMapper;
        @Autowired  
        private IdWorker idWorker;
        @Autowired
        private CategoryMapper categoryMapper;

        /**
        * 保存商品
        @param goods 商品組合實(shí)體類
        */

        @Transactional
        public void saveGoods(Goods goods) {
            // 保存一個(gè)spu的信息
            Spu spu = goods.getSpu();
            spu.setId(idWorker.nextId()+"");
            spuMapper.insert(spu);
            
            //保存sku列表的信息
            Date date=new Date();
            //分類對(duì)象
            Category category = categoryMapper.selectByPrimaryKey(spu.getCategory3Id());
            List<Sku> skuList = goods.getSkuList();
            for (Sku sku:skuList){
                sku.setId(idWorker.nextId()+"");
                sku.setSpuId(spu.getId());

                //sku名稱 =spu名稱+規(guī)格值列表
                String name=spu.getName();
                //sku.getSpec() {"顏色":"紅","機(jī)身內(nèi)存":"64G"}
                Map<String,String> specMap = JSON.parseObject(sku.getSpec(), Map.class);
                for(String value:specMap.values()){
                    name+=" "+value;
                }
                sku.setName(name);//名稱
                sku.setCreateTime(date);//創(chuàng)建日期
                sku.setUpdateTime(date);//修改日期
                sku.setCategoryId(spu.getCategory3Id());//分類id
                sku.setCategoryName(category.getName());//分類名稱
                sku.setCommentNum(0);//評(píng)論數(shù)
                sku.setSaleNum(0);//銷(xiāo)售數(shù)量

                skuMapper.insert(sku);
            }
        }

        該方法要對(duì)兩個(gè)表操作,需添加事務(wù):

        @Service(interfaceClass=SpuService.class)

        在類上加@Transactional,并在@Service注解中指定接口為SpuService.class。

        SpuController修改add方法:

        @PostMapping("/save")
        public Result save(@RequestBody Goods goods){
            spuService.saveGoods(goods);
            return new Result();
        }

        3 建立分類與品牌的關(guān)聯(lián)

        3.1 需求

        Q:為什么要建立分類與品牌的關(guān)聯(lián)?

        A:因?yàn)槲覀冊(cè)谇芭_(tái)搜索時(shí),需要通過(guò)分類找到品牌列表。

        Q:分類與品牌是什么關(guān)系?

        A:多對(duì)多。

        Q:在什么地方添加關(guān)系?

        A:我們不在后臺(tái)單獨(dú)實(shí)現(xiàn)分類與品牌的關(guān)聯(lián),而是在添加商品時(shí)自動(dòng)添加關(guān)聯(lián)。

        3.2 實(shí)現(xiàn)思路

        • 設(shè)計(jì)中間表tb_category_brand表
        • 創(chuàng)建實(shí)體類、數(shù)據(jù)訪問(wèn)接口
        • 在添加商品的saveGoods方法中添加代碼邏輯 ,將SPU的品牌編號(hào)和分類編號(hào)一起插入到(中間表)

        3.3 代碼

        創(chuàng)建實(shí)體類

        @Table(name="tb_category_brand")
        @Data
        public class CategoryBrand implements Serializable {
            @Id
            private Integer categoryId;
            @Id 
            private Integer brandId;
        }

        聯(lián)合主鍵,templateId和brandId都有@Id注解。

        新建數(shù)據(jù)訪問(wèn)接口

        public interface CategoryBrandMapper extends Mapper<CategoryBrand{
        }

        修改saveGoods方法

        CategoryBrand categoryBrand =new CategoryBrand();
        categoryBrand.setBrandId(spu.getBrandId());
        categoryBrand.setCategoryId(spu.getCategory3Id());
        int count=categoryBrandMapper.selectCount(categoryBrand);
        if(count==0) {
            categoryBrandMapper.insert(categoryBrand);
        }

        4 根據(jù)ID查詢商品

        根據(jù)id 查詢SPU和SKU列表 ,顯示效果:

        {
            "spu": {
                "brandId"0,
                "caption""111",
                "category1Id"558,
                "category2Id"559,
                "category3Id"560,
                "commentNum"null,
                "freightId"null,
                "id"149187842867993,
                "image"null,
                "images"null,
                "introduction"null,
                "isDelete"null,
                "isEnableSpec""0",
                "isMarketable""1",
                "name""黑馬智能手機(jī)",
                "paraItems"null,
                "saleNum"null,
                "saleService"null,
                "sn"null,
                "specItems"null,
                "status"null,
                "templateId"42
            },
            "skuList": [
                {
                    "alertNum"null,
                    "brandName""金立(Gionee)",
                    "categoryId"560,
                    "categoryName""手機(jī)",
                    "commentNum"null,
                    "createTime""2018‐11‐06 10:17:08",
                    "id"1369324,
                    "image"null,
                    "images""blob:http://localhost:8080/ec04d1a5‐d865‐4e7f‐a313‐2e9a76cfb3f8",
                    "name""黑馬智能手機(jī)",
                    "num"100,
                    "price"900000,
                    "saleNum"null,
                    "sn""",
                    "spec"null,
                    "spuId"149187842867993,
                    "status""1",
                    "updateTime""2018‐11‐06 10:17:08",
                    "weight"null
                },
                {
                    "alertNum"null,
                    "brandName""金立(Gionee)",
                    "categoryId"560,
                    "categoryName""手機(jī)",
                    "commentNum"null,
                    "createTime""2018‐11‐06 10:17:08",
                    "id"1369325,
                    "image"null,
                    "images""blob:http://localhost:8080/ec04d1a5‐d865‐4e7f‐a313‐2e9a76cfb3f8",
                    "name""黑馬智能手機(jī)",
                    "num"100,
                    "price"900000,
                    "saleNum"null,
                    "sn""",
                    "spec"null,
                    "spuId"149187842867993,
                    "status""1",
                    "updateTime""2018‐11‐06 10:17:08",
                    "weight"null
                }
            ]
        }

        4.1 代碼

        SpuService方法

        /**
        * 根據(jù)ID查詢商品
        @param id 
        @return
        */

        public Goods findGoodsById(String id){
            //查詢spu
            Spu spu = spuMapper.selectByPrimaryKey(id);
            
            //查詢SKU 列表
            Example example=new Example(Sku.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("spuId",id);
            List<Sku> skuList = skuMapper.selectByExample(example);
            
            //封裝,返回
            Goods goods=new Goods();
            goods.setSpu(spu);
            goods.setSkuList(skuList);
            return goods;
        }

        SpuController

        @GetMapping("/findGoodsById")
        public Goods findGoodsById(Long id){
            return spuService.findGoodsById(id);
        }

        5 保存修改

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

        • 修改與新增共用同一個(gè)方法
        • 通過(guò)spu的id判斷當(dāng)前操作是新增還是修改
        • 如果是新增需要設(shè)置spu的id,對(duì)spu執(zhí)行的是insert操作
        • 如果修改則需要?jiǎng)h除原來(lái)的sku列表,對(duì)spu執(zhí)行的是updateByPrimaryKeySelective操作
        • sku列表的插入部分的代碼要判斷sku是否有id,如果有id則不重新生成id

        代碼實(shí)現(xiàn)

        修改SpuServiceImpl的saveGoods:

        /**
        * 保存商品
        @param goods
        */

        @Transactional
        public void saveGoods(Goods goods) {
            //保存一個(gè)spu的信息
            Spu spu = goods.getSpu();
            if(spu.getId()==null){//新增商品
                spu.setId(idWorker.nextId()+"");
                spuMapper.insert(spu);
            }else//修改
                //刪除原來(lái)的sku列表
                Example example=new Example(Sku.class);
                Example.Criteria criteria = example.createCriteria();
                criteria.andEqualTo("spuId",spu.getId());
                skuMapper.deleteByExample(example);

                //執(zhí)行spu的修改
                spuMapper.updateByPrimaryKeySelective(spu);
            }

            //保存sku列表的信息
            List<Sku> skuList = goods.getSkuList();
            for (Sku sku:skuList){
                if(sku.getId()==null){//新增
                    sku.setId(idWorker.nextId()+"");
                    sku.setCreateTime(date);//創(chuàng)建日期
                }
                //添加sku
            }

        //建立分類和品牌的關(guān)聯(lián)
        }

        6 未啟用規(guī)格的sku處理

        6.1 需求分析

        有些商品沒(méi)區(qū)分規(guī)格,即一個(gè)spu對(duì)應(yīng)一個(gè)sku ,這時(shí)sku列表只傳遞一條記錄,且無(wú)規(guī)格(spec)屬性,要對(duì)其判斷,避免因空值產(chǎn)生異常。

        6.2 實(shí)現(xiàn)思路

        在saveGoods方法的sku列表循環(huán)中添加代碼,判斷

        // 構(gòu)建SKU名稱,采用SPU+規(guī)格值組裝
        if(sku.getSpec()==null || "".equals(sku.getSpec())){
            sku.setSpec("{}");
        }

        7 商品審核與上下架

        7.1 商品審核

        7.1.1 需求分析與實(shí)現(xiàn)思路

        商品審核:新錄入的商品是未審核狀態(tài),也是未上架狀態(tài)。

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

        • 修改審核狀態(tài),如果審核狀態(tài)為1,則上架狀態(tài)也修改為1
        • 記錄商品審核記錄
        • 記錄商品日志

        7.1.2 代碼實(shí)現(xiàn)

        /**
        * 商品審核
        @param id
        @param status
        @param message
        */

        @Transactional
        public void audit(String id, String status, String message) {
            //1.修改狀態(tài) 審核狀態(tài)和上架狀態(tài)
            Spu spu = new Spu();
            spu.setId(id);
            spu.setStatus(status);
            if("1".equals(status)){//審核通過(guò)
                spu.setIsMarketable("1");//自動(dòng)上架
            }
            spuMapper.updateByPrimaryKeySelective(spu);
            
            //2.記錄商品審核記錄
            
            //3.記錄商品日志
        }
        @GetMapping("/audit")
        public Result audit(Long id){
            spuService.audit(id);
            return new Result();
        }

        7.2 下架商品

        7.2.1 需求與實(shí)現(xiàn)思路

        下架商品,修改上下架狀態(tài)為下架。下架商品不修改審核狀態(tài)。 下架商品需要記錄商品日志。

        7.2.2 代碼實(shí)現(xiàn)

        /**
        * 下架商品
        @param id
        */

        public void pull(String id) {
            Spu spu = spuMapper.selectByPrimaryKey(id);
            spu.setIsMarketable("0");//下架狀態(tài)
            spuMapper.updateByPrimaryKeySelective(spu);
        }
        @GetMapping("/pull")
        public Result pull(String id){
            spuService.pull(id);
            return new Result();
        }

        7.3 上架商品

        7.3.1 需求分析

        將商品修改為上架狀態(tài),需要驗(yàn)證該商品是否審核通過(guò),未審核通過(guò)的商品不能上架。 上架商品需要記錄商品日志。

        7.3.2 代碼實(shí)現(xiàn)

        通過(guò)審核的商品才能上架:

        /**
        * 商品上架
        @param id
        */

        public void put(String id) {
            //1.修改狀態(tài)
            Spu spu = spuMapper.selectByPrimaryKey(id);
            if(!"1".equals(spu.getStatus())){
                throw new RuntimeException("此商品未通過(guò)審核");
            }
            spu.setIsMarketable("1");
            spuMapper.updateByPrimaryKeySelective(spu);
            
            //2.記錄商品日志
        }
        @GetMapping("/put")
        public Result put(String id){
            spuService.put(id);
            return new Result();
        }

        7.4 批量上下架

        7.4.1 需求分析

        前端傳遞一組商品ID,后端進(jìn)行批量上下架處理,處理后給前端返回處理的條數(shù)

        7.4.2 代碼實(shí)現(xiàn)

        /**
        * 批量上架商品
        @param ids
        */

        public int putMany(Long[] ids) {
            Spu spu=new Spu();
            spu.setIsMarketable("1");//上架
            
            //批量修改
            Example example=new Example(Spu.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andIn("id", Arrays.asList(ids));//id
            criteria.andEqualTo("isMarketable","0");//下架
            criteria.andEqualTo("status","1");//審核通過(guò)的
            criteria.andEqualTo("isDelete","0");//非刪除的
            return spuMapper.updateByExampleSelective(spu, example);
        }
        @GetMapping("/putMany")
        public Result putMany(Long[] ids){
            int count = spuService.putMany(ids);
            return new Result(0,"上架"+count+"個(gè)商品");
        }

        8 刪除與還原商品

        8.1 需求分析

        刪除商品并非物理刪除(真正的執(zhí)行刪除數(shù)據(jù)),而是通過(guò)將表中某字段標(biāo)記為刪除狀態(tài)。

        還原商品實(shí)際就是將刪除狀態(tài)再修改回來(lái)。

        如果商品需要物理刪除,必須是先邏輯刪除才能進(jìn)行物理刪除,刪除前需要檢查狀態(tài)。

        8.2 實(shí)現(xiàn)思路

        • 邏輯刪除商品,修改spu表is_delete字段為1
        • 商品回收站顯示spu表is_delete字段為1的記錄
        • 回收商品,修改spu表is_delete字段為0

        寫(xiě)在最后

        公眾號(hào)JavaEdge 專注分享軟件開(kāi)發(fā)全生態(tài)相關(guān)技術(shù)文章、視頻教程資源、熱點(diǎn)資訊等,如果喜歡我的分享,給 ???? 點(diǎn)一個(gè) ?? 或者 ?關(guān)注 都是對(duì)我最大的支持。

        歡迎長(zhǎng)按圖片加好友,我會(huì)第一時(shí)間和你分享軟件行業(yè)趨勢(shì),面試資源,學(xué)習(xí)途徑等等。

        添加好友備注【技術(shù)群交流】拉你進(jìn)技術(shù)交流群

        關(guān)注公眾號(hào)后,在后臺(tái)私信:

        • 回復(fù)架構(gòu)師,獲取架構(gòu)師學(xué)習(xí)資源教程
        • 回復(fù)【面試,獲取最新最全的互聯(lián)網(wǎng)大廠面試資料
        • 回復(fù)【簡(jiǎn),獲取各種樣式精美、內(nèi)容豐富的簡(jiǎn)歷模板
        • 回復(fù) 路線圖,獲取直升Java P7技術(shù)管理的全網(wǎng)最全學(xué)習(xí)路線圖
        • 回復(fù) 大數(shù)據(jù),獲取Java轉(zhuǎn)型大數(shù)據(jù)研發(fā)的全網(wǎng)最全思維導(dǎo)圖
        • 更多教程資源應(yīng)有盡有,歡迎關(guān)注,慢慢獲取

        瀏覽 59
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 国产91精品高潮白浆喷水 | 欧美肏屄视频 | 娇妻玩4p被3个男子伺候 | 美女偷拍自拍 | 大吊视频一区 |