Day04 sku与spu接口

一、答疑

1、Docker

① 如果在创建容器的时候,没有进行端口映射和卷的挂载,后来又想添加,我们如何做呢?

docker update 不行

把docker容器的核心内容docker cp出来,再启动一个新容器挂载

② 如何创建nacos的容器镜像呢,和Sentinel完全不一样?

FROM alpine
COPY ./nacos /app/nacos

ENTRYPOINT [“sh”,"/app/nacos/bin/startup.sh"]

2、SQL

① 怎么优化SQL的sendingdata的时间?感觉很影响整体速度。

select 不写* ,查少量列

select where 限制好,只查到核心内容

② 一条读写sql语句的执行过程就是按照架构图上面的顺序吗?

连接器 —> 语法分析器 —> 优化器 —> 执行器


二、品牌的CRUD

1、新增品牌

文档

接口 http://api.gmall.com/admin/product/baseTrademark/save
请求参数 {tmName: “锤子。”, logoUrl: “/static/default.jpg”}
请求方式 post
例: http://api.gmall.com/admin/product/baseTrademark/save
返回值 {code: 200, message: “成功”, data: null, ok: true}

BaseTrademarkController

/*** 添加品牌* 请求参数:{tmName: "锤子。", logoUrl: "/static/default.jpg"}* @param baseTrademark* @return*/
@PostMapping("/baseTrademark/save")
public Result baseTrademarkSave(@RequestBody BaseTrademark baseTrademark){log.info("baseTrademark:{}",baseTrademark);baseTrademarkService.save(baseTrademark);return Result.ok();
}

对照 BaseTrademark

BaseTrademark

@Data
@ApiModel(description = "商标品牌")
@TableName("base_trademark")
public class BaseTrademark extends BaseEntity {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "属性值")@TableField("tm_name")private String tmName;@ApiModelProperty(value = "品牌logo的图片路径")@TableField("logo_url")private String logoUrl;}

2、修改品牌

文档

接口 http://api.gmall.com/admin/product/baseTrademark/update
请求参数 baseTrademark的json字符串
请求方式 put
例: http://api.gmall.com/admin/product/baseTrademark/update
返回值 {code: 200, message: “成功”, data: null, ok: true}

BaseTrademarkController

/*** 修改品牌* @param baseTrademark* @return*/
@PutMapping("/baseTrademark/update")
public Result baseTrademarkUpdate(@RequestBody BaseTrademark baseTrademark){baseTrademarkService.updateById(baseTrademark);return Result.ok();
}

3、删除品牌

文档

接口 http://api.gmall.com/admin/product/baseTrademark/remove/{id}
请求参数 品牌Id
请求方式 delete
例: http://api.gmall.com/admin/product/baseTrademark/remove/1
返回值 {code: 200, message: “成功”, data: null, ok: true}

BaseTrademarkController

/*** 删除品牌* @param id* @return*/
@DeleteMapping("/baseTrademark/remove/{id}")
public Result baseTrademarkRemove(@PathVariable("id") Long id){baseTrademarkService.removeById(id);return Result.ok();
}

4、根据Id获取品牌

文档

接口 http://api.gmall.com/admin/product/baseTrademark/get/{id}
请求参数 品牌Id
请求方式 get
例: http://api.gmall.com/admin/product/baseTrademark/get/1
返回值 {
“code”: 200,
“message”: “成功”,
“data”: {
“id”: 1,
“tmName”: “苹果”,
“logoUrl”: “http://192.168.200.128:8080/group1/M00/00/00/wKjIgF5r8hSELUs1AAAAAIyTSXk960.png”
},
“ok”: true
}
{"code": 200,"message": "成功","data": {"id": 1,"tmName": "苹果","logoUrl": "http://192.168.200.128:8080/group1/M00/00/00/wKjIgF5r8hSELUs1AAAAAIyTSXk960.png"},"ok": true
}

BaseTrademarkController

/*** 按照id获取品牌* @param id* @return*/
@GetMapping("/baseTrademark/get/{id}")
public Result<BaseTrademark> baseTrademarkGet(@PathVariable("id") Long id){BaseTrademark trademarkServiceById = baseTrademarkService.getById(id);return Result.ok(trademarkServiceById);
}

三、SPU的CRUD

1、获取spu分页列表

文档

