谷粒商城–商品发布–笔记九

谷粒商城–商品发布–笔记九

1.基本信息页面

1.选择分类后品牌列表不显示问题

image-20211014103936395

原因

使用到了PubSub 但是没有依赖

解决

  1. npm install –save pubsub-js
  2. 在src下的main.js中引用:
    ① import PubSub from pubsub-js
    ② Vue.prototype.PubSub = PubSub

效果

报错消失了,取而代之的是找不到接口,问题解决

image-20211014104741259

2.编写根据商品分类查询品牌列表接口

新增品牌vo对象

gulimall-product/src/main/java/site/zhourui/gulimall/product/vo/BrandVo.java

@Data
public class BrandVo {/*** "brandId": 0,* "brandName": "string",*/private Long brandId;private String  brandName;
}

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/CategoryBrandRelationService.java

新增接口

List<BrandEntity> getBrandsByCatId(Long catId);

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/impl/CategoryBrandRelationServiceImpl.java

新增接口实现

@Override
//获取目录下所有品牌列表
public List<BrandEntity> getBrandsByCatId(Long catId) {List<CategoryBrandRelationEntity> catelogId = relationDao.selectList(new QueryWrapper<CategoryBrandRelationEntity>().eq("catelog_id", catId));List<BrandEntity> collect = catelogId.stream().map(item -> {Long brandId = item.getBrandId();BrandEntity byId = brandService.getById(brandId);return byId;}).collect(Collectors.toList());return collect;
}

gulimall-product/src/main/java/site/zhourui/gulimall/product/controller/CategoryBrandRelationController.java 新增接口

 /*** 获取当前品牌关联的所有分类列表*/@GetMapping("/catelog/list")//@RequiresPermissions("product:categorybrandrelation:list")public R cateloglist(@RequestParam("brandId")Long brandId){List<CategoryBrandRelationEntity> data = categoryBrandRelationService.list(new QueryWrapper<CategoryBrandRelationEntity>().eq("brand_id",brandId));return R.ok().put("data", data);}

重启gulimall-product服务

观察效果 商品列表出现

image-20211014110409402

3.获取会员等级列表

发现还需要会员等级接口

image-20211014110608026

1.网关配置

因为之前配置过会员模块,这里就不配置了

但是在网关中需要配置会员服务路由,并重启网关

gulimall-gateway/src/main/resources/application.yml

		- id: member_routeuri: lb://gulimall-memberpredicates:- Path=/api/member/**filters:- RewritePath=/api/(?<segment>.*),/${segment}

2.添加会员等级

启动 gulimall-member服务

设置会员等级

image-20211014150251996

此时会员列表接口也能查询到会员等级列表信息了

image-20211014150739205

2.规格参数页面

规格参数属如果需要多选

image-20211014165938771

需要在对应的属性

3.销售属性页面

1.根据分类id查出所有的分组以及这些组里面的属性

com/atguigu/gulimall/product/vo/AttrGroupWithAttrsVo.java

属性分组带有属性集合的vo

package site.zhourui.gulimall.product.vo;import lombok.Data;
import site.zhourui.gulimall.product.entity.AttrEntity;import java.util.List;@Data
public class AttrGroupWithAttrsVo {/*** 分组id*/private Long attrGroupId;/*** 组名*/private String attrGroupName;/*** 排序*/private Integer sort;/*** 描述*/private String descript;/*** 组图标*/private String icon;/*** 所属分类id*/private Long catelogId;private List<AttrEntity> attrs;
}

com/atguigu/gulimall/product/service/AttrGroupService.java

新增根据分类id查出所有的分组以及这些组里面的属性接口

//根据分类id查出所有的分组以及这些组里面的属性
List<AttrGroupWithAttrsVo> getAttrGroupWithAttrsByCatelogId(Long catelogId);

com/atguigu/gulimall/product/service/impl/AttrGroupServiceImpl.java

