谷粒商城 Day04 sku与spu接口
Day04 sku与spu接口
一、答疑
1、Docker
① 如果在创建容器的时候,没有进行端口映射和卷的挂载,后来又想添加,我们如何做呢?
docker update 不行
把docker容器的核心内容docker cp出来,再启动一个新容器挂载
② 如何创建nacos的容器镜像呢,和Sentinel完全不一样?
FROM alpine
COPY ./nacos /app/nacosENTRYPOINT [“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接口相关推荐
- 谷粒商城 Day05 商品详情页接口准备
Day05 商品详情页接口准备 一.Thymeleaf 1.thymeleaf 简介 ① HelloController com.atguigu.thymeleaf.controller.HelloC ...
- 谷粒商城笔记+踩坑(9)——上架商品spu到ES索引库
导航: 谷粒商城笔记+踩坑汇总篇 目录 1.ES回顾 2.ES整合商品上架 2.1.分析 2.2.创建sku的es索引库 2.2.1.两种索引库设计方案分析 2.2.2.最终选用的索引库方案,nest ...
- 谷粒商城项目8——商品上架 上架商品sku保存到es nginx配置
文章目录 一.商城业务 1.商品上架 1.1 ES 的存储结构分析 1.2 PUT product 1.3 一些细节 2.商品上架-构造基本数据 3.商品上架-业务代码: 4.商品上架-search模 ...
- 商城-商品规格管理-SPU和SKU数据结构
商城-商品规格管理-SPU和SKU数据结构 3.SPU和SKU数据结构 3.1.SPU表 3.1.1.表结构 3.1.2.spu中的规格参数 3.1.2.1.specifications字段 3.1. ...
- 商城sku和spu设计
SPU与SKU 1.1 SPU与SKU概念 SPU = Standard Product Unit (标准产品单位) 概念 : SPU 是商品信息聚合的最小单位,是一组可复用.易检索的标准化信息的集合 ...
- 谷粒商城分布式基础篇1-个人版
基础篇 1 项目简介 1.1 项目背景 1.2 电商模式 市面上有5种常见的电商模式 B2B.B2C.C2B.C2C.O2O 1.2.1 B2B 模式 B2B(Business to Business ...
- 尚硅谷谷粒商城第十二天 商品详情页及异步编排
1. 商品详情 当用户搜索到商品,肯定会点击查看,就会进入商品详情页,接下来我们完成商品详情页的展示. 商品详情浏览量比较大,并发高,我们会独立开启一个微服务,用来展示商品详情. 1.1. 创建mod ...
- 谷粒商城开发踩坑及部分知识点大总结
谷粒商城开发BUG踩坑及部分知识点大总结 基本上bug的出现位置和时间线都能够匹配 如果对你有帮助的话就点个赞哈 2022.6.28 github设置ssh免密登陆,以下代码在git bash上面输入 ...
- 谷粒商城项目总结(一)-基础篇
谷粒商城基础篇高级篇,跟着看,也敲了部分代码,但是感觉后续随着业务增加代码部分敲了也记不住,就想着应该重视解决问题的思路,理清思路比代码更重要,写这篇文章,是在看完后在从第一到高级篇,少部分集群篇总结 ...
- 谷粒商城项目搭建思路
文章目录 基础篇 核心技术点 1. 搭建环境 1.1 安装Linux虚拟机 1.2 安装Docker 1.3 统一开发环境 1.4 搭建后台管理项目 1.5 逆向工程 1.6 测试商品服务功能 1.7 ...
最新文章
- 汉字在屏幕上的显示过程以及乱码的原因
- java Locale 解析方法
- 《动手学深度学习》PyTorch版本
- webpack学习1-打包
- ArrayBlockingQueue原理分析-remove方法
- SQL查询数据库完整表结构(mysql)
- sqlserver 事务日志 异常增长原因排查_小白入门学习打日志
- android第三方推送实现,Android--利用第三方推送实现APP伪保活(小米篇)
- 2018-2019-2 20165118 《网络对抗技术》Exp4 恶意代码分析
- 数据交互什么意思_学习编程怎么样才可以不枯燥?什么是前端语言?
- mysql能管理多大的硬盘,Mysql----查看数据库,表占用磁盘大小
- ppp协议 服务器,详解PPP及PPPoE协议
- STM32串口printf调试输出(SSCOM V5.13.1)
- 国内外你知道的设计网站!给你的设计找点灵感!
- E.03.24 Colin Huang steps down as Pinduoduo chair
- PIM是什么意思,如何做好企业产品信息管理?
- 南卡小音舱体验评测:CD级音质听感震撼
- 谷歌搜索语法(一)基本语法
- 消费升级背景下零食行业发展报告_趋势 | 保健食品 “零食化”升级
- 三个限免网站,助你白嫖正版付费软件/游戏