接口 http://api.gmall.com/admin/product/{page}/{limit}?category3Id=61
请求参数 page:第几页limit:每页数量category3Id:三级分类ID
请求方式 get
例: http://api.gmall.com/admin/product/1/10?category3Id=61
返回值 {
“code”:200,
“message”:“成功”,
“data”:{
“records”:[
{
“id”:2,
“spuName”:“华为 HUAWEI Mate 30 5G”,
“description”:“品牌: 华为(HUAWEI) 商品名称:华为Mate 30 5G商品编号:100009177424商品毛重:0.6kg商品产地:中国大陆CPU型号:其他运行内存:8GB机身存储:128GB存储卡:NM存储卡摄像头数量:后置三摄后摄主摄像素:4000万像素前摄主摄像素:2400万像素主屏幕尺寸(英寸):6.62英寸 备注:显示屏采用圆角设计,按照标准矩形测量时,屏幕的对角线长度是6.62英寸(实际可视区域略小)分辨率:全高清FHD+屏幕比例:其它屏幕比例屏幕前摄组合:刘海屏电池容量(mAh):4200mAh(典型值) 备注:电池额定容量为4100mAh充电器:5V/2A;9V/2A;10V/4A机身颜色:亮黑色热点:5G游戏性能:发烧级操作系统:Android(安卓)”,
“category3Id”:61,
“tmId”:2,
“spuSaleAttrList”:null,
“spuImageList”:null
},

],
“total”:2,
“size”:10,
“current”:1,
“pages”:1
},
“ok”:true
}
{"code":200,"message":"成功","data":{"records":[{"id":2,"spuName":"华为 HUAWEI Mate 30 5G","description":"品牌: 华为(HUAWEI) 商品名称:华为Mate 30 5G商品编号:100009177424商品毛重:0.6kg商品产地:中国大陆CPU型号:其他运行内存:8GB机身存储:128GB存储卡:NM存储卡摄像头数量:后置三摄后摄主摄像素:4000万像素前摄主摄像素:2400万像素主屏幕尺寸(英寸):6.62英寸 备注:显示屏采用圆角设计,按照标准矩形测量时,屏幕的对角线长度是6.62英寸(实际可视区域略小)分辨率:全高清FHD+屏幕比例:其它屏幕比例屏幕前摄组合:刘海屏电池容量(mAh):4200mAh(典型值) 备注:电池额定容量为4100mAh充电器:5V/2A;9V/2A;10V/4A机身颜色:亮黑色热点:5G游戏性能:发烧级操作系统:Android(安卓)","category3Id":61,"tmId":2,"spuSaleAttrList":null,"spuImageList":null},…],"total":2,"size":10,"current":1,"pages":1},"ok":true
}

① SpuController

新建 com.atguigu.gmall.product.controller.SpuController

/*** SPU操作类*/
@RequestMapping("/admin/product")
@RestController
public class SpuController {@AutowiredSpuInfoService spuInfoService;/*** 分页查询SpuInfo信息** @param category3Id* @param page* @param limit* @return*///http://api.gmall.com/admin/product/{page}/{limit}?category3Id=61//get@GetMapping("/{page}/{limit}")public Result<Page<SpuInfo>> spuInfoPageList(@RequestParam("category3Id") Long category3Id,@PathVariable("page") Long page,@PathVariable("limit") Long limit) {Page<SpuInfo> spuInfoPage = new Page<>(page, limit);QueryWrapper<SpuInfo> spuInfoQueryWrapper = new QueryWrapper<>();spuInfoQueryWrapper.eq("category3_id", category3Id);Page<SpuInfo> infoPage = spuInfoService.page(spuInfoPage, spuInfoQueryWrapper);return Result.ok(infoPage);}
}

② SpuInfoService

新建 com.atguigu.gmall.product.service.SpuInfoService

public interface SpuInfoService extends IService<SpuInfo> {}

③ SpuInfoServiceImpl

新建 com.atguigu.gmall.product.service.impl.SpuInfoServiceImpl

@Service
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoMapper, SpuInfo> implements SpuInfoService {}

④ SpuInfoMapper

新建 com.atguigu.gmall.product.mapper.SpuInfoMapper

public interface SpuInfoMapper extends BaseMapper<SpuInfo> {}

⑤ SpuInfoMapper.xml

新建 service/service-product/src/main/resources/mapper/SpuInfoMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.atguigu.gmall.product.mapper.SpuInfoMapper"></mapper>

对照着 SpuInfo

⑥ SpuInfo

@Data
@ApiModel(description = "SpuInfo")
@TableName("spu_info")
public class SpuInfo extends BaseEntity {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "商品名称")@TableField("spu_name")private String spuName;@ApiModelProperty(value = "商品描述(后台简述)")@TableField("description")private String description;@ApiModelProperty(value = "三级分类id")@TableField("category3_id")private Long category3Id;@ApiModelProperty(value = "品牌id")@TableField("tm_id")private Long tmId;// 销售属性集合@TableField(exist = false)private List<SpuSaleAttr> spuSaleAttrList;// 商品的图片集合@TableField(exist = false)private List<SpuImage> spuImageList;}

效果

2、获取销售属性

文档

接口 http://api.gmall.com/admin/product/baseSaleAttrList
请求参数
请求方式 get
例: http://api.gmall.com/admin/product/baseSaleAttrList
返回值 {
“code”:200,
“message”:“成功”,
“data”:[
{
“id”:1,
“name”:“选择颜色”
},
{
“id”:2,
“name”:“选择版本”
},
{
“id”:3,
“name”:“选择套装”
}
],
“ok”:true
}
{"code":200,"message":"成功","data":[{"id":1,"name":"选择颜色"},{"id":2,"name":"选择版本"},{"id":3,"name":"选择套装"}],"ok":true
}

① BaseSaleAttrController

新建 com.atguigu.gmall.product.controller.BaseSaleAttrController

@RequestMapping("/admin/product/")
@RestController
public class BaseSaleAttrController {@AutowiredBaseSaleAttrInfoService saleAttrInfoService;/*** 查询所有销售属性名* @return*/@GetMapping("/baseSaleAttrList")public Result<List<BaseSaleAttr>> getBaseSaleAttrList(){List<BaseSaleAttr> list = saleAttrInfoService.list();return Result.ok(list);}
}

