在P83级中,点击发布商品时没有出现请求
则需要解决 PubSub is not definded这个问题
PubSub是用来检测选择分类的值变动的。
选择分类值变动,会请求后台接口,动态更新选择品牌的选项。
- 安装依赖
npm install --save pubsub-js(要到项目目录下安装)
如果安装失败则:
重新这个:
npm install --save pubsub-js --legacy-peer-deps
- 导包
src\views\modules\common\category-cascader.vue
这个vue模块下,增加:
即可解决该问题
将访问路径中有/api/member/的转发到gulimall-member-appication这个模块下
在gateway这个模块下的bootstrp.yml文件中添加负载均衡路径
- id: member
uri: lb://gulimall-member
predicates:
- Path=/api/member/**
filters:
- RewritePath=/api/(?<segment>/?.*), /$\{segment}
将member-application这个模块启动起来
将资料中的
modules下的文件都放到项目中的modules下
添加会员
获取分类关联的品牌
到商品系统的商品维护中添加商品
当点击选择分类后会发送一个请求
如果没有发送请求,查看Console
出现报错 TypeError: Cannot read properties of undefined
解决办法:
则需要到src\views\modules\common\category-cascader.vue下将PubSub函数前面的this去掉
如下:
解决后,编写查询分类关联的品牌的接口
由于返回的data中只含有brandId和brandName
我们写一个BrandVo
@Data
public class BrandVo {
private Long brandId;
private String brandName;
}
在CategoryBrandRelationController中
///product/categorybrandrelation/brands/list
@GetMapping("/brands/list")
public R selectBrandRelation(@RequestParam(value = "catId",required = true)Long catId){
List<BrandEntity> brandEntities = categoryBrandRelationService.getBrandByCatId(catId);
List<BrandVo> collect = brandEntities.stream().map((item) -> {
BrandVo brandVo = new BrandVo();
//由于BrandVo中的品牌名和BrandEntity中的品牌名不是一个变量名
//所以不能直接拷贝
brandVo.setBrandId(item.getBrandId());
brandVo.setBrandName(item.getName());
return brandVo;
}).collect(Collectors.toList());
return R.ok().put("data",collect);
}
编写getBrandByCatId(catId)方法
@Override
public List<BrandEntity> getBrandByCatId(Long catId) {
List<CategoryBrandRelationEntity> categoryBrandRelationEntities = categoryBrandRelationDao.selectList(new QueryWrapper<CategoryBrandRelationEntity>().eq("catelog_id", catId));
//可能别的方法也需要调这个方法,我们返回品牌的详细信息
List<BrandEntity> collect = categoryBrandRelationEntities.stream().map((item) -> {
Long brandId = item.getBrandId();
BrandEntity brandEntity = brandDao.selectById(brandId);
return brandEntity;
}).collect(Collectors.toList());
return collect;
}
实现效果:
先将spuadd.vue中的
设置为false
出现了循环依赖的问题
在配置文件中添加:
spring:
main:
allow-circular-references:true
效果展示:
展示销售属性
点击下一步设置销售属性没有出现数据
1、数据库中没有存销售属性
2、在spuadd.vue中,自己传一个key
效果展示:
商品保存功能
根据前端返回的字符串逆向生成JAVA实体类
注意:将pms_spu_info表中的catalog_id改为catelog_id
并且将对应的实体类中的catalogId修改为catelogId
并且将前端中的cpuinfor.vue中的catalogId修改成catelogId
在SpuInfoController中
/**
* 保存
*/
@Transactional
@RequestMapping("/save")
public R save(@RequestBody SpuSaveVo spuInfo){
// spuInfoService.save(spuInfo);
//1、保存Spu的基本信息
SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
//SpuInfoEntity中的属性名和SpuSaveVo中的一样
//直接对拷
BeanUtils.copyProperties(spuInfo,spuInfoEntity);
spuInfoEntity.setCreateTime(new Date());
spuInfoEntity.setUpdateTime(new Date());
spuInfoService.saveBaseSpuInfo(spuInfoEntity);
//2、保存spu的描述图片pms_spu_info_desc
SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
List<String> decript = spuInfo.getDecript();
spuInfoDescEntity.setSpuId(spuInfoEntity.getId());
spuInfoDescEntity.setDecript(String.join(",",decript));
spuInfoDescService.saveSpuInfoDesc(spuInfoDescEntity);
//3、保存spu的图片集 pms_spu_images
List<String> images = spuInfo.getImages();
spuImagesService.saveImages(spuInfoEntity.getId(),images);
//4、保存spu的规格参数 pms_product_attr_value
List<BaseAttrs> baseAttrs = spuInfo.getBaseAttrs();
List<ProductAttrValueEntity> collect = baseAttrs.stream().map((attr) -> {
ProductAttrValueEntity productAttrValueEntity = new ProductAttrValueEntity();
productAttrValueEntity.setAttrId(attr.getAttrId());
productAttrValueEntity.setAttrName(attrService.getById(attr.getAttrId()).getAttrName());
productAttrValueEntity.setAttrValue(attr.getAttrValues());
productAttrValueEntity.setQuickShow(attr.getShowDesc());
productAttrValueEntity.setSpuId(spuInfoEntity.getId());
return productAttrValueEntity;
}).collect(Collectors.toList());
productAttrValueService.saveProductAttr(collect);
//5、保存spu的积分信息 gulimall_sms->sms_spu_bounds
//5.1、sku的基本信息:pms_sku_info
//5.2、sku的图片信息:pms_sku_images
//5.3、sku的销售图片信息:pms_keu_sale_attr_value
//5.4、sku的优惠、满减等信息:gulimall_sms_sku_ladder\sms_sku_full_reduction\
一、saveBaseSpuInfo(spuInfoEntity)
@Override
public void saveBaseSpuInfo(SpuInfoEntity spuInfoEntity) {
this.baseMapper.insert(spuInfoEntity);
}
二、saveSpuInfoDesc(spuInfoDescEntity);
@Override
public void saveSpuInfoDesc(SpuInfoDescEntity spuInfoDescEntity) {
this.baseMapper.insert(spuInfoDescEntity);
}
三、saveImages(spuInfoEntity.getId(),images);
@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);
}
}
四、saveProductAttr(collect);
@Override
public void saveProductAttr(List<ProductAttrValueEntity> collect) {
this.saveBatch(collect);
}
5.1、5.2、5.3
//5.1、sku的基本信息:pms_sku_info
List<Skus> skus = spuInfo.getSkus();
if (skus!=null&skus.size()!=0){
skus.forEach((item)->{
String defaultImg="";
for (Images image : item.getImages()) {
if (image.getDefaultImg()==1){
//是默认图片
defaultImg=image.getImgUrl();
}
}
SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
BeanUtils.copyProperties(item,skuInfoEntity);
// catalogId brandId saleCount spuId skuDefaultImg
skuInfoEntity.setBrandId(spuInfoEntity.getBrandId());
skuInfoEntity.setCatalogId(spuInfoEntity.getCatalogId());
skuInfoEntity.setSaleCount(0L);
skuInfoEntity.setSpuId(spuInfoEntity.getId());
skuInfoEntity.setSkuDefaultImg(defaultImg);
skuInfoServicel.saveSkuInfo(skuInfoEntity);
//5.2、sku的图片信息:pms_sku_images
Long skuId = skuInfoEntity.getSkuId();
List<Images> images1 = item.getImages();
List<SkuImagesEntity> collect1 = images1.stream().map((img) -> {
SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
skuImagesEntity.setSkuId(skuId);
skuImagesEntity.setImgUrl(img.getImgUrl());
skuImagesEntity.setDefaultImg(img.getDefaultImg());
return skuImagesEntity;
}).collect(Collectors.toList());
skuImagesService.saveBatch(collect1);
//5.3、sku的销售图片信息:pms_keu_sale_attr_value
List<Attr> attr = item.getAttr();
List<SkuSaleAttrValueEntity> collect2 = attr.stream().map(a -> {
SkuSaleAttrValueEntity skuSaleAttrValue = new SkuSaleAttrValueEntity();
BeanUtils.copyProperties(a, skuSaleAttrValue);
skuSaleAttrValue.setSkuId(skuId);
return skuSaleAttrValue;
}).collect(Collectors.toList());
skuSaleAttrValueService.saveBatch(collect2);
});
}
5.保存积分信息保存商品积分
在common模块下创建一个to包,用来存放远程调用传输的对象
@Data
public class SpuBoundTo {
private Long spuId;
private BigDecimal buyBounds;
private BigDecimal growBounds;
}
创建一个包feign用来存放远程调用的接口
@FeignClient("gulimall-coupon")
public interface CouponFenginService {
@PostMapping("coupon/spubounds/save")
R saveSpuBounds(@RequestBody SpuBoundTo spuBounds);
}
在SpuInforController中
//5、保存spu的积分信息 gulimall_sms->sms_spu_bounds
SpuBoundTo spuBoundTo = new SpuBoundTo();
Bounds bounds = spuInfo.getBounds();
BeanUtils.copyProperties(bounds,spuBoundTo);
spuBoundTo.setSpuId(spuInfoEntity.getId());
couponFenginService.saveSpuBounds(spuBoundTo);
if (r1.getCode()!=0){
System.err.println("远程保存spu积分信息失败");
}
5.4
同样需要远程调用
在CouponFenginService中
@PostMapping("/coupon/skufullreduction/saveinfo")
R saveSkuReduction(@RequestBody SkuReductionTo skuReductionTo);
@PostMapping("/saveinfo")
public R saveinfo(@RequestBody SkuReductionTo skuReductionTo){
skuFullReductionService.saveSkuReduction(skuReductionTo);
return R.ok();
}
//5.4、sku的优惠、满减等信息:gulimall_sms_sku_ladder\sms_sku_full_reduction\
SkuReductionTo skuReductionTo = new SkuReductionTo();
BeanUtils.copyProperties(item,skuReductionTo);
skuReductionTo.setSkuId(skuId);
R r = couponFenginService.saveSkuReduction(skuReductionTo);
if (r.getCode()!=0){
//有异常
System.err.println("远程保存spu优惠信息失败");
}
减小内存开销
设置最大占用内存100m
注意:
这里要将这个设置为input因为在数据库设计时,这个不是自增的
优化细节:
添加filter判断
在SpuinfoController
在SkuFullReductionServiceImpl中
SPU检索
实现效果:
在SpuInfoController中
/**
* 列表
*/
@GetMapping("/list")
public R list(@RequestParam Map<String, Object> params){
PageUtils page = spuInfoService.queryPageByKey(params);
return R.ok().put("page", page);
}
生成queryPageByKey(params)方法
@Override
public PageUtils queryPageByKey(Map<String, Object> params) {
QueryWrapper<SpuInfoEntity> spuInfoEntityQueryWrapper = new QueryWrapper<>();
String key = (String) params.get("key");
if (!StringUtils.isEmpty(key)){
spuInfoEntityQueryWrapper.and((queryWrapper)->{
queryWrapper.eq("id",key).or().like("spu_name",key);
});
}
String catelogId = (String) params.get("catelogId");
if (!StringUtils.isEmpty(catelogId)&&!"0".equalsIgnoreCase(catelogId)){
spuInfoEntityQueryWrapper.eq("catelog_id",catelogId);
}
String brandId = (String) params.get("brandId");
if (!StringUtils.isEmpty(brandId)&&!"0".equalsIgnoreCase(brandId)){
spuInfoEntityQueryWrapper.eq("brand_id",brandId);
}
String status = (String) params.get("status");
if (!StringUtils.isEmpty(status)){
spuInfoEntityQueryWrapper.eq("publish_status",status);
}
IPage<SpuInfoEntity> page = this.page(
new Query<SpuInfoEntity>().getPage(params),
spuInfoEntityQueryWrapper
);
return new PageUtils(page);
}
日期格式化
在yml配置文件中设置
jackson:
date-format: yyyy-MM-dd HH:mm:ss
SKU检索
将pms_sku_info中的catalog_id修改为catelog_id
并将skuInfoEntity的catalogId修改为catelogId
在skuInfoController中
@RequestMapping("/list")
// @RequiresPermissions("product:skuinfo:list")
public R list(@RequestParam Map<String, Object> params){
PageUtils page = skuInfoService.queryPageByConditions(params);
return R.ok().put("page", page);
}
编写queryPageByConditions(params);
@Override
public PageUtils queryPageByConditions(Map<String, Object> params) {
/*
key: '华为',//检索关键字
catelogId: 0,
brandId: 0,
min: 0,
max: 0
*/
QueryWrapper<SkuInfoEntity> skuInfoEntityQueryWrapper = new QueryWrapper<>();
String key = (String) params.get("key");
if (!StringUtils.isEmpty(key)){
skuInfoEntityQueryWrapper.and((queryWrapper)->{
queryWrapper.eq("sku_id",key).or().like("sku_name",key);
});
}
String catelogId = (String) params.get("catelogId");
if (!StringUtils.isEmpty(catelogId)&&!"0".equalsIgnoreCase(catelogId)){
skuInfoEntityQueryWrapper.eq("catelog_id",catelogId);
}
String brandId = (String) params.get("brandId");
if (!StringUtils.isEmpty(brandId)&&!"0".equalsIgnoreCase(brandId)){
skuInfoEntityQueryWrapper.eq("brand_id",brandId);
}
String min = (String) params.get("min");
if (!StringUtils.isEmpty(min)){
skuInfoEntityQueryWrapper.ge("price",min);
}
String max = (String) params.get("max");
try {
//这里转换可能会有异常
BigDecimal maxBg=new BigDecimal(max);
if (!StringUtils.isEmpty(max)&&maxBg.compareTo(new BigDecimal("0"))==1){
skuInfoEntityQueryWrapper.le("price",max);
}
} catch (Exception e) {
}
IPage<SkuInfoEntity> page = this.page(
new Query<SkuInfoEntity>().getPage(params),
skuInfoEntityQueryWrapper
);
return new PageUtils(page);
}