/*** 根据分类id查出所有的分组以及这些组里面的属性* @param catelogId* @return*/@Overridepublic List<AttrGroupWithAttrsVo> getAttrGroupWithAttrsByCatelogId(Long catelogId) {//com.atguigu.gulimall.product.vo//1、查询分组信息List<AttrGroupEntity> attrGroupEntities = this.list(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));//2、查询所有属性List<AttrGroupWithAttrsVo> collect = attrGroupEntities.stream().map(group -> {AttrGroupWithAttrsVo attrsVo = new AttrGroupWithAttrsVo();BeanUtils.copyProperties(group,attrsVo);List<AttrEntity> attrs = attrService.getRelationAttr(attrsVo.getAttrGroupId());attrsVo.setAttrs(attrs);return attrsVo;}).collect(Collectors.toList());return collect;}

gulimall-product/src/main/java/site/zhourui/gulimall/product/controller/AttrGroupController.java

编写获取会员等级列表接口

///product/attrgroup/{catelogId}/withattr
@GetMapping("/{catelogId}/withattr")
public R getAttrGroupWithAttrs(@PathVariable("catelogId")Long catelogId){//1、查出当前分类下的所有属性分组,//2、查出每个属性分组的所有属性List<AttrGroupWithAttrsVo> vos =  attrGroupService.getAttrGroupWithAttrsByCatelogId(catelogId);return R.ok().put("data",vos);
}

效果

image-20211014161012619

4.SKU信息页面

此页面主要是前端生成的

根据步骤二中选中的属性进行笛卡尔乘积生成的数据

具体实现代码

generateSkus() {this.step = 3;//根据笛卡尔积运算进行生成skulet selectValues = [];this.dataResp.tableAttrColumn = [];this.dataResp.tempSaleAttrs.forEach(item => {if (item.attrValues.length > 0) {selectValues.push(item.attrValues);this.dataResp.tableAttrColumn.push(item);}});let descartes = this.descartes(selectValues);//[["黑色","6GB","移动"],["黑色","6GB","联通"],["黑色","8GB","移动"],["黑色","8GB","联通"],//["白色","6GB","移动"],["白色","6GB","联通"],["白色","8GB","移动"],["白色","8GB","联通"],//["蓝色","6GB","移动"],["蓝色","6GB","联通"],["蓝色","8GB","移动"],["蓝色","8GB","联通"]]console.log("生成的组合", JSON.stringify(descartes));//有多少descartes就有多少skulet skus = [];descartes.forEach((descar, descaridx) => {let attrArray = []; //sku属性组descar.forEach((de, index) => {//构造saleAttr信息let saleAttrItem = {attrId: this.dataResp.tableAttrColumn[index].attrId,attrName: this.dataResp.tableAttrColumn[index].attrName,attrValue: de};attrArray.push(saleAttrItem);});//先初始化几个images,后面的上传还要加let imgs = [];this.spu.images.forEach((img, idx) => {imgs.push({ imgUrl: "", defaultImg: 0 });});//会员价,也必须在循环里面生成,否则会导致数据绑定问题let memberPrices = [];if (this.dataResp.memberLevels.length > 0) {for (let i = 0; i < this.dataResp.memberLevels.length; i++) {if (this.dataResp.memberLevels[i].priviledgeMemberPrice == 1) {memberPrices.push({id: this.dataResp.memberLevels[i].id,name: this.dataResp.memberLevels[i].name,price: 0});}}}//;descaridx,判断如果之前有就用之前的值;let res = this.hasAndReturnSku(this.spu.skus, descar);if (res === null) {skus.push({attr: attrArray,skuName: this.spu.spuName + " " + descar.join(" "),price: 0,skuTitle: this.spu.spuName + " " + descar.join(" "),skuSubtitle: "",images: imgs,descar: descar,fullCount: 0,discount: 0,countStatus: 0,fullPrice: 0.0,reducePrice: 0.0,priceStatus: 0,memberPrice: new Array().concat(memberPrices)});} else {skus.push(res);}});this.spu.skus = skus;console.log("结果!!!", this.spu.skus, this.dataResp.tableAttrColumn);},//判断如果包含之前的sku的descar组合,就返回这个sku的详细信息;hasAndReturnSku(skus, descar) {let res = null;if (skus.length > 0) {for (let i = 0; i < skus.length; i++) {if (skus[i].descar.join(" ") == descar.join(" ")) {res = skus[i];}}}return res;},

生成效果

image-20211014161135351

5.新增商品vo抽取

1.新增商品保存json

保存时会向后端发送一个这样的json对象

{"spuName":"2","spuDescription":"2","catalogId":225,"brandId":9,"weight":0.1,"publishStatus":0,"decript":["https://zr-gulimall-images.oss-cn-chengdu.aliyuncs.com/2021-10-14/04854fc0-7f1b-4505-8b34-e53f97f7fb81_2021-07-07.png"],"images":["https://zr-gulimall-images.oss-cn-chengdu.aliyuncs.com/2021-10-14/6697a7e5-294a-4e74-8389-4fd5fd1b826b_2021-06-28.png"],"bounds":{"buyBounds":0,"growBounds":0},"baseAttrs":[{"attrId":7,"attrValues":"A2217;C3J","showDesc":1},{"attrId":8,"attrValues":"2018","showDesc":0},{"attrId":11,"attrValues":"白色","showDesc":1},{"attrId":13,"attrValues":"135.9","showDesc":0},{"attrId":14,"attrValues":"以官网信息为准;陶瓷","showDesc":0},{"attrId":15,"attrValues":"高通(Qualcomm)","showDesc":1},{"attrId":16,"attrValues":"骁龙665","showDesc":0}],"skus":[{"attr":[{"attrId":9,"attrName":"颜色","attrValue":"黑色"},{"attrId":10,"attrName":"内存","attrValue":"6GB"},{"attrId":13,"attrName":"机身长度(mm)","attrValue":"158.3"}],"skuName":"2 黑色 6GB 158.3","price":0,"skuTitle":"2 黑色 6GB 158.3","skuSubtitle":"","images":[{"imgUrl":"","defaultImg":0}],"descar":["黑色","6GB","158.3"],"fullCount":0,"discount":0,"countStatus":0,"fullPrice":0,"reducePrice":0,"priceStatus":0,"memberPrice":[{"id":2,"name":"铜牌会员","price":0},{"id":3,"name":"银牌会员","price":0}]},{"attr":[{"attrId":9,"attrName":"颜色","attrValue":"黑色"},{"attrId":10,"attrName":"内存","attrValue":"6GB"},{"attrId":13,"attrName":"机身长度(mm)","attrValue":"135.9"}],"skuName":"2 黑色 6GB 135.9","price":0,"skuTitle":"2 黑色 6GB 135.9","skuSubtitle":"","images":[{"imgUrl":"","defaultImg":0}],"descar":["黑色","6GB","135.9"],"fullCount":0,"discount":0,"countStatus":0,"fullPrice":0,"reducePrice":0,"priceStatus":0,"memberPrice":[{"id":2,"name":"铜牌会员","price":0},{"id":3,"name":"银牌会员","price":0}]},{"attr":[{"attrId":9,"attrName":"颜色","attrValue":"黑色"},{"attrId":10,"attrName":"内存","attrValue":"4GB"},{"attrId":13,"attrName":"机身长度(mm)","attrValue":"158.3"}],"skuName":"2 黑色 4GB 158.3","price":0,"skuTitle":"2 黑色 4GB 158.3","skuSubtitle":"","images":[{"imgUrl":"","defaultImg":0}],"descar":["黑色","4GB","158.3"],"fullCount":0,"discount":0,"countStatus":0,"fullPrice":0,"reducePrice":0,"priceStatus":0,"memberPrice":[{"id":2,"name":"铜牌会员","price":0},{"id":3,"name":"银牌会员","price":0}]},{"attr":[{"attrId":9,"attrName":"颜色","attrValue":"黑色"},{"attrId":10,"attrName":"内存","attrValue":"4GB"},{"attrId":13,"attrName":"机身长度(mm)","attrValue":"135.9"}],"skuName":"2 黑色 4GB 135.9","price":0,"skuTitle":"2 黑色 4GB 135.9","skuSubtitle":"","images":[{"imgUrl":"","defaultImg":0}],"descar":["黑色","4GB","135.9"],"fullCount":0,"discount":0,"countStatus":0,"fullPrice":0,"reducePrice":0,"priceStatus":0,"memberPrice":[{"id":2,"name":"铜牌会员","price":0},{"id":3,"name":"银牌会员","price":0}]},{"attr":[{"attrId":9,"attrName":"颜色","attrValue":"白色"},{"attrId":10,"attrName":"内存","attrValue":"6GB"},{"attrId":13,"attrName":"机身长度(mm)","attrValue":"158.3"}],"skuName":"2 白色 6GB 158.3","price":0,"skuTitle":"2 白色 6GB 158.3","skuSubtitle":"","images":[{"imgUrl":"","defaultImg":0}],"descar":["白色","6GB","158.3"],"fullCount":0,"discount":0,"countStatus":0,"fullPrice":0,"reducePrice":0,"priceStatus":0,"memberPrice":[{"id":2,"name":"铜牌会员","price":0},{"id":3,"name":"银牌会员","price":0}]},{"attr":[{"attrId":9,"attrName":"颜色","attrValue":"白色"},{"attrId":10,"attrName":"内存","attrValue":"6GB"},{"attrId":13,"attrName":"机身长度(mm)","attrValue":"135.9"}],"skuName":"2 白色 6GB 135.9","price":0,"skuTitle":"2 白色 6GB 135.9","skuSubtitle":"","images":[{"imgUrl":"","defaultImg":0}],"descar":["白色","6GB","135.9"],"fullCount":0,"discount":0,"countStatus":0,"fullPrice":0,"reducePrice":0,"priceStatus":0,"memberPrice":[{"id":2,"name":"铜牌会员","price":0},{"id":3,"name":"银牌会员","price":0}]},{"attr":[{"attrId":9,"attrName":"颜色","attrValue":"白色"},{"attrId":10,"attrName":"内存","attrValue":"4GB"},{"attrId":13,"attrName":"机身长度(mm)","attrValue":"158.3"}],"skuName":"2 白色 4GB 158.3","price":0,"skuTitle":"2 白色 4GB 158.3","skuSubtitle":"","images":[{"imgUrl":"","defaultImg":0}],"descar":["白色","4GB","158.3"],"fullCount":0,"discount":0,"countStatus":0,"fullPrice":0,"reducePrice":0,"priceStatus":0,"memberPrice":[{"id":2,"name":"铜牌会员","price":0},{"id":3,"name":"银牌会员","price":0}]},{"attr":[{"attrId":9,"attrName":"颜色","attrValue":"白色"},{"attrId":10,"attrName":"内存","attrValue":"4GB"},{"attrId":13,"attrName":"机身长度(mm)","attrValue":"135.9"}],"skuName":"2 白色 4GB 135.9","price":0,"skuTitle":"2 白色 4GB 135.9","skuSubtitle":"","images":[{"imgUrl":"","defaultImg":0}],"descar":["白色","4GB","135.9"],"fullCount":0,"discount":0,"countStatus":0,"fullPrice":0,"reducePrice":0,"priceStatus":0,"memberPrice":[{"id":2,"name":"铜牌会员","price":0},{"id":3,"name":"银牌会员","price":0}]}]}

2.将json字符串格式化

json在线格式化网站

{"spuName": "2","spuDescription": "2","catalogId": 225,"brandId": 9,"weight": 0.1,"publishStatus": 0,"decript": ["https://zr-gulimall-images.oss-cn-chengdu.aliyuncs.com/2021-10-14/04854fc0-7f1b-4505-8b34-e53f97f7fb81_2021-07-07.png"],"images": ["https://zr-gulimall-images.oss-cn-chengdu.aliyuncs.com/2021-10-14/6697a7e5-294a-4e74-8389-4fd5fd1b826b_2021-06-28.png"],"bounds": {"buyBounds": 0,"growBounds": 0},"baseAttrs": [{"attrId": 7,"attrValues": "A2217;C3J","showDesc": 1}, {"attrId": 8,"attrValues": "2018","showDesc": 0}, {"attrId": 11,"attrValues": "白色","showDesc": 1}, {"attrId": 13,"attrValues": "135.9","showDesc": 0}, {"attrId": 14,"attrValues": "以官网信息为准;陶瓷","showDesc": 0}, {"attrId": 15,"attrValues": "高通(Qualcomm)","showDesc": 1}, {"attrId": 16,"attrValues": "骁龙665","showDesc": 0}],"skus": [{"attr": [{"attrId": 9,"attrName": "颜色","attrValue": "黑色"}, {"attrId": 10,"attrName": "内存","attrValue": "6GB"}, {"attrId": 13,"attrName": "机身长度(mm)","attrValue": "158.3"}],"skuName": "2 黑色 6GB 158.3","price": 0,"skuTitle": "2 黑色 6GB 158.3","skuSubtitle": "","images": [{"imgUrl": "","defaultImg": 0}],"descar": ["黑色", "6GB", "158.3"],"fullCount": 0,"discount": 0,"countStatus": 0,"fullPrice": 0,"reducePrice": 0,"priceStatus": 0,"memberPrice": [{"id": 2,"name": "铜牌会员","price": 0}, {"id": 3,"name": "银牌会员","price": 0}]}, {"attr": [{"attrId": 9,"attrName": "颜色","attrValue": "黑色"}, {"attrId": 10,"attrName": "内存","attrValue": "6GB"}, {"attrId": 13,"attrName": "机身长度(mm)","attrValue": "135.9"}],"skuName": "2 黑色 6GB 135.9","price": 0,"skuTitle": "2 黑色 6GB 135.9","skuSubtitle": "","images": [{"imgUrl": "","defaultImg": 0}],"descar": ["黑色", "6GB", "135.9"],"fullCount": 0,"discount": 0,"countStatus": 0,"fullPrice": 0,"reducePrice": 0,"priceStatus": 0,"memberPrice": [{"id": 2,"name": "铜牌会员","price": 0}, {"id": 3,"name": "银牌会员","price": 0}]}, {"attr": [{"attrId": 9,"attrName": "颜色","attrValue": "黑色"}, {"attrId": 10,"attrName": "内存","attrValue": "4GB"}, {"attrId": 13,"attrName": "机身长度(mm)","attrValue": "158.3"}],"skuName": "2 黑色 4GB 158.3","price": 0,"skuTitle": "2 黑色 4GB 158.3","skuSubtitle": "","images": [{"imgUrl": "","defaultImg": 0}],"descar": ["黑色", "4GB", "158.3"],"fullCount": 0,"discount": 0,"countStatus": 0,"fullPrice": 0,"reducePrice": 0,"priceStatus": 0,"memberPrice": [{"id": 2,"name": "铜牌会员","price": 0}, {"id": 3,"name": "银牌会员","price": 0}]}, {"attr": [{"attrId": 9,"attrName": "颜色","attrValue": "黑色"}, {"attrId": 10,"attrName": "内存","attrValue": "4GB"}, {"attrId": 13,"attrName": "机身长度(mm)","attrValue": "135.9"}],"skuName": "2 黑色 4GB 135.9","price": 0,"skuTitle": "2 黑色 4GB 135.9","skuSubtitle": "","images": [{"imgUrl": "","defaultImg": 0}],"descar": ["黑色", "4GB", "135.9"],"fullCount": 0,"discount": 0,"countStatus": 0,"fullPrice": 0,"reducePrice": 0,"priceStatus": 0,"memberPrice": [{"id": 2,"name": "铜牌会员","price": 0}, {"id": 3,"name": "银牌会员","price": 0}]}, {"attr": [{"attrId": 9,"attrName": "颜色","attrValue": "白色"}, {"attrId": 10,"attrName": "内存","attrValue": "6GB"}, {"attrId": 13,"attrName": "机身长度(mm)","attrValue": "158.3"}],"skuName": "2 白色 6GB 158.3","price": 0,"skuTitle": "2 白色 6GB 158.3","skuSubtitle": "","images": [{"imgUrl": "","defaultImg": 0}],"descar": ["白色", "6GB", "158.3"],"fullCount": 0,"discount": 0,"countStatus": 0,"fullPrice": 0,"reducePrice": 0,"priceStatus": 0,"memberPrice": [{"id": 2,"name": "铜牌会员","price": 0}, {"id": 3,"name": "银牌会员","price": 0}]}, {"attr": [{"attrId": 9,"attrName": "颜色","attrValue": "白色"}, {"attrId": 10,"attrName": "内存","attrValue": "6GB"}, {"attrId": 13,"attrName": "机身长度(mm)","attrValue": "135.9"}],"skuName": "2 白色 6GB 135.9","price": 0,"skuTitle": "2 白色 6GB 135.9","skuSubtitle": "","images": [{"imgUrl": "","defaultImg": 0}],"descar": ["白色", "6GB", "135.9"],"fullCount": 0,"discount": 0,"countStatus": 0,"fullPrice": 0,"reducePrice": 0,"priceStatus": 0,"memberPrice": [{"id": 2,"name": "铜牌会员","price": 0}, {"id": 3,"name": "银牌会员","price": 0}]}, {"attr": [{"attrId": 9,"attrName": "颜色","attrValue": "白色"}, {"attrId": 10,"attrName": "内存","attrValue": "4GB"}, {"attrId": 13,"attrName": "机身长度(mm)","attrValue": "158.3"}],"skuName": "2 白色 4GB 158.3","price": 0,"skuTitle": "2 白色 4GB 158.3","skuSubtitle": "","images": [{"imgUrl": "","defaultImg": 0}],"descar": ["白色", "4GB", "158.3"],"fullCount": 0,"discount": 0,"countStatus": 0,"fullPrice": 0,"reducePrice": 0,"priceStatus": 0,"memberPrice": [{"id": 2,"name": "铜牌会员","price": 0}, {"id": 3,"name": "银牌会员","price": 0}]}, {"attr": [{"attrId": 9,"attrName": "颜色","attrValue": "白色"}, {"attrId": 10,"attrName": "内存","attrValue": "4GB"}, {"attrId": 13,"attrName": "机身长度(mm)","attrValue": "135.9"}],"skuName": "2 白色 4GB 135.9","price": 0,"skuTitle": "2 白色 4GB 135.9","skuSubtitle": "","images": [{"imgUrl": "","defaultImg": 0}],"descar": ["白色", "4GB", "135.9"],"fullCount": 0,"discount": 0,"countStatus": 0,"fullPrice": 0,"reducePrice": 0,"priceStatus": 0,"memberPrice": [{"id": 2,"name": "铜牌会员","price": 0}, {"id": 3,"name": "银牌会员","price": 0}]}]
}

3.生成JavaBean

image-20211014175017715

下载代码

image-20211014175242777

将生成的代码放入

gulimall-product/src/main/java/site/zhourui/gulimall/product/vo

image-20211014175353861

image-20211014175828426

4.使用lombok

将所有生成的的实体类删除getter/setter方法,替换为@Data

将所有Double类型的字段换成BigDecimal

将所有id的类型换成Long

5.完整示例

1.Attr

package site.zhourui.gulimall.product.vo;import lombok.Data;/*** Auto-generated: 2021-10-14 17:59:35** @author bejson.com (i@bejson.com)* @website http://www.bejson.com/java2pojo/*/
@Data
public class Attr {private Long attrId;private String attrName;private String attrValue;}

2.BaseAttrs

package site.zhourui.gulimall.product.vo;import lombok.Data;/*** Auto-generated: 2021-10-14 17:59:35** @author bejson.com (i@bejson.com)* @website http://www.bejson.com/java2pojo/*/
@Data
public class BaseAttrs {private Long attrId;private String attrValues;private int showDesc;}

3.Bounds

package site.zhourui.gulimall.product.vo;import lombok.Data;import java.math.BigDecimal;/*** Auto-generated: 2021-10-14 17:59:35** @author bejson.com (i@bejson.com)* @website http://www.bejson.com/java2pojo/*/
@Data
public class Bounds {private BigDecimal buyBounds;private BigDecimal growBounds;}

4.BrandVo

package site.zhourui.gulimall.product.vo;import lombok.Data;@Data
public class BrandVo {/*** "brandId": 0,* "brandName": "string",*/private Long brandId;private String  brandName;
}

5.Images

package site.zhourui.gulimall.product.vo;import lombok.Data;/*** Auto-generated: 2021-10-14 17:59:35** @author bejson.com (i@bejson.com)* @website http://www.bejson.com/java2pojo/*/
@Data
public class Images {private String imgUrl;private int defaultImg;}

6.MemberPrice

package site.zhourui.gulimall.product.vo;import lombok.Data;import java.math.BigDecimal;/*** Auto-generated: 2021-10-14 17:59:35** @author bejson.com (i@bejson.com)* @website http://www.bejson.com/java2pojo/*/
@Data
public class MemberPrice {private Long id;private String name;private BigDecimal price;}

7.Skus

package site.zhourui.gulimall.product.vo;
import lombok.Data;import java.math.BigDecimal;
import java.util.List;/*** Auto-generated: 2021-10-14 17:59:35** @author bejson.com (i@bejson.com)* @website http://www.bejson.com/java2pojo/*/
@Data
public class Skus {private List<Attr> attr;private String skuName;private BigDecimal price;private String skuTitle;private String skuSubtitle;private List<Images> images;private List<String> descar;private int fullCount;private BigDecimal discount;private int countStatus;private BigDecimal fullPrice;private BigDecimal reducePrice;private int priceStatus;private List<MemberPrice> memberPrice;}

8.SpuSaveVo

package site.zhourui.gulimall.product.vo;import lombok.Data;import java.math.BigDecimal;
import java.util.List;/*** Auto-generated: 2021-10-14 17:59:35** @author bejson.com (i@bejson.com)* @website http://www.bejson.com/java2pojo/*/
@Data
public class SpuSaveVo {private String spuName;private String spuDescription;private Long catalogId;private Long brandId;private BigDecimal weight;private int publishStatus;private List<String> decript;private List<String> images;private Bounds bounds;private List<BaseAttrs> baseAttrs;private List<Skus> skus;
}

6.商品新增业务流程分析

修改商品保存接口

com/atguigu/gulimall/product/controller/SpuInfoController.java

	/*** 保存*/@RequestMapping("/save")//@RequiresPermissions("product:spuinfo:save")public R save(@RequestBody SpuSaveVo vo){//spuInfoService.save(spuInfo);spuInfoService.saveSpuInfo(vo);return R.ok();}

新增saveSpuInfo方法

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/SpuInfoService.java

void saveSpuInfo(SpuSaveVo vo);

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/impl/SpuInfoServiceImpl.java

新增saveSpuInfo方法实现(完整示例)

1.商品新增业务流程分析

  1. 保存spu基本信息 pms_spu_info

  2. 保存Spu的描述图片 pms_spu_info_desc

  3. 保存spu的图片集 pms_spu_images

  4. 保存spu的规格参数;pms_product_attr_value

  5. 保存spu的积分信息;gulimall_sms->sms_spu_bounds (此处需要调用优惠模块服务(gulimall-coupon)的积分接口)

  6. 保存当前spu对应的所有sku信息;

    1. sku的基本信息;pms_sku_info

    2. sku的图片信息;pms_sku_image

    3. sku的销售属性信息:pms_sku_sale_attr_value

    4. sku的优惠、满减等信息;gulimall_sms->sms_sku_laddersms_sku_full_reductionsms_member_price

      (此处需要调用优惠模块服务(gulimall-coupon)优惠阶段接口满减优惠接口会员价接口)

/*** //TODO 高级部分完善* @param vo*/
@Transactional
@Override
public void saveSpuInfo(SpuSaveVo vo) {//1、保存spu基本信息 pms_spu_infoSpuInfoEntity infoEntity = new SpuInfoEntity();BeanUtils.copyProperties(vo,infoEntity);infoEntity.setCreateTime(new Date());infoEntity.setUpdateTime(new Date());this.saveBaseSpuInfo(infoEntity);//2、保存Spu的描述图片 pms_spu_info_descList<String> decript = vo.getDecript();SpuInfoDescEntity descEntity = new SpuInfoDescEntity();descEntity.setSpuId(infoEntity.getId());descEntity.setDecript(String.join(",",decript));spuInfoDescService.saveSpuInfoDesc(descEntity);//3、保存spu的图片集 pms_spu_imagesList<String> images = vo.getImages();imagesService.saveImages(infoEntity.getId(),images);//4、保存spu的规格参数;pms_product_attr_valueList<BaseAttrs> baseAttrs = vo.getBaseAttrs();List<ProductAttrValueEntity> collect = baseAttrs.stream().map(attr -> {ProductAttrValueEntity valueEntity = new ProductAttrValueEntity();valueEntity.setAttrId(attr.getAttrId());AttrEntity id = attrService.getById(attr.getAttrId());valueEntity.setAttrName(id.getAttrName());valueEntity.setAttrValue(attr.getAttrValues());valueEntity.setQuickShow(attr.getShowDesc());valueEntity.setSpuId(infoEntity.getId());return valueEntity;}).collect(Collectors.toList());attrValueService.saveProductAttr(collect);//5、保存spu的积分信息;gulimall_sms->sms_spu_boundsBounds bounds = vo.getBounds();SpuBoundTo spuBoundTo = new SpuBoundTo();BeanUtils.copyProperties(bounds,spuBoundTo);spuBoundTo.setSpuId(infoEntity.getId());R r = couponFeignService.saveSpuBounds(spuBoundTo);if(r.getCode() != 0){log.error("远程保存spu积分信息失败");}//5、保存当前spu对应的所有sku信息;List<Skus> skus = vo.getSkus();if(skus!=null && skus.size()>0){skus.forEach(item->{String defaultImg = "";for (Images image : item.getImages()) {if(image.getDefaultImg() == 1){defaultImg = image.getImgUrl();}}//    private String skuName;//    private BigDecimal price;//    private String skuTitle;//    private String skuSubtitle;SkuInfoEntity skuInfoEntity = new SkuInfoEntity();BeanUtils.copyProperties(item,skuInfoEntity);skuInfoEntity.setBrandId(infoEntity.getBrandId());skuInfoEntity.setCatalogId(infoEntity.getCatalogId());skuInfoEntity.setSaleCount(0L);skuInfoEntity.setSpuId(infoEntity.getId());skuInfoEntity.setSkuDefaultImg(defaultImg);//5.1)、sku的基本信息;pms_sku_infoskuInfoService.saveSkuInfo(skuInfoEntity);Long skuId = skuInfoEntity.getSkuId();List<SkuImagesEntity> imagesEntities = item.getImages().stream().map(img -> {SkuImagesEntity skuImagesEntity = new SkuImagesEntity();skuImagesEntity.setSkuId(skuId);skuImagesEntity.setImgUrl(img.getImgUrl());skuImagesEntity.setDefaultImg(img.getDefaultImg());return skuImagesEntity;}).filter(entity->{//返回true就是需要,false就是剔除return !StringUtils.isEmpty(entity.getImgUrl());}).collect(Collectors.toList());//5.2)、sku的图片信息;pms_sku_imageskuImagesService.saveBatch(imagesEntities);//TODO 没有图片路径的无需保存List<Attr> attr = item.getAttr();List<SkuSaleAttrValueEntity> skuSaleAttrValueEntities = attr.stream().map(a -> {SkuSaleAttrValueEntity attrValueEntity = new SkuSaleAttrValueEntity();BeanUtils.copyProperties(a, attrValueEntity);attrValueEntity.setSkuId(skuId);return attrValueEntity;}).collect(Collectors.toList());//5.3)、sku的销售属性信息:pms_sku_sale_attr_valueskuSaleAttrValueService.saveBatch(skuSaleAttrValueEntities);// //5.4)、sku的优惠、满减等信息;gulimall_sms->sms_sku_laddersms_sku_full_reductionsms_member_priceSkuReductionTo skuReductionTo = new SkuReductionTo();BeanUtils.copyProperties(item,skuReductionTo);skuReductionTo.setSkuId(skuId);if(skuReductionTo.getFullCount() >0 || skuReductionTo.getFullPrice().compareTo(new BigDecimal("0")) == 1){R r1 = couponFeignService.saveSkuReduction(skuReductionTo);if(r1.getCode() != 0){log.error("远程保存sku优惠信息失败");}}});}}

7.流程分析所需接口

1.保存spu基本信息

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/SpuInfoService.java

void saveBaseSpuInfo(SpuInfoEntity infoEntity);

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/impl/SpuInfoServiceImpl.java

@Override
public void saveBaseSpuInfo(SpuInfoEntity infoEntity) {this.baseMapper.insert(infoEntity);
}

2.保存Spu的描述图片

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/SpuInfoDescService.java

void saveSpuInfoDesc(SpuInfoDescEntity descEntity);

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/impl/SpuInfoDescServiceImpl.java

@Override
public void saveSpuInfoDesc(SpuInfoDescEntity descEntity) {this.baseMapper.insert(descEntity);
}

3.保存spu的图片集

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/SpuImagesService.java

    void saveImages(Long id, List<String> images);

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/impl/SpuImagesServiceImpl.java

@Override
public void saveImages(Long id, List<String> images) {if(images == null || images.size() == 0){}else{List<SpuImagesEntity> collect = images.stream().map(img -> {SpuImagesEntity spuImagesEntity = new SpuImagesEntity();spuImagesEntity.setSpuId(id);spuImagesEntity.setImgUrl(img);return spuImagesEntity;}).collect(Collectors.toList());this.saveBatch(collect);}
}

4.保存spu的规格参数

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/ProductAttrValueService.java

void saveProductAttr(List<ProductAttrValueEntity> collect);

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/impl/ProductAttrValueServiceImpl.java

	@Overridepublic void saveProductAttr(List<ProductAttrValueEntity> collect) {this.saveBatch(collect);}

5.保存spu的积分信息(远程调用)

此处需要调用远程服务

新增新增spu积分传输对象

调用者和被调用者可能都需要这个对象,所以放在gulimall-common模块下

gulimall-common/src/main/java/site/zhourui/common/to/SpuBoundTo.java

调用者

调用者需要开启远程调用@EnableFeignClients

gulimall-product/src/main/java/site/zhourui/gulimall/product/GulimallProductApplication.java

@EnableFeignClients不加属性值会默认扫描主类同级下的所有包下带有@FeignClient的接口,加了会扫描指定包下的所有接口

//@EnableFeignClients
@EnableFeignClients("site.zhourui.gulimall.product.feign")
@SpringBootApplication
@EnableDiscoveryClient
public class GulimallProductApplication {public static void main(String[] args) {SpringApplication.run(GulimallProductApplication.class, args);}
}
@FeignClient("gulimall-coupon")
public interface CouponFeignService {/*** 1、CouponFeignService.saveSpuBounds(spuBoundTo);*      1)、@RequestBody将这个对象转为json。*      2)、找到gulimall-coupon服务,给/coupon/spubounds/save发送请求。*          将上一步转的json放在请求体位置,发送请求;*      3)、对方服务收到请求。请求体里有json数据。*          (@RequestBody SpuBoundsEntity spuBounds);将请求体的json转为SpuBoundsEntity;* 只要json数据模型是兼容的。双方服务无需使用同一个to* @param spuBoundTo* @return*/@PostMapping("/coupon/spubounds/save")R saveSpuBounds(@RequestBody SpuBoundTo spuBoundTo);
}

被调用者

gulimall-coupon/src/main/java/site/zhourui/gulimall/coupon/controller/SpuBoundsController.java

此方法是逆向生成的

	/*** 保存*/@RequestMapping("/save")public R save(@RequestBody SpuBoundsEntity spuBounds){spuBoundsService.save(spuBounds);return R.ok();}

gulimall-common/src/main/java/site/zhourui/common/to/SpuBoundTo.java

package site.zhourui.common.to;import lombok.Data;import java.math.BigDecimal;@Data
public class SpuBoundTo {private Long spuId;private BigDecimal buyBounds;private BigDecimal growBounds;
}

调用者传的参数是SpuBoundTo,被调用者接收的参数是SpuBoundsEntity,这样使用的原因是@RequestBody将对象转化为json,这样只需要属性名相同就可以接收,如果不这样就需要相同的对象才能接收

6.保存当前spu对应的所有sku信息

1.sku的基本信息

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/SkuInfoService.java

void saveSkuInfo(SkuInfoEntity skuInfoEntity);

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/impl/SkuInfoServiceImpl.java

@Override
public void saveSkuInfo(SkuInfoEntity skuInfoEntity) {this.baseMapper.insert(skuInfoEntity);
}

2.sku的图片信息

保存sku图片信息是利用逆向工程生成的批量保存方法saveBatch

skuImagesService.saveBatch(imagesEntities);

3.sku的销售属性信息

保存sku销售属性是利用逆向工程生成的批量保存方法saveBatch

skuSaleAttrValueService.saveBatch(skuSaleAttrValueEntities);

4.sku的优惠、满减等信息(远程调用)

所需to

gulimall-common/src/main/java/site/zhourui/common/to/SkuReductionTo.java

package site.zhourui.common.to;import lombok.Data;import java.math.BigDecimal;
import java.util.List;@Data
public class SkuReductionTo {private Long skuId;private int fullCount;private BigDecimal discount;private int countStatus;private BigDecimal fullPrice;private BigDecimal reducePrice;private int priceStatus;private List<MemberPrice> memberPrice;
}

gulimall-coupon/src/main/java/site/zhourui/gulimall/coupon/controller/SpuBoundsController.java

新增方法

 	@PostMapping("/coupon/skufullreduction/saveinfo")R saveSkuReduction(@RequestBody SkuReductionTo skuReductionTo);

被调用者

gulimall-coupon/src/main/java/site/zhourui/gulimall/coupon/controller/SkuFullReductionController.java

	@PostMapping("/saveinfo")public R saveInfo(@RequestBody SkuReductionTo reductionTo){skuFullReductionService.saveSkuReduction(reductionTo);return R.ok();}

被调用者中需要实现对优惠信息的保存的接口

gulimall-coupon/src/main/java/site/zhourui/gulimall/coupon/service/SkuFullReductionService.java

新增接口

void saveSkuReduction(SkuReductionTo reductionTo);

gulimall-coupon/src/main/java/site/zhourui/gulimall/coupon/service/impl/SkuFullReductionServiceImpl.java

新增接口实现

@Overridepublic void saveSkuReduction(SkuReductionTo reductionTo) {//1、// //5.4)、sku的优惠、满减等信息;gulimall_sms->sms_sku_laddersms_sku_full_reductionsms_member_price//sms_sku_ladderSkuLadderEntity skuLadderEntity = new SkuLadderEntity();skuLadderEntity.setSkuId(reductionTo.getSkuId());skuLadderEntity.setFullCount(reductionTo.getFullCount());skuLadderEntity.setDiscount(reductionTo.getDiscount());skuLadderEntity.setAddOther(reductionTo.getCountStatus());if(reductionTo.getFullCount() > 0){skuLadderService.save(skuLadderEntity);}//2、sms_sku_full_reductionSkuFullReductionEntity reductionEntity = new SkuFullReductionEntity();BeanUtils.copyProperties(reductionTo,reductionEntity);if(reductionEntity.getFullPrice().compareTo(new BigDecimal("0"))==1){this.save(reductionEntity);}//3、sms_member_priceList<MemberPrice> memberPrice = reductionTo.getMemberPrice();List<MemberPriceEntity> collect = memberPrice.stream().map(item -> {MemberPriceEntity priceEntity = new MemberPriceEntity();priceEntity.setSkuId(reductionTo.getSkuId());priceEntity.setMemberLevelId(item.getId());priceEntity.setMemberLevelName(item.getName());priceEntity.setMemberPrice(item.getPrice());priceEntity.setAddOther(1);return priceEntity;}).filter(item->{return item.getMemberPrice().compareTo(new BigDecimal("0")) == 1;}).collect(Collectors.toList());memberPriceService.saveBatch(collect);}

8.分组批量启用模块,及设置模块最大内存

1.分组批量启用模块

image-20211015142309681

选着需要批量保存的服务并添加

image-20211015142350501

添加完成后重命名后就可批量启动了

image-20211015142504518

2.设置模块最大使用内存

每个模块都设置相同的值

image-20211015143002914

9.新增商品测试

1.mysql设置事务隔离级别(方便事务调试)

mysql默认的隔离级别为读已提交,为了能够在调试过程中,获取到数据库中的数据信息,可以调整隔离级别为读未提交

但是它对于当前的事务窗口生效,如果想要设置全局的,需要加上global字段。

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;SELECT * FROM `pms_spu_info`

image-20211015174429188

一旦报错了事务回滚了,该条数据就消失了

2.数据库自增,存入自己的数据

比如此处报错信息

Cause: java.sql.SQLException: Field ‘spu_id’ doesn’t have a default value

解释:数据库spu_id字段有默认值,但是我们传入了值

原因:数据库spu_id字段设置了自增,但是我们传入了值

1.解决方案一

将该字段实体类的@TableId加上type = IdType.INPUT,表示可输入

	/*** 商品id*/@TableId(type = IdType.INPUT)private Long spuId;

2.解决方法二

将该字段的自动递增关闭

image-20211015180532361

3.存入空图片地址问题

image-20211017155547471

原因:

前端传入spu图片时没有选中图片时该路径会是空

image-20211017155824526

解决保存sku的图片信息时,先筛选一次,imgurl为空的话就不保存了

10.SPU检索

1.检索条件

image-20211017160449270

2.后端增加接口

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/SpuInfoService.java

新增接口

PageUtils queryPageByCondition(Map<String, Object> params);

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/impl/SpuInfoServiceImpl.java

新增接口实现

@Overridepublic PageUtils queryPageByCondition(Map<String, Object> params) {QueryWrapper<SpuInfoEntity> wrapper = new QueryWrapper<>();String key = (String) params.get("key");if(!StringUtils.isEmpty(key)){wrapper.and((w)->{w.eq("id",key).or().like("spu_name",key);});}// status=1 and (id=1 or spu_name like xxx)String status = (String) params.get("status");if(!StringUtils.isEmpty(status)){wrapper.eq("publish_status",status);}String brandId = (String) params.get("brandId");if(!StringUtils.isEmpty(brandId)&&!"0".equalsIgnoreCase(brandId)){wrapper.eq("brand_id",brandId);}String catelogId = (String) params.get("catelogId");if(!StringUtils.isEmpty(catelogId)&&!"0".equalsIgnoreCase(catelogId)){wrapper.eq("catalog_id",catelogId);}/*** status: 2* key:* brandId: 9* catelogId: 225*/IPage<SpuInfoEntity> page = this.page(new Query<SpuInfoEntity>().getPage(params),wrapper);return new PageUtils(page);}

gulimall-product/src/main/java/site/zhourui/gulimall/product/controller/SpuInfoController.java

修改查询方法,调用条件查询

/*** 列表*/@RequestMapping("/list")//@RequiresPermissions("product:spuinfo:list")public R list(@RequestParam Map<String, Object> params){PageUtils page = spuInfoService.queryPageByCondition(params);return R.ok().put("page", page);}

3.时间格式问题

image-20211017161810753

解决

gulimall-product/src/main/resources/application.yml加上如下配置

该配置会将该模块下的所有时间转化为指定格式

  jackson:date-format: yyyy-MM-dd HH:mm:ss

image-20211017162004377

4.重启并测试

测试结果

image-20211017161523834

11.SKU检索

1.检索条件

image-20211017162225730

2.后端新增接口

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/SkuInfoService.java

新增接口

PageUtils queryPageByCondition(Map<String, Object> params);

gulimall-product/src/main/java/site/zhourui/gulimall/product/service/impl/SkuInfoServiceImpl.java

新增接口实现

@Overridepublic PageUtils queryPageByCondition(Map<String, Object> params) {QueryWrapper<SkuInfoEntity> queryWrapper = new QueryWrapper<>();/*** key:* catelogId: 0* brandId: 0* min: 0* max: 0*/String key = (String) params.get("key");if(!StringUtils.isEmpty(key)){queryWrapper.and((wrapper)->{wrapper.eq("sku_id",key).or().like("sku_name",key);});}String catelogId = (String) params.get("catelogId");if(!StringUtils.isEmpty(catelogId)&&!"0".equalsIgnoreCase(catelogId)){queryWrapper.eq("catalog_id",catelogId);}String brandId = (String) params.get("brandId");if(!StringUtils.isEmpty(brandId)&&!"0".equalsIgnoreCase(catelogId)){queryWrapper.eq("brand_id",brandId);}String min = (String) params.get("min");if(!StringUtils.isEmpty(min)){queryWrapper.ge("price",min);}String max = (String) params.get("max");if(!StringUtils.isEmpty(max)  ){try{BigDecimal bigDecimal = new BigDecimal(max);if(bigDecimal.compareTo(new BigDecimal("0"))==1){queryWrapper.le("price",max);}}catch (Exception e){}}IPage<SkuInfoEntity> page = this.page(new Query<SkuInfoEntity>().getPage(params),queryWrapper);return new PageUtils(page);}

gulimall-product/src/main/java/site/zhourui/gulimall/product/controller/SkuInfoController.java

修改list方法

/*** 列表*/
@RequestMapping("/list")
//@RequiresPermissions("product:skuinfo:list")
public R list(@RequestParam Map<String, Object> params){PageUtils page = skuInfoService.queryPageByCondition(params);return R.ok().put("page", page);
}

3.重启并测试

image-20211017162836255

Published by

风君子

独自遨游何稽首 揭天掀地慰生平