② BaseSaleAttrInfoService

新建 com.atguigu.gmall.product.service.BaseSaleAttrInfoService

public interface BaseSaleAttrInfoService extends IService<BaseSaleAttr> {}

③ BaseSaleAttrInfoServiceImpl

新建 com.atguigu.gmall.product.service.impl.BaseSaleAttrInfoServiceImpl

@Service
public class BaseSaleAttrInfoServiceImpl extends ServiceImpl<BaseSaleAttrInfoMapper, BaseSaleAttr> implements BaseSaleAttrInfoService {}

④ BaseSaleAttrInfoMapper

新建 com.atguigu.gmall.product.mapper.BaseSaleAttrInfoMapper

public interface BaseSaleAttrInfoMapper extends BaseMapper<BaseSaleAttr> {}

⑤ BaseSaleAttrInfoMapper.xml

新建 service/service-product/src/main/resources/mapper/BaseSaleAttrInfoMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.atguigu.gmall.product.mapper.BaseSaleAttrInfoMapper"></mapper>

对照 BaseSaleAttr

⑥ BaseSaleAttr

@Data
@ApiModel(description = "销售属性")
@TableName("base_sale_attr")
public class BaseSaleAttr extends BaseEntity {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "销售属性名称")@TableField("name")private String name;}

3、获取品牌属性

① 数据库表的复习

(1)一对一

(2)一对多

(3)多对多

获取品牌属性

接口 http://api.gmall.com/admin/product/baseTrademark/getTrademarkList
请求参数
请求方式 get
例: http://api.gmall.com/admin/product/baseTrademark/getTrademarkList
返回值 {
“code”:200,
“message”:“成功”,
“data”:[
{
“id”:1,
“tmName”:“苹果”,
“logoUrl”:“http://127.0.0.1/assets/img/_/phone01.png”
},

],
“ok”:true
}
{"code":200,"message":"成功","data":[{"id":1,"tmName":"苹果","logoUrl":"http://127.0.0.1/assets/img/_/phone01.png"},…],"ok":true
}

② BaseTrademarkController

/*** 获取所有* @return*/
//http://api.gmall.com/admin/product/baseTrademark/getTrademarkList
@GetMapping("/baseTrademark/getTrademarkList")
public Result getBaseTrademarkList(){List<BaseTrademark> list = baseTrademarkService.list();return Result.ok(list);
}

4、spu保存

① 分析传递的数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wooXlpco-1639309167470)(Day04 sku与spu接口.assets/image-20210919204946599.png)]

当我们点击保存的时候

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V3tITNRo-1639309167475)(Day04 sku与spu接口.assets/image-20210919205113070.png)]

对照着 spu_info 看

对照着 spu_image 看

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NoG3uXj8-1639309167476)(Day04 sku与spu接口.assets/image-20210919205341090.png)]

② spu 数据结构图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Esq4YoWH-1639309167478)(Day04 sku与spu接口.assets/image-20210919205510024.png)]

③ 写 SQL

(1)查询某一个 spu 的销售属性

例如:查询 spu_id 为24的销售属性

(2)查询某个 spu 的销售属性以及值的详情

④ 分析流程和步骤

保存SPU
1、spu_info
2、spu_image : spu把后来所有sku要用的图片全部上传好,录入sku的时候sku自己选
3、spu_sale_attr、spu_sale_attr_value
先操作spu_sale_attr,保存以下值"baseSaleAttrId":"1","saleAttrName":"选择颜色",
再操作spu_sale_attr_valuespuSaleAttrValueList:[{"baseSaleAttrId":"1","saleAttrValueName":"黑色"}]
注意:spu_sale_attr、spu_sale_attr_value有冗余存储项,
需要提前设置好值

⑤ 文档

接口 http://api.gmall.com/admin/product/saveSpuInfo
请求参数 {
“id”:null,
“spuName”:“小米”,
“description”:“小米”,
“category3Id”:61,
“spuImageList”:[
{
“imgName”:“list.jpg”,
“imgUrl”:“http://47.93.118.241/group1/M00/00/00/L1128V47i9GARYUWAADxtUrmGBA961.jpg”
}
],
“spuSaleAttrList”:[
{
“baseSaleAttrId”:“1”,
“saleAttrName”:“选择颜色”,
“spuSaleAttrValueList”:[
{
“baseSaleAttrId”:“1”,
“saleAttrValueName”:“红色”
},
{
“baseSaleAttrId”:“1”,
“saleAttrValueName”:“白色”
}
]
}
],
“tmId”:4
}
请求方式 Post
例: http://api.gmall.com/admin/product/saveSpuInfo
返回值 {
“code”:200,
“message”:“成功”,
“data”:null,
“ok”:true
}

请求参数

{"id":null,"spuName":"小米","description":"小米","category3Id":61,"spuImageList":[{"imgName":"list.jpg","imgUrl":"http://47.93.118.241/group1/M00/00/00/L1128V47i9GARYUWAADxtUrmGBA961.jpg"}],"spuSaleAttrList":[{"baseSaleAttrId":"1","saleAttrName":"选择颜色","spuSaleAttrValueList":[{"baseSaleAttrId":"1","saleAttrValueName":"红色"},{"baseSaleAttrId":"1","saleAttrValueName":"白色"}]}],"tmId":4
}

返回值

{"code":200,"message":"成功","data":null,"ok":true
}

⑥ 完成 spu 保存的接口

(1)SpuController

@Autowired
SpuInfoService spuInfoService;@PostMapping("/saveSpuInfo")
public Result saveSpuInfo(@RequestBody SpuInfo spuInfo) {boolean b = spuInfoService.bigSaveSpuInfo(spuInfo);return Result.ok();
}

(2)SpuInfoService

boolean bigSaveSpuInfo(SpuInfo spuInfo);

(3)SpuInfoServiceImpl

    @AutowiredSpuInfoMapper spuInfoMapper;@AutowiredSpuImageMapper spuImageMapper;@AutowiredSpuSaleAttrMapper spuSaleAttrMapper;@AutowiredSpuSaleAttrValueMapper spuSaleAttrValueMapper;//TODO 前端提交三级分类id有bug@Transactional(rollbackFor = Exception.class)@Overridepublic boolean bigSaveSpuInfo(SpuInfo spuInfo) {//1、保存spu_infospuInfoMapper.insert(spuInfo);Long id = spuInfo.getId();//2、保存spu_imageList<SpuImage> spuImageList = spuInfo.getSpuImageList();if (!CollectionUtils.isEmpty(spuImageList)) {for (SpuImage spuImage : spuImageList) {spuImage.setSpuId(id);spuImageMapper.insert(spuImage);}}//3、保存spu_sale_attrList<SpuSaleAttr> spuSaleAttrList = spuInfo.getSpuSaleAttrList();if (!CollectionUtils.isEmpty(spuSaleAttrList)) {for (SpuSaleAttr spuSaleAttr : spuSaleAttrList) {spuSaleAttr.setSpuId(id);spuSaleAttrMapper.insert(spuSaleAttr);//4、保存spu_sale_attr_valueList<SpuSaleAttrValue> spuSaleAttrValueList = spuSaleAttr.getSpuSaleAttrValueList();if (!CollectionUtils.isEmpty(spuSaleAttrValueList)) {for (SpuSaleAttrValue spuSaleAttrValue : spuSaleAttrValueList) {// 回填 spuIdspuSaleAttrValue.setSpuId(id);// 回填 saleAttrNamespuSaleAttrValue.setSaleAttrName(spuSaleAttr.getSaleAttrName());spuSaleAttrValueMapper.insert(spuSaleAttrValue);}}}}return id > 0;}

注意回填

这是前端发送的 JSON

这是数据表的字段

JSON 传递的有些字段没有一一匹配上,这个时候就需要我们手动回填了

1)前端会传递销售属性 id 和销售属性名

spu_sale_attr

2)前端会传递销售属性值的 id 和销售属性值的名

spu_sale_attr_value

测试:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8faewd1i-1639309167480)(Day04 sku与spu接口.assets/image-20210920084010833.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IbxwUHkO-1639309167482)(Day04 sku与spu接口.assets/image-20210920084044506.png)]

数据库中也有了

用 sql 查询一下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Os5FvdvW-1639309167484)(Day04 sku与spu接口.assets/image-20210920084221700.png)]

查询包含图片的时候

⑦ 商品保存三级分类id有bug

当我们选择一级分类的时候商品的 spu 信息就出来了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yniUeBZf-1639309167485)(Day04 sku与spu接口.assets/image-20210920084541876.png)]

在数据库中保存的三级分类的 id,它不是我们提交的

我们先来做个测试,在图书、音响、电子书刊下的电子书刊下的电子书添加 spu 信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YtMIkBJO-1639309167486)(Day04 sku与spu接口.assets/image-20210920084849482.png)]

这个地方提交的三级分类 id 不对,前端把他写死了

四、sku 的CRUD

1、前端页面分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RHCNLxKv-1639309167487)(Day04 sku与spu接口.assets/image-20210920085338796.png)]

当我们要详细定义信息的时候,点击右侧的添加SKU

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZbpRHcJw-1639309167488)(Day04 sku与spu接口.assets/image-20210920085743779.png)]

① spuSaleAttrList

② spuImageList

我们为 spu 里面定义它详细的 sku 信息时,要我们之前保存的 spu 数据,那么我们就先来准备数据

2、根据spuId获取图片列表

① 文档

接口 http://api.gmall.com/admin/product/spuImageList/{spuId}
请求参数 spuId:spuId
请求方式 Get
例: http://api.gmall.com/admin/product/spuImageList/4
返回值 {
“code”:200,
“message”:“成功”,
“data”:[
{
“id”:33,
“spuId”:4,
“imgName”:“list.jpg”,
“imgUrl”:“http://47.93.118.241/group1/M00/00/00/L1128V47i9GARYUWAADxtUrmGBA961.jpg”
}
],
“ok”:true
}
{"code":200,"message":"成功","data":[{"id":33,"spuId":4,"imgName":"list.jpg","imgUrl":"http://47.93.118.241/group1/M00/00/00/L1128V47i9GARYUWAADxtUrmGBA961.jpg"}],"ok":true
}

② SpuController

