当前位置:网站首页>黑馬暢購商城---3.商品管理
黑馬暢購商城---3.商品管理
2022-06-25 11:57:00 【帥傑IT大神】
學習目標
- SPU與SKU概念理解
1 2
SPU:某一款商品的公共屬性 SKU:某款商品的不同參數對應的商品信息[某個商品]
- ==新增商品、修改商品==
1 2
增加:增加SPU和SKU 修改:修改SPU和SKU
- 商品審核、上架、下架
1 2
審核:修改審核狀態 上架下架:修改上架下架狀態
- 删除商品
1 2
邏輯删除:修改了删除狀態 物理删除:真實删除了數據
- 找回商品
找回商品:一定是屬於邏輯删除的商品
1 SPU與SKU
1.1 SPU與SKU概念
SPU = Standard Product Unit (標准產品單比特)
概念 : SPU 是商品信息聚合的最小單比特,是一組可複用、易檢索的標准化信息的集合,該集合描述了一個產品的特性。
通俗點講,屬性值、特性相同的貨品就可以稱為一個 SPU
==同款商品的公共屬性抽取==
例如:**華為P30 就是一個 SPU**
SKU=stock keeping unit( 庫存量單比特)
SKU 即庫存進出計量的單比特, 可以是以件、盒、托盤等為單比特。
SKU 是物理上不可分割的最小存貨單元。在使用時要根據不同業態,不同管理模式來處理。
在服裝、鞋類商品中使用最多最普遍。
例如:**華為P30 紅色 64G 就是一個 SKU**
==某個庫存單比特的商品獨有屬性(某個商品的獨有屬性)==
1.2 錶結構分析
tb_spu 錶 (SPU錶)
字段名稱 | 字段含義 | 字段類型 | 字段長度 | 備注 |
---|---|---|---|---|
id | 主鍵 | BIGINT | ||
sn | 貨號 | VARCHAR | ||
name | SPU名 | VARCHAR | ||
caption | 副標題 | VARCHAR | ||
brand_id | 品牌ID | INT | ||
category1_id | 一級分類 | INT | ||
category2_id | 二級分類 | INT | ||
category3_id | 三級分類 | INT | ||
template_id | 模板ID | INT | ||
freight_id | 運費模板id | INT | ||
image | 圖片 | VARCHAR | ||
images | 圖片列錶 | VARCHAR | ||
sale_service | 售後服務 | VARCHAR | ||
introduction | 介紹 | TEXT | ||
spec_items | 規格列錶 | VARCHAR | ||
para_items | 參數列錶 | VARCHAR | ||
sale_num | 銷量 | INT | ||
comment_num | 評論數 | INT | ||
is_marketable | 是否上架 | CHAR | ||
is_enable_spec | 是否啟用規格 | CHAR | ||
is_delete | 是否删除 | CHAR | ||
status | 審核狀態 | CHAR |
tb_sku 錶(SKU商品錶)
字段名稱 | 字段含義 | 字段類型 | 字段長度 | 備注 |
---|---|---|---|---|
id | 商品id | BIGINT | ||
sn | 商品條碼 | VARCHAR | ||
name | SKU名稱 | VARCHAR | ||
price | 價格(分) | INT | ||
num | 庫存數量 | INT | ||
alert_num | 庫存預警數量 | INT | ||
image | 商品圖片 | VARCHAR | ||
images | 商品圖片列錶 | VARCHAR | ||
weight | 重量(克) | INT | ||
create_time | 創建時間 | DATETIME | ||
update_time | 更新時間 | DATETIME | ||
spu_id | SPUID | BIGINT | ||
category_id | 類目ID | INT | ||
category_name | 類目名稱 | VARCHAR | ||
brand_name | 品牌名稱 | VARCHAR | ||
spec | 規格 | VARCHAR | ||
sale_num | 銷量 | INT | ||
comment_num | 評論數 | INT | ||
status | 商品狀態 1-正常,2-下架,3-删除 | CHAR |
2 新增和修改商品
2.1 需求分析
實現商品的新增與修改功能。
(1)第1個步驟,先選擇添加的商品所屬分類
這塊在第2天的代碼中已經有一個根據父節點ID查詢分類信息的方法,參考第2天的4.3.4的findByPrantId方法,首先查詢頂級分類,也就是pid=0,然後根據用戶選擇的分類,將選擇的分類作為pid查詢子分類。
(2)第2個步驟,填寫SPU的信息
(3)第3個步驟,填寫SKU信息
先進入選擇商品分類 再填寫商品的信息 填寫商品的屬性添加商品。
2.2 實現思路
前端傳遞給後端的數據格式 是一個spu對象和sku列錶組成的對象,如下圖:
上圖JSON數據如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
{ "spu": { "name": "這個是商品名稱", "caption": "這個是副標題", "brandId": 12, "category1Id": 558, "category2Id": 559, "category3Id": 560, "freightId": 10, "image": "http://www.qingcheng.com/image/1.jpg", "images": "http://www.qingcheng.com/image/1.jpg,http://www.qingcheng.com/image/2.jpg", "introduction": "這個是商品詳情,html代碼", "paraItems": { "出廠年份": "2019", "贈品": "充電器" }, "saleService": "七天包退,閃電退貨", "sn": "020102331", "specItems": { "顏色": [ "紅", "綠" ], "機身內存": [ "64G", "8G" ] }, "templateId": 42 }, "skuList": [ { "sn": "10192010292", "num": 100, "alertNum": 20, "price": 900000, "spec": { "顏色": "紅", "機身內存": "64G" }, "image": "http://www.qingcheng.com/image/1.jpg", "images": "http://www.qingcheng.com/image/1.jpg,http://www.qingcheng.com/image/2.jpg", "status": "1", "weight": 130 }, { "sn": "10192010293", "num": 100, "alertNum": 20, "price": 600000, "spec": { "顏色": "綠", "機身內存": "8G" }, "image": "http://www.qingcheng.com/image/1.jpg", "images": "http://www.qingcheng.com/image/1.jpg,http://www.qingcheng.com/image/2.jpg", "status": "1", "weight": 130 } ] }
2.3 代碼生成
准備工作:為了更快的實現代碼編寫,我們可以采用《黑馬代碼生成器》來批量生成代碼,這些代碼就已經實現了我們之前的增删改查功能。
《黑馬代碼生成器》一款由傳智播客教育集團JavaEE教研團隊開發的基於Freemarker模板引擎的“代碼生成神器”。即便是一個工程幾百個錶,也可以瞬間完成基礎代碼的構建!用戶只需建立數據庫錶結構,運行main方法就可快速生成可以運行的一整套代碼,可以極大地縮短開發周期,降低人力成本。《黑馬代碼生成器》的誕生主要用於迅速構建生成微服務工程的Pojo、Dao、Service、Controller各層、並且可以生成swagger API模板等。 用戶通過自己開發模板也可以實現生成php、python、C# 、c++、數據庫存儲過程等其它編程語言的代碼。
《黑馬代碼生成器》目前已經開源 地址:https://github.com/shenkunlin/code-template.git
如下圖資料,將其導入到idea中 並執行即可:
使用說明,簡單來說如下圖所示:
2.4 代碼實現
一會兒會用到ID生成,我們可以使用IdWorker,在啟動類GoodsApplication中添加如下代碼,用於創建IdWorker,並將IdWorker交給Spring容器,代碼如下:
1 2 3 4 5 6 7 8
/*** * IdWorker * @return */ @Bean public IdWorker idWorker(){ return new IdWorker(0,0); }
2.4.1 查詢分類
2.4.1.1 分析
在實現商品增加之前,需要先選擇對應的分類,選擇分類的時候,首選選擇一級分類,然後根據選中的分類,將選中的分類作為查詢的父ID,再查詢對應的子分類集合,因此我們可以在後臺編寫一個方法,根據父類ID查詢對應的分類集合即可。
2.4.1.2 代碼實現
(1)Service層
修改com.changgou.goods.service.CategoryService
添加根據父類ID查詢所有子節點,代碼如下:
1 2 3 4
/*** * 根據分類的父ID查詢子分類節點集合 */ List<Category> findByParentId(Integer pid);
修改com.changgou.goods.service.impl.CategoryServiceImpl
添加上面的實現,代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12
/*** * 根據分類的父節點ID查詢所有子節點 * @param pid * @return */ @Override public List<Category> findByParentId(Integer pid) { //SELECT * FROM tb_category WHERE parent_id=? Category category = new Category(); category.setParentId(pid); return categoryMapper.select(category); }
(2)Controller層
修改com.changgou.goods.controller.CategoryController
添加根據父ID查詢所有子類集合,代碼如下:
1 2 3 4 5 6 7 8 9
/**** * 根據節點ID查詢所有子節點分類集合 */ @GetMapping(value = "/list/{pid}") public Result<List<Category>> findByParentId(@PathVariable(value = "pid")Integer pid){ //調用Service實現查詢 List<Category> categories = categoryService.findByParentId(pid); return new Result<List<Category>>(true,StatusCode.OK,"查詢成功!",categories); }
2.4.2 模板查詢(規格參數組)
同學作業
2.4.2.1 分析
如上圖,當用戶選中了分類後,需要根據分類的ID查詢出對應的模板數據,並將模板的名字顯示在這裏,模板錶結構如下:
1 2 3 4 5 6 7
CREATE TABLE `tb_template` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID', `name` varchar(50) DEFAULT NULL COMMENT '模板名稱', `spec_num` int(11) DEFAULT '0' COMMENT '規格數量', `para_num` int(11) DEFAULT '0' COMMENT '參數數量', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8;
2.4.2.2 代碼實現
(1)Service層
修改com.changgou.goods.service.TemplateService
接口,添加如下方法根據分類ID查詢模板:
1 2 3 4 5 6
/** * 根據分類ID查詢模板信息 * @param id * @return */ Template findByCategoryId(Integer id);
修改com.changgou.goods.service.impl.TemplateServiceImpl
添加上面方法的實現:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
@Autowired private CategoryMapper categoryMapper; /*** * 根據分類ID查詢模板信息 * @param id * @return */ @Override public Template findByCategoryId(Integer id) { //查詢分類信息 Category category = categoryMapper.selectByPrimaryKey(id); //根據模板Id查詢模板信息 return templateMapper.selectByPrimaryKey(category.getTemplateId()); }
(2)Controller層
修改com.changgou.goods.controller.TemplateController
,添加根據分類ID查詢模板數據:
1 2 3 4 5 6 7 8 9 10
/*** * 根據分類查詢模板數據 * @param id:分類ID */ @GetMapping(value = "/category/{id}") public Result<Template> findByCategoryId(@PathVariable(value = "id")Integer id){ //調用Service查詢 Template template = templateService.findByCategoryId(id); return new Result<Template>(true, StatusCode.OK,"查詢成功",template); }
2.4.3 查詢分類品牌數據
2.4.3.1 分析
用戶每次選擇了分類之後,可以根據用戶選擇的分類到tb_category_brand
錶中查詢指定的品牌集合ID,然後根據品牌集合ID查詢對應的品牌集合數據,再將品牌集合數據拿到這裏來展示即可實現上述功能。
2.4.3.2 代碼實現
(1)Dao實現
修改com.changgou.goods.dao.BrandMapper
添加根據分類ID查詢對應的品牌數據,代碼如下:
1 2 3 4 5 6 7 8
public interface BrandMapper extends Mapper<Brand> { /*** * 查詢分類對應的品牌集合 */ @Select("SELECT tb.* FROM tb_category_brand tcb,tb_brand tb WHERE tcb.category_id=#{categoryid} AND tb.id=tcb.brand_id") List<Brand> findByCategory(Integer categoryid); }
(2)Service層
修改com.changgou.goods.service.BrandService
,添加根據分類ID查詢指定的品牌集合方法,代碼如下:
1 2 3 4 5
/*** * 根據分類ID查詢品牌集合 * @param categoryid:分類ID */ List<Brand> findByCategory(Integer categoryid);
修改com.changgou.goods.service.impl.BrandServiceImpl
添加上面方法的實現,代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
/*** * 根據分類ID查詢品牌集合 * @param categoryid:分類ID * @return */ @Override public List<Brand> findByCategory(Integer categoryid) { //1.查詢當前分類所對應的所有品牌信息 //2.根據品牌ID查詢對應的品牌集合 //自己創建DAO實現查詢 return brandMapper.findByCategory(categoryid); }
(3)Controller層
修改,添加根據分類ID查詢對應的品牌數據代碼如下:
1 2 3 4 5 6 7 8 9 10
/*** * 根據分類實現品牌列錶查詢 * /brand/category/{id} 分類ID */ @GetMapping(value = "/category/{id}") public Result<List<Brand>> findBrandByCategory(@PathVariable(value = "id")Integer categoryId){ //調用Service查詢品牌數據 List<Brand> categoryList = brandService.findByCategory(categoryId); return new Result<List<Brand>>(true,StatusCode.OK,"查詢成功!",categoryList); }
2.4.4 規格查詢
2.4.4.1 分析
用戶選擇分類後,需要根據所選分類對應的模板ID查詢對應的規格,規格錶結構如下:
1 2 3 4 5 6 7 8
CREATE TABLE `tb_spec` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID', `name` varchar(50) DEFAULT NULL COMMENT '名稱', `options` varchar(2000) DEFAULT NULL COMMENT '規格選項', `seq` int(11) DEFAULT NULL COMMENT '排序', `template_id` int(11) DEFAULT NULL COMMENT '模板ID', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8;
2.4.4.2 代碼實現
(1)Service層
修改com.changgou.goods.service.SpecService
添加根據分類ID查詢規格列錶,代碼如下:
1 2 3 4 5 6
/*** * 根據分類ID查詢規格列錶 * @param categoryid * @return */ List<Spec> findByCategoryId(Integer categoryid);
修改com.changgou.goods.service.impl.SpecServiceImpl
添加上面方法的實現,代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
@Autowired private CategoryMapper categoryMapper; /*** * 根據分類ID查詢規格列錶 * @param categoryid * @return */ @Override public List<Spec> findByCategoryId(Integer categoryid) { //查詢分類 Category category = categoryMapper.selectByPrimaryKey(categoryid); //根據分類的模板ID查詢規格 Spec spec = new Spec(); spec.setTemplateId(category.getTemplateId()); return specMapper.select(spec); }
(2)Controller層
修改com.changgou.goods.controller.SpecController
添加根據分類ID查詢規格數據,代碼如下:
1 2 3 4 5 6 7 8 9
/*** * 根據分類ID查詢對應的規格列錶 */ @GetMapping(value = "/category/{id}") public Result<List<Spec>> findByCategoryId(@PathVariable(value = "id")Integer categoryid){ //調用Service查詢 List<Spec> specs = specService.findByCategoryId(categoryid); return new Result<List<Spec>>(true, StatusCode.OK,"查詢成功",specs); }
2.4.5 參數列錶查詢
2.4.5.1 分析
當用戶選中分類後,需要根據分類的模板ID查詢對應的參數列錶,參數錶結構如下:
1 2 3 4 5 6 7 8
CREATE TABLE `tb_para` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id', `name` varchar(50) DEFAULT NULL COMMENT '名稱', `options` varchar(2000) DEFAULT NULL COMMENT '選項', `seq` int(11) DEFAULT NULL COMMENT '排序', `template_id` int(11) DEFAULT NULL COMMENT '模板ID', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
2.4.5.2 代碼實現
(1)Service層
修改com.changgou.goods.service.ParaService
添加根據分類ID查詢參數列錶,代碼如下:
1 2 3 4 5 6
/*** * 根據分類ID查詢參數列錶 * @param id * @return */ List<Para> findByCategoryId(Integer id);
修改com.changgou.goods.service.impl.ParaServiceImpl
添加上面方法的實現,代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
@Autowired private CategoryMapper categoryMapper; /*** * 根據分類ID查詢參數列錶 * @param id * @return */ @Override public List<Para> findByCategoryId(Integer id) { //查詢分類信息 Category category = categoryMapper.selectByPrimaryKey(id); //根據分類的模板ID查詢參數列錶 Para para = new Para(); para.setTemplateId(category.getTemplateId()); return paraMapper.select(para); }
(2)Controller層
修改com.changgou.goods.controller.ParaController
,添加根據分類ID查詢參數列錶,代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12
/** * 根據分類ID查詢參數列錶 * @param id * @return */ @GetMapping(value = "/category/{id}") public Result<List<Para>> getByCategoryId(@PathVariable(value = "id")Integer id){ //根據分類ID查詢對應的參數信息 List<Para> paras = paraService.findByCategoryId(id); Result<List<Para>> result = new Result<List<Para>>(true,StatusCode.OK,"查詢分類對應的品牌成功!",paras); return result; }
2.4.6 SPU+SKU保存
2.4.6.1 分析
保存商品數據的時候,需要保存Spu和Sku,一個Spu對應多個Sku,我們可以先構建一個Goods對象,將Spu
和List<Sku>
組合到一起,前端將2者數據提交過來,再實現添加操作。
2.4.62 代碼實現
(1)Pojo改造
修改changgou-service-goods-api工程創建組合實體類,創建com.changgou.goods.pojo.Goods,代碼如下:
1 2 3 4 5 6 7 8
public class Goods implements Serializable { //SPU private Spu spu; //SKU集合 private List<Sku> skuList; //..get..set..toString }
(2) 業務層
修改com.changgou.goods.service.SpuService接口,添加保存Goods方法,代碼如下:
1 2 3 4 5
/** * 保存商品 * @param goods */ void saveGoods(Goods goods);
修改com.changgou.goods.service.impl.SpuServiceImpl類,添加保存Goods的方法實現,代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
@Autowired private IdWorker idWorker; @Autowired private CategoryMapper categoryMapper; @Autowired private BrandMapper brandMapper; @Autowired private SkuMapper skuMapper; /*** * 保存Goods * @param goods */ @Override public void saveGoods(Goods goods) { //增加Spu Spu spu = goods.getSpu(); spu.setId(idWorker.nextId()); spuMapper.insertSelective(spu); //增加Sku Date date = new Date(); Category category = categoryMapper.selectByPrimaryKey(spu.getCategory3Id()); Brand brand = brandMapper.selectByPrimaryKey(spu.getBrandId()); //獲取Sku集合 List<Sku> skus = goods.getSkus(); //循環將數據加入到數據庫 for (Sku sku : skus) { //構建SKU名稱,采用SPU+規格值組裝 if(StringUtils.isEmpty(sku.getSpec())){ sku.setSpec("{}"); } //獲取Spu的名字 String name = spu.getName(); //將規格轉換成Map Map<String,String> specMap = JSON.parseObject(sku.getSpec(), Map.class); //循環組裝Sku的名字 for (Map.Entry<String, String> entry : specMap.entrySet()) { name+=" "+entry.getValue(); } sku.setName(name); //ID sku.setId(idWorker.nextId()); //SpuId sku.setSpuId(spu.getId()); //創建日期 sku.setCreateTime(date); //修改日期 sku.setUpdateTime(date); //商品分類ID sku.setCategoryId(spu.getCategory3Id()); //分類名字 sku.setCategoryName(category.getName()); //品牌名字 sku.setBrandName(brand.getName()); //增加 skuMapper.insertSelective(sku); } }
(3)控制層
修改com.changgou.goods.controller.SpuController,增加保存Goods方法,代碼如下:
1 2 3 4 5 6 7 8 9 10
/*** * 添加Goods * @param goods * @return */ @PostMapping("/save") public Result save(@RequestBody Goods goods){ spuService.saveGoods(goods); return new Result(true,StatusCode.OK,"保存成功"); }
測試數據
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
{ "skuList": [ { "alertNum": 10, "brandName": "華為", "categoryId": 64, "commentNum": 0, "image": "http://www.baidu.com", "images": "", "name": "華為P30手機", "num": 5, "price": 1000, "saleNum": 0, "sn": "No1001", "spec": "{\"顏色\":\"紅色\",\"網絡\":\"移動3G\"}", "weight": 0 } ], "spu": { "brandId": 8557, "caption": "華為手機大促銷", "category1Id": 1, "category2Id": 59, "category3Id": 64, "commentNum": 0, "freightId": 0, "images": "http://www.qingcheng.com/image/1.jpg,http://www.qingcheng.com/image/2.jpg", "introduction": "華為產品世界最强", "isEnableSpec": "1", "isMarketable": "1", "name": "string", "specItems": "{\"顏色\":[\"紅\",\"綠\"],\"機身內存\":[\"64G\",\"8G\"]}", "paraItems": "{\"贈品\":\"充電器\",\"出廠年份\":\"2019\"}", "saleNum": 0, "saleService": "一年包換", "sn": "No10001", "status": "1", "templateId": 42 } }
2.4.7 根據ID查詢商品
2.4.7.1 需求分析
需求:根據id 查詢SPU和SKU列錶 ,顯示效果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
{ "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": "黑馬智能手機", "paraItems": null, "saleNum": null, "saleService": null, "sn": null, "specItems": null, "status": null, "templateId": 42 }, "skuList": [{ "alertNum": null, "brandName": "金立(Gionee)", "categoryId": 560, "categoryName": "手機", "commentNum": null, "createTime": "2018-11-06 10:17:08", "id": 1369324, "image": null, "images": "blob:http://localhost:8080/ec04d1a5-d865-4e7f-a313-2e9a76cfb3f8", "name": "黑馬智能手機", "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": "手機", "commentNum": null, "createTime": "2018-11-06 10:17:08", "id": 1369325, "image": null, "images": "blob:http://localhost:8080/ec04d1a5-d865-4e7f-a313-2e9a76cfb3f8", "name": "黑馬智能手機", "num": 100, "price": 900000, "saleNum": null, "sn": "", "spec": null, "spuId": 149187842867993, "status": "1", "updateTime": "2018-11-06 10:17:08", "weight": null } ] }
2.4.7.2 代碼實現
(1)業務層
修改qingcheng-service-goods工程,修改com.changgou.goods.service.SpuService接口,添加根據ID查找方法findGoodsById代碼如下:
1 2 3 4 5
/*** * 根據SPU的ID查找SPU以及對應的SKU集合 * @param spuId */ Goods findGoodsById(Long spuId);
修改qingcheng-service-goods工程,修改com.changgou.goods.service.impl.SpuServiceImpl類,添加根據ID查找findGoodsById方法,代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*** * 根據SpuID查詢goods信息 * @param spuId * @return */ @Override public Goods findGoodsById(Long spuId) { //查詢Spu Spu spu = spuMapper.selectByPrimaryKey(spuId); //查詢List<Sku> Sku sku = new Sku(); sku.setSpuId(spuId); List<Sku> skus = skuMapper.select(sku); //封裝Goods Goods goods = new Goods(); goods.setSkus(skus); goods.setSpu(spu); return goods; }
(2)控制層
修改com.changgou.goods.controller.SpuController,修改findById方法,代碼如下:
1 2 3 4 5 6 7 8 9 10 11
/*** * 根據ID查詢Goods * @param id * @return */ @GetMapping("/goods/{id}") public Result<Goods> findGoodsById(@PathVariable Long id){ //根據ID查詢Goods(SPU+SKU)信息 Goods goods = spuService.findGoodsById(id); return new Result<Goods>(true,StatusCode.OK,"查詢成功",goods); }
測試:http://localhost:18081/spu/goods/1088256029394866176
2.4.8 保存修改
修改changgou-service-goods的SpuServiceImpl的saveGoods方法,修改添加SPU部分代碼:
上圖代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12
if(spu.getId()==null){ //增加 spu.setId(idWorker.nextId()); spuMapper.insertSelective(spu); }else{ //修改數據 spuMapper.updateByPrimaryKeySelective(spu); //删除該Spu的Sku Sku sku = new Sku(); sku.setSpuId(spu.getId()); skuMapper.delete(sku); }
2.4.9 修改SKU庫存
(學員實現)
3 商品審核與上下架
3.1 需求分析
商品新增後,審核狀態為0(未審核),默認為下架狀態。
審核商品,需要校驗是否是被删除的商品,如果未删除則修改審核狀態為1,並自動上架
下架商品,需要校驗是否是被删除的商品,如果未删除則修改上架狀態為0
上架商品,需要審核通過的商品
3.2 實現思路
(1)按照ID查詢SPU信息
(2)判斷修改審核、上架和下架狀態
(3)保存SPU
3.3 代碼實現
3.3.1 商品審核
實現審核通過,自動上架。
(1)業務層
修改修改changgou-service-goods工程的com.changgou.goods.service.SpuService接口,添加審核方法,代碼如下:
1 2 3 4 5
/*** * 商品審核 * @param spuId */ void audit(Long spuId);
修改changgou-service-goods工程的com.changgou.goods.service.impl.SpuServiceImpl類,添加audit方法,代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*** * 商品審核 * @param spuId */ @Override public void audit(Long spuId) { //查詢商品 Spu spu = spuMapper.selectByPrimaryKey(spuId); //判斷商品是否已經删除 if(spu.getIsDelete().equalsIgnoreCase("1")){ throw new RuntimeException("該商品已經删除!"); } //實現上架和審核 spu.setStatus("1"); //審核通過 spu.setIsMarketable("1"); //上架 spuMapper.updateByPrimaryKeySelective(spu); }
(2)控制層
修改com.changgou.goods.controller.SpuController,新增audit方法,代碼如下:
1 2 3 4 5 6 7 8 9 10
/** * 審核 * @param id * @return */ @PutMapping("/audit/{id}") public Result audit(@PathVariable Long id){ spuService.audit(id); return new Result(true,StatusCode.OK,"審核成功"); }
3.3.2 下架商品
(1)業務層
修改com.changgou.goods.service.SpuService接口,添加pull方法,用於商品下架,代碼如下:
1 2 3 4 5
/*** * 商品下架 * @param spuId */ void pull(Long spuId);
修改com.changgou.goods.service.impl.SpuServiceImpl,添加如下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13
/** * 商品下架 * @param spuId */ @Override public void pull(Long spuId) { Spu spu = spuMapper.selectByPrimaryKey(spuId); if(spu.getIsDelete().equals("1")){ throw new RuntimeException("此商品已删除!"); } spu.setIsMarketable("0");//下架狀態 spuMapper.updateByPrimaryKeySelective(spu); }
(2)控制層
修改com.changgou.goods.controller.SpuController,添加pull方法,代碼如下:
1 2 3 4 5 6 7 8 9 10
/** * 下架 * @param id * @return */ @PutMapping("/pull/{id}") public Result pull(@PathVariable Long id){ spuService.pull(id); return new Result(true,StatusCode.OK,"下架成功"); }
3.3.3 上架商品
必須是通過審核的商品才能上架
(1)業務層
修改com.changgou.goods.service.SpuService,添加put方法,代碼如下:
1 2 3 4 5
/*** * 商品上架 * @param spuId */ void put(Long spuId);
修改com.changgou.goods.service.impl.SpuServiceImpl,添加put方法實現,代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*** * 商品上架 * @param spuId */ @Override public void put(Long spuId) { Spu spu = spuMapper.selectByPrimaryKey(spuId); //檢查是否删除的商品 if(spu.getIsDelete().equals("1")){ throw new RuntimeException("此商品已删除!"); } if(!spu.getStatus().equals("1")){ throw new RuntimeException("未通過審核的商品不能!"); } //上架狀態 spu.setIsMarketable("1"); spuMapper.updateByPrimaryKeySelective(spu); }
(2)控制層
修改com.changgou.goods.controller.SpuController,添加put方法代碼如下:
1 2 3 4 5 6 7 8 9 10
/** * 商品上架 * @param id * @return */ @PutMapping("/put/{id}") public Result put(@PathVariable Long id){ spuService.put(id); return new Result(true,StatusCode.OK,"上架成功"); }
3.3.4 批量上架
前端傳遞一組商品ID,後端進行批量上下架處理
(1)業務層
修改com.changgou.goods.service.SpuService接口,代碼如下:
int putMany(Long[] ids);
修改com.changgou.goods.service.impl.SpuServiceImpl,添加批量上架方法實現,代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*** * 批量上架 * @param ids:需要上架的商品ID集合 * @return */ @Override 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"); //非删除的 criteria.andEqualTo("isDelete","0"); return spuMapper.updateByExampleSelective(spu, example); }
(2)控制層
修改com.changgou.goods.controller.SpuController,天啊及批量上架方法,代碼如下:
1 2 3 4 5 6 7 8 9 10
/** * 批量上架 * @param ids * @return */ @PutMapping("/put/many") public Result putMany(@RequestBody Long[] ids){ int count = spuService.putMany(ids); return new Result(true,StatusCode.OK,"上架"+count+"個商品"); }
使用Postman測試:
3.3.5 批量下架
學員實現
4 删除與還原商品
4.1 需求分析
請看管理後臺的靜態原型
商品列錶中的删除商品功能,並非真正的删除,而是將删除標記的字段設置為1,
在回收站中有恢複商品的功能,將删除標記的字段設置為0
在回收站中有删除商品的功能,是真正的物理删除。
4.2 實現思路
邏輯删除商品,修改spu錶is_delete字段為1
商品回收站顯示spu錶is_delete字段為1的記錄
回收商品,修改spu錶is_delete字段為0
4.3 代碼實現
4.3.1 邏輯删除商品
(1)業務層
修改com.changgou.goods.service.SpuService接口,增加logicDelete方法,代碼如下:
1 2 3 4 5
/*** * 邏輯删除 * @param spuId */ void logicDelete(Long spuId);
修改com.changgou.goods.service.impl.SpuServiceImpl,添加logicDelete方法實現,代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*** * 邏輯删除 * @param spuId */ @Override @Transactional public void logicDelete(Long spuId) { Spu spu = spuMapper.selectByPrimaryKey(spuId); //檢查是否下架的商品 if(!spu.getIsMarketable().equals("0")){ throw new RuntimeException("必須先下架再删除!"); } //删除 spu.setIsDelete("1"); //未審核 spu.setStatus("0"); spuMapper.updateByPrimaryKeySelective(spu); }
(2)控制層
修改com.changgou.goods.controller.SpuController,添加logicDelete方法,如下:
1 2 3 4 5 6 7 8 9 10
/** * 邏輯删除 * @param id * @return */ @DeleteMapping("/logic/delete/{id}") public Result logicDelete(@PathVariable Long id){ spuService.logicDelete(id); return new Result(true,StatusCode.OK,"邏輯删除成功!"); }
4.3.2 還原被删除的商品
(1)業務層
修改com.changgou.goods.service.SpuService接口,添加restore方法代碼如下:
1 2 3 4 5
/*** * 還原被删除商品 * @param spuId */ void restore(Long spuId);
修改com.changgou.goods.service.impl.SpuServiceImpl類,添加restore方法,代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/** * 恢複數據 * @param spuId */ @Override public void restore(Long spuId) { Spu spu = spuMapper.selectByPrimaryKey(spuId); //檢查是否删除的商品 if(!spu.getIsDelete().equals("1")){ throw new RuntimeException("此商品未删除!"); } //未删除 spu.setIsDelete("0"); //未審核 spu.setStatus("0"); spuMapper.updateByPrimaryKeySelective(spu); }
(2)控制層
修改com.changgou.goods.controller.SpuController,添加restore方法,代碼如下:
1 2 3 4 5 6 7 8 9 10
/** * 恢複數據 * @param id * @return */ @PutMapping("/restore/{id}") public Result restore(@PathVariable Long id){ spuService.restore(id); return new Result(true,StatusCode.OK,"數據恢複成功!"); }
4.3.3 物理删除商品
修改com.changgou.goods.service.impl.SpuServiceImpl的delete方法,代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
/** * 删除 * @param id */ @Override public void delete(Long id){ Spu spu = spuMapper.selectByPrimaryKey(id); //檢查是否被邏輯删除 ,必須先邏輯删除後才能物理删除 if(!spu.getIsDelete().equals("1")){ throw new RuntimeException("此商品不能删除!"); } spuMapper.deleteByPrimaryKey(id); }
5 商品列錶
5.1 需求分析
如圖所示 展示商品的列錶。並實現分頁。
思路:
1 2
根據查詢的條件 分頁查詢 並返回分頁結果即可。 分頁查詢 采用 pagehelper ,條件查詢 通過map進行封裝傳遞給後臺即可。
5.2 代碼實現
在代碼生成器生成的代碼中已經包含了該實現,這裏就省略了。
控制層(SpuController):
1 2 3 4 5 6 7 8 9 10 11 12 13
/*** * Spu分頁條件搜索實現 * @param spu * @param page * @param size * @return */ @PostMapping(value = "/search/{page}/{size}" ) public Result<PageInfo> findPage(@RequestBody(required = false) Spu spu, @PathVariable int page, @PathVariable int size){ //執行搜索 PageInfo<Spu> pageInfo = spuService.findPage(spu, page, size); return new Result(true,StatusCode.OK,"查詢成功",pageInfo); }
其他每層代碼,代碼生成器已經生成,這裏就不再列出來了。
边栏推荐
- Cesium building loading (with height)
- How to use the markdown editor
- Manually rollback abnormal data
- Xishan technology rushes to the scientific innovation board: it plans to raise 660million yuan. Guoyijun and his wife have 60% of the voting rights
- CFCA Anxin sign access
- Deeply understand Flink SQL execution process based on flink1.12
- try-catch-finally
- Is the online stock trading account opening ID card information safe?
- Mui scroll bar recovery
- WebRTC Native M96 基础Base模块介绍之网络相关的封装
猜你喜欢
Deeply understand Flink SQL execution process based on flink1.12
Caused by: org. xml. sax. SAXParseException; lineNumber: 1; columnNumber: 10; Processing matching '[xx][mm][ll]' is not allowed
Nacos installation and use
Eureka accesses the console and reports an error: whitelabel error page
ROS notes (06) - definition and use of topic messages
Research on parallel computing architecture of meteorological early warning based on supercomputing platform
使用php脚本查看已开启的扩展
Database Series: MySQL index optimization summary (comprehensive version)
Sentinel integrated Nacos data source
Source code analysis of AQS & reentrantlock
随机推荐
Redis6 note02 configuration file, publish and subscribe, new data type, jedis operation
Detailed explanation of Flink checkpoint specific operation process and summary of error reporting and debugging methods
ThingsPanel 发布物联网手机客户端(多图)
VFP develops a official account to receive coupons, and users will jump to various target pages after registration, and a set of standard processes will be sent to you
ROS notes (06) - definition and use of topic messages
Spark runs wordcount (case 1)
Capacity expansion mechanism of Dict Of redis (rehash)
分享7个神仙壁纸网站,让新的壁纸,给自己小小的雀跃,不陷入年年日日的重复。
优品购电商3.0微服务商城项目实战小结
Manually rollback abnormal data
Actual combat summary of Youpin e-commerce 3.0 micro Service Mall project
VFP function to summarize all numeric columns of grid to cursor
Redis雪崩、穿透和击穿是什么?
TCP如何處理三次握手和四次揮手期間的异常
quarkus saas动态数据源切换实现,简单完美
Nacos installation and use
Record the process of submitting code to openharmony once
Simple use of stream (II)
The service layer reports an error. The XXX method invalid bound statement (not found) cannot be found
時創能源沖刺科創板:擬募資11億 年營收7億淨利反降36%