/*** 根据spuId获取图片列表** @param spuId* @return*/
@GetMapping("/spuImageList/{spuId}")
public Result<List<SpuImage>> spuImageList(@PathVariable("spuId") Long spuId) {QueryWrapper<SpuImage> spuImageQueryWrapper = new QueryWrapper<>();spuImageQueryWrapper.eq("spu_id", spuId);List<SpuImage> list = spuImageService.list(spuImageQueryWrapper);return Result.ok(list);
}

3、根据spuId获取销售属性

① 文档

接口 http://api.gmall.com/admin/product/spuSaleAttrList/{spuId}
请求参数 spuId:spuId
请求方式 Get
例: http://api.gmall.com/admin/product/spuSaleAttrList/4
返回值 {
“code”:200,
“message”:“成功”,
“data”:[
{
“id”:8,
“spuId”:4,
“baseSaleAttrId”:1,
“saleAttrName”:“选择颜色”,
“spuSaleAttrValueList”:[
{
“id”:18,
“spuId”:4,
“baseSaleAttrId”:1,
“saleAttrValueName”:“红色”,
“saleAttrName”:“选择颜色”,
“isChecked”:null
},

]
}
],
“ok”:true
}
{"code":200,"message":"成功","data":[{"id":8,"spuId":4,"baseSaleAttrId":1,"saleAttrName":"选择颜色","spuSaleAttrValueList":[{"id":18,"spuId":4,"baseSaleAttrId":1,"saleAttrValueName":"红色","saleAttrName":"选择颜色","isChecked":null},…]}],"ok":true
}

② 写 SQL

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KjvUfuwm-1639309167491)(Day04 sku与spu接口.assets/image-20210920105847297.png)]

剔除重复的列

③ SpuController

/*** 根据spuId获取商品销售属性列表* 每一组销售属性的组合,应该对应一个SKU* 颜色:黄、蓝* 内存:128,256* SKU: 2*2=4:* 黄+128  黄+256* 蓝+128  蓝+256* 我们在录入sku的时候,只需要录入我们的组合** @param spuId* @return*/
@GetMapping("/spuSaleAttrList/{spuId}")
public Result<List<SpuSaleAttr>> spuSaleAttrList(@PathVariable("spuId") Long spuId) {List<SpuSaleAttr> spuSaleAttrs = spuSaleAttrService.getSpuAttrAndValue(spuId);return Result.ok(spuSaleAttrs);
}

④ SpuSaleAttrService

public interface SpuSaleAttrService extends IService<SpuSaleAttr> {List<SpuSaleAttr> getSpuAttrAndValue(Long spuId);
}

⑤ SpuSaleAttrServiceImpl

/*** 按照spuId查出对应所有的销售属性名和值* @param spuId* @return*/
@Override
public List<SpuSaleAttr> getSpuAttrAndValue(Long spuId) {return spuSaleAttrMapper.getSpuAttrAndValue(spuId);
}

⑥ SpuSaleAttrMapper

public interface SpuSaleAttrMapper extends BaseMapper<SpuSaleAttr> {List<SpuSaleAttr> getSpuAttrAndValue(Long spuId);
}

⑦ SpuSaleAttrMapper.xml

spu_sale_attr_value 的 id 需要起别名,否则 collection 中的 id 就和 resultMap 中 SpuSaleAttr 的 id 冲突了

collection 中 saleAttrName、baseSaleAttrId、spuId 沿用 resultMap 中的 SpuSaleAttr,这是一个小优化

    <resultMap id="SpuSaleAttrResultMap" type="com.atguigu.gmall.model.product.SpuSaleAttr"><id property="id" column="id"></id><result property="spuId" column="spu_id"></result><result property="baseSaleAttrId" column="base_sale_attr_id"></result><result property="saleAttrName" column="sale_attr_name"></result><collection property="spuSaleAttrValueList"ofType="com.atguigu.gmall.model.product.SpuSaleAttrValue"><id property="id" column="sav_id"></id><result property="saleAttrName" column="sale_attr_name"></result><result property="baseSaleAttrId" column="base_sale_attr_id"></result><result property="spuId" column="spu_id"></result><result property="saleAttrValueName" column="sale_attr_value_name"></result></collection></resultMap><select id="getSpuAttrAndValue" resultMap="SpuSaleAttrResultMap">SELECT ssa.*, ssav.id sav_id, ssav.sale_attr_value_nameFROM spu_sale_attr ssaLEFT JOIN spu_sale_attr_value ssavON ssa.spu_id = ssav.spu_id ANDssa.base_sale_attr_id = ssav.base_sale_attr_idWHERE ssa.spu_id = #{spuId}</select>

小复习:

如果 resultMap 中是集合就用 collection 标签,如果是对象就用 association 标签

⑧ 效果

4、添加sku

① 逻辑分析

/***   SPU:录入SPU,平台属性暂时没有参与,录入SKU的时候会有展示.*   SKU的录入:*       1、sku的详情:sku_info*       2、sku的图片:sku_image*          内容来自spu_image的一部分*       3、sku的属性*           3.1)、sku平台属性 : 来源于 base_attr_info  base_attr_value  sku_info*                  被记录在 sku_attr_value(他是base_attr_info  base_attr_value  sku_info的中间表)   价格: 0-499*           3.2)、sku销售属性 :来源于 spu_sale_attr_value*                  被记录在 sku_sale_attr_value (他是 sku_info spu_sale_attr_value的中间表)*/

sku_info

② sku 的数据库结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ci085CSe-1639309167493)(Day04 sku与spu接口.assets/image-20210920115629300.png)]

③ 数据分析

当一个 sku 录入完成之后准备保存

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hjbl8UKi-1639309167494)(Day04 sku与spu接口.assets/image-20210920120236662.png)]

拿到它要发送的源数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lh4H30IV-1639309167495)(Day04 sku与spu接口.assets/image-20210920120408872.png)]

(1)对比 SkuInfo

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qOAYYckP-1639309167496)(Day04 sku与spu接口.assets/image-20210920121403509.png)]

(2)对比 skuImageList

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EzZamPMu-1639309167497)(Day04 sku与spu接口.assets/image-20210920121608651.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sza45EnO-1639309167498)(Day04 sku与spu接口.assets/image-20210920121706617.png)]

注意点:这里的 skuId 前端不可能提交,只有 sku 保存了才有自增 id,所以要回填

(3)对比 sku_sale_attr_value

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rGasPziK-1639309167500)(Day04 sku与spu接口.assets/image-20210920122239433.png)]

sale_attr_value_id 前端已经给我们传过来了,但是 sku_id 和 spu_id 没有传,因此我们要回填

(4)对比 spu_sale_attr_value

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8DQNWQTs-1639309167501)(Day04 sku与spu接口.assets/image-20210920122446585.png)]

④ SkuController

@RestController
@RequestMapping("/admin/product")
@Slf4j
public class SkuController {@AutowiredSkuInfoService skuInfoService;/***   SPU:录入SPU,平台属性暂时没有参与,录入SKU的时候会有展示.*   SKU的录入:*       1、sku的详情:sku_info*       2、sku的图片:sku_image*          内容来自spu_image的一部分*       3、sku的属性*           3.1)、sku平台属性 : 来源于 base_attr_info  base_attr_value  sku_info*                  被记录在 sku_attr_value(他是base_attr_info  base_attr_value  sku_info的中间表)   价格: 0-499*           3.2)、sku销售属性 :来源于 spu_sale_attr_value*                  被记录在 sku_sale_attr_value (他是 sku_info spu_sale_attr_value的中间表)*/@Transactional(rollbackFor = Exception.class)@PostMapping("/saveSkuInfo")public Result saveSkuInfo(@RequestBody SkuInfo skuInfo){log.info("sku保存信息:{}",skuInfo);boolean b = skuInfoService.bigSaveSkuInfo(skuInfo);return Result.ok();}
}

⑤ SkuInfoService

public interface SkuInfoService extends IService<SkuInfo> {boolean bigSaveSkuInfo(SkuInfo skuInfo);
}

⑥ SkuInfoServiceImpl

@Service
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoMapper, SkuInfo> implements SkuInfoService {@AutowiredSkuInfoMapper skuInfoMapper;@AutowiredSkuImageMapper skuImageMapper;@AutowiredSkuAttrValueMappper skuAttrValueMappper;@AutowiredSkuSaleAttrValueMapper skuSaleAttrValueMapper;/*** 保存 SKU 信息* SPU:录入SPU,平台属性暂时没有参与,录入SKU的时候会有展示.* SKU的录入:* 1、sku的详情:sku_info* 2、sku的图片:sku_image* 内容来自spu_image的一部分* 3、sku的属性* 3.1)、sku平台属性 : 来源于 base_attr_info  base_attr_value  sku_info* 被记录在 sku_attr_value(他是base_attr_info  base_attr_value  sku_info的中间表)   价格: 0-499* 3.2)、sku销售属性 :来源于 spu_sale_attr_value* 被记录在 sku_sale_attr_value (他是 sku_info spu_sale_attr_value的中间表)*/@Transactional@Overridepublic boolean bigSaveSkuInfo(SkuInfo skuInfo) {//1、保存sku_info基础信息,数据校验
//        if (skuInfo.getPrice() == null){//            return false;
//        }int insert = skuInfoMapper.insert(skuInfo);Long skuId = skuInfo.getId();//只要操作了数据库,赶紧告诉布隆,我插入了数据//2、保存sku图片信息   sku_imageList<SkuImage> skuImageList = skuInfo.getSkuImageList();if (!CollectionUtils.isEmpty(skuImageList)) {for (SkuImage skuImage : skuImageList) {skuImage.setSkuId(skuId);skuImageMapper.insert(skuImage);}}//3、保存sku的平台属性对应的所有值 sku_attr_value//attr_id  value_id  sku_id// 1          2      sku_idList<SkuAttrValue> skuAttrValueList = skuInfo.getSkuAttrValueList();if (!CollectionUtils.isEmpty(skuAttrValueList)) {for (SkuAttrValue skuAttrValue : skuAttrValueList) {skuAttrValue.setSkuId(skuId);skuAttrValueMappper.insert(skuAttrValue);}}//4、保存sku的销售属性以及值信息 sku_sale_attr_value//  sku_id    spu_id   sale_attr_value_id来源于spu_sale_attr_value的id// "saleAttrValueId":"123", spu_sale_attr_value的id// "baseSaleAttrId ":"1", base_sale_attr的idList<SkuSaleAttrValue> skuSaleAttrValueList = skuInfo.getSkuSaleAttrValueList();if (!CollectionUtils.isEmpty(skuSaleAttrValueList)) {for (SkuSaleAttrValue skuSaleAttrValue : skuSaleAttrValueList) {//注意回填 spuId 和 skuIdskuSaleAttrValue.setSkuId(skuId);skuSaleAttrValue.setSpuId(skuInfo.getSpuId());skuSaleAttrValueMapper.insert(skuSaleAttrValue);}}return true;}
}

⑦ 效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2NhgTcoN-1639309167502)(Day04 sku与spu接口.assets/image-20210920162740128.png)]

⑧ 查询某个 sku 真正的平台属性值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7iQgGbFr-1639309167503)(Day04 sku与spu接口.assets/image-20210920163609406.png)]

⑨ 查询某个 sku 的销售属性值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y8bBupJ3-1639309167504)(Day04 sku与spu接口.assets/image-20210920164345980.png)]

⑩ 查询这个 sku 的所有图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uJY80egw-1639309167506)(Day04 sku与spu接口.assets/image-20210920164604971.png)]

5、获取sku分页列表

① 文档

接口 http://api.gmall.com/admin/product/list/{page}/{limit}
请求参数 page:第几页limit:每页数量
请求方式 get
例: http://api.gmall.com/admin/product/list/1/10
返回值 {
“code”:200,
“message”:“成功”,
“data”:{
“records”:[
{
“id”:10,
“spuId”:2,
“price”:3999,
“skuName”:“华为 HUAWEI Mate 30 手机”,
“skuDesc”:“主体(mm) 9.2 运营商标志或内容 无”,
“weight”:“0.55”,
“tmId”:2,
“category3Id”:61,
“skuDefaultImg”:“http://192.168.200.128:8080/group1/M00/00/00/wKjIgF42TsmAZc7HAANJjSt4ynk994.jpg”,
“isSale”:0,
“skuImageList”:null,
“skuAttrValueList”:null,
“skuSaleAttrValueList”:null
},

],
“total”:11,
“size”:10,
“current”:1,
“pages”:2
},
“ok”:true
}
{"code":200,"message":"成功","data":{"records":[{"id":10,"spuId":2,"price":3999,"skuName":"华为 HUAWEI Mate 30 手机","skuDesc":"主体(mm) 9.2 运营商标志或内容 无","weight":"0.55","tmId":2,"category3Id":61,"skuDefaultImg":"http://192.168.200.128:8080/group1/M00/00/00/wKjIgF42TsmAZc7HAANJjSt4ynk994.jpg","isSale":0,"skuImageList":null,"skuAttrValueList":null,"skuSaleAttrValueList":null},…],"total":11,"size":10,"current":1,"pages":2},"ok":true
}

② SkuController

/*** 获取sku分页列表* @param page* @param limit* @return*///http://api.gmall.com/admin/product/list/{page}/{limit}
@GetMapping("/list/{page}/{limit}")
public Result<Page<SkuInfo>> listSkuInfo(@PathVariable("page") Long page,@PathVariable("limit") Long limit){Page<SkuInfo> skuInfoPage = new Page<>(page, limit);Page<SkuInfo> infoPage = skuInfoService.page(skuInfoPage);return Result.ok(infoPage);
}

③ 效果

6、上架和下架

① 上架文档

接口 http://api.gmall.com/admin/product/onSale/{skuId}
请求参数 skuId:skuId
请求方式 Get
例: http://api.gmall.com/admin/product/onSale/11
返回值 {
“code”:200,
“message”:“成功”,
“data”:null,
“ok”:true
}

② 下架文档

接口 http://api.gmall.com/admin/product/cancelSale/{skuId}
请求参数 skuId:skuId
请求方式 Get
例: http://api.gmall.com/admin/product/cancelSale/11
返回值 {
“code”:200,
“message”:“成功”,
“data”:null,
“ok”:true
}

③ SkuController

 /*** 上架* @param skuId* @return*///http://api.gmall.com/admin/product/onSale/{skuId}@GetMapping("/onSale/{skuId}")public Result onSale(@PathVariable("skuId") Long skuId){boolean b = skuInfoService.onSale(skuId);return Result.ok(b);}/*** 下架* @param skuId* @return*///http://api.gmall.com/admin/product/cancelSale/{skuId}
@GetMapping("/cancelSale/{skuId}")
public Result cancelSale(@PathVariable("skuId") Long skuId){boolean b = skuInfoService.cancelSale(skuId);return Result.ok(b);
}

④ SkuInfoService

boolean onSale(Long skuId);boolean cancelSale(Long skuId);

⑤ SkuInfoServiceImpl

@Override
public boolean onSale(Long skuId) {// 1、上架修改数据库skuInfoMapper.updateSkuStatus(skuId, 1);// TODO 2、把商品信息同步到搜索引擎return true;
}@Override
public boolean cancelSale(Long skuId) {//1、下架修改数据库skuInfoMapper.updateSkuStatus(skuId, 0);//TODO 2、把商品信息从搜索引擎移除return true;
}

⑥ SkuInfoMapper

void updateSkuStatus(@Param("skuId") Long skuId,@Param("status") int status);

⑦ SkuInfoMapper.xml

<update id="updateSkuStatus">UPDATE sku_info SET is_sale = #{status}where id = #{skuId}
</update>

谷粒商城 Day04 sku与spu接口相关推荐

  1. 谷粒商城 Day05 商品详情页接口准备

    Day05 商品详情页接口准备 一.Thymeleaf 1.thymeleaf 简介 ① HelloController com.atguigu.thymeleaf.controller.HelloC ...

  2. 谷粒商城笔记+踩坑(9)——上架商品spu到ES索引库

    导航: 谷粒商城笔记+踩坑汇总篇 目录 1.ES回顾 2.ES整合商品上架 2.1.分析 2.2.创建sku的es索引库 2.2.1.两种索引库设计方案分析 2.2.2.最终选用的索引库方案,nest ...

  3. 谷粒商城项目8——商品上架 上架商品sku保存到es nginx配置

    文章目录 一.商城业务 1.商品上架 1.1 ES 的存储结构分析 1.2 PUT product 1.3 一些细节 2.商品上架-构造基本数据 3.商品上架-业务代码: 4.商品上架-search模 ...

  4. 商城-商品规格管理-SPU和SKU数据结构

    商城-商品规格管理-SPU和SKU数据结构 3.SPU和SKU数据结构 3.1.SPU表 3.1.1.表结构 3.1.2.spu中的规格参数 3.1.2.1.specifications字段 3.1. ...

  5. 商城sku和spu设计

    SPU与SKU 1.1 SPU与SKU概念 SPU = Standard Product Unit (标准产品单位) 概念 : SPU 是商品信息聚合的最小单位,是一组可复用.易检索的标准化信息的集合 ...

  6. 谷粒商城分布式基础篇1-个人版

    基础篇 1 项目简介 1.1 项目背景 1.2 电商模式 市面上有5种常见的电商模式 B2B.B2C.C2B.C2C.O2O 1.2.1 B2B 模式 B2B(Business to Business ...

  7. 尚硅谷谷粒商城第十二天 商品详情页及异步编排

    1. 商品详情 当用户搜索到商品,肯定会点击查看,就会进入商品详情页,接下来我们完成商品详情页的展示. 商品详情浏览量比较大,并发高,我们会独立开启一个微服务,用来展示商品详情. 1.1. 创建mod ...

  8. 谷粒商城开发踩坑及部分知识点大总结

    谷粒商城开发BUG踩坑及部分知识点大总结 基本上bug的出现位置和时间线都能够匹配 如果对你有帮助的话就点个赞哈 2022.6.28 github设置ssh免密登陆,以下代码在git bash上面输入 ...

  9. 谷粒商城项目总结(一)-基础篇

    谷粒商城基础篇高级篇,跟着看,也敲了部分代码,但是感觉后续随着业务增加代码部分敲了也记不住,就想着应该重视解决问题的思路,理清思路比代码更重要,写这篇文章,是在看完后在从第一到高级篇,少部分集群篇总结 ...

  10. 谷粒商城项目搭建思路

    文章目录 基础篇 核心技术点 1. 搭建环境 1.1 安装Linux虚拟机 1.2 安装Docker 1.3 统一开发环境 1.4 搭建后台管理项目 1.5 逆向工程 1.6 测试商品服务功能 1.7 ...

最新文章

  1. 汉字在屏幕上的显示过程以及乱码的原因
  2. java Locale 解析方法
  3. 《动手学深度学习》PyTorch版本
  4. webpack学习1-打包
  5. ArrayBlockingQueue原理分析-remove方法
  6. SQL查询数据库完整表结构(mysql)
  7. sqlserver 事务日志 异常增长原因排查_小白入门学习打日志
  8. android第三方推送实现,Android--利用第三方推送实现APP伪保活(小米篇)
  9. 2018-2019-2 20165118 《网络对抗技术》Exp4 恶意代码分析
  10. 数据交互什么意思_学习编程怎么样才可以不枯燥?什么是前端语言?
  11. mysql能管理多大的硬盘,Mysql----查看数据库,表占用磁盘大小
  12. ppp协议 服务器,详解PPP及PPPoE协议
  13. STM32串口printf调试输出(SSCOM V5.13.1)
  14. 国内外你知道的设计网站!给你的设计找点灵感!
  15. E.03.24 Colin Huang steps down as Pinduoduo chair
  16. PIM是什么意思,如何做好企业产品信息管理?
  17. 南卡小音舱体验评测:CD级音质听感震撼
  18. 谷歌搜索语法(一)基本语法
  19. 消费升级背景下零食行业发展报告_趋势 | 保健食品 “零食化”升级
  20. 三个限免网站,助你白嫖正版付费软件/游戏

热门文章

  1. pandavan 固件squashfs只读文件系统如何上传应用程序
  2. 苹果手机录屏软件_手机端录屏软件哪个好 手机上最好的录屏软件
  3. en55032最新标准下载_欧盟新EMC标准EN55032
  4. 为了方便在微博上看小黄图,我写了一段JS
  5. 【JSP简单实现购物车(书本案例代码)】
  6. 【2020.2.29更新】高通蓝牙芯片QCC3003,QCC3008 学习视频教材
  7. Cmder安装使用篇
  8. Java实现18位身份证号码的校验码计算校验
  9. 【十次方】十次方项目前期准备
  10. 运维记之源码编译nfs-utils和rpcbind