96SEO 2026-02-19 21:32 0
unit(标准化产品单元)是商品信息聚合的最小单位是一组可复用、易检索的标准化信息的集合该集合描述了一个产品的特性。

如iphone13是SPU它是一个产品的集合
unit(库存量单位)库存进出计量的基本单元可以是件/盒/托盘等单位。
SKU是对于大型连锁超市DC配送中心物流管理的一个必要的方法。
现在已经被引申为产品统一编号的简称每种产品对应有唯一的SKU号。
如iphone13ProMax
像这里的商品介绍规格与包装都是属于SPU的属性。
它们都属于是规格参数
每个三级分类下有各自的属性分组表通过id和catelogid关联能查出每个分类下的属性分组
属性分组表和属性表通过一个属性属性关联表进行关联能查出每个属性分组下的属性
最终这样的关系我们可以查出每个分类的属性分组和每个属性分组对应的属性
商品属性表和属性表通过attrid和id进行关联能查出每个spu的属性
sku销售属性表是为了表示spu下不同sku比如1号spu在此表有两个sku这两个sku有不同的销售属性是通过和属性表关联获取的
正常我们是在系统管理里自定义添加步骤都是一样的其实在前端页面添加就是把数据提交到mall_admin表中,这里我们直接把提供的sql语句导入即可
这个页面就是三级分类和一个表格显示在一块对吧属于是父子组件交互
/product/attrgroup/list/{catelogId},技术团队的文档管理平台接口文档工具支持在线接口调试一键生成API文档适合编写接口文档、产品文档、使用手册https://easydoc.net/s/78237135/ZUqEdvA4/OXTgKobR
别人告诉你需要什么功能需要返回什么样的数据你就通过接口的形式把他们呢实现出来即可
以后工作了也是这种形式主要是开发接口为多前端其实不用写太多能看懂即可
RequestMapping(/list/{catelogId})public
attrGroupService.queryPage(params);PageUtils
attrGroupService.queryPage(params,
params.get(key);QueryWrapperAttrGroupEntity
{obj.eq(attr_group_id,key).or().like(attr_group_name,key);});}if
{//如果是默认的是查全部的一级分类IPageAttrGroupEntity
QueryAttrGroupEntity().getPage(params),wrapper);return
catelogId);IPageAttrGroupEntity
QueryAttrGroupEntity().getPage(params),
attrService.getById(attrId);Long
categoryService.findCatelogPath(catelogId);attr.setCatelogPath(path);return
给一个分类id不断的查它的父类id直到查不到为止最后把查询到的id到放到一个集合里
list);//1.确定递归参数和返回值Collections.reverse(parentPath);return
list){//3.递归逻辑list.add(catelogId);CategoryEntity
(entity.getParentCid()!0){//2.递归终止条件findParentPath(entity.getParentCid(),list);}return
vo){attrService.saveAttr(vo);return
这里注意因为添加规格参数的时候会有选择属性组因为属性组和属性是通过关联关系表连接的所以要有级联操作。
在往pms_attr表插入数据的时候pms_attr_group_relation也要插入
小bug这里有个注意点当添加规格参数的时候如果没有指定规格参数所属分组那么就不应该在关联表中保存关联关系
AttrEntity();//1.将前端接收数据的对象vo赋值给attrEntity对象从而更新数据库BeanUtils.copyProperties(attr,
attrEntity);this.save(attrEntity);if
ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()
{//2.保存关联关系//因为属性组和属性是通过关联关系表连接的AttrAttrgroupRelationEntity
AttrAttrgroupRelationEntity();relationEntity.setAttrGroupId(attr.getAttrGroupId());relationEntity.setAttrId(attrEntity.getAttrId());relationService.save(relationEntity);}}显示规格参数
GetMapping(/base/list/{catelogId})
attrService.queryBaseAttrPage(params,
catelogId);}//多条件模糊查询//搜索框里的key不但可以对catelog_id进行模糊查询对attr_name也模糊查询String
QueryAttrEntity().getPage(params),wrapper);PageUtils
规格参数表pms_attr中有所属分类的信息可以直接调用分类的service进行查询
这里我们就要借助第三张表属性和分组表pms_attr_attrgroup_relation进行查询
通过规格参数表pms_attr获得attr_id之后在调用属性和分组表的service获得属性和分组表的实体类从而获得该属性的分组
下面通过stream流的方式通过map给list集合中的每一项做映射给新实体类AttrRespVo赋值最后返回AttrRespVo
小bug这里显示规格参数的时候会显示规格。
参数对应的分组、分类那么如果它们查出对象分组id或分类id为空那就不设置名字if
QueryWrapperAttrEntity().eq(attr_type,
ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()
ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());if
?//IgnoreCase忽略大小写wrapper.eq(catelog_id,
catelogId);}//多条件模糊查询//搜索框里的key不但可以对catelog_id进行模糊查询对attr_name也模糊查询String
QueryAttrEntity().getPage(params),wrapper);PageUtils
.map()这个方法是对被筛选过后的流进行映射一般是对属性进行赋值。
ListAttrRespVo
AttrRespVo();BeanUtils.copyProperties(item,
QueryWrapperAttrAttrgroupRelationEntity().eq(attr_id,
{//attrgroupRelationEntity.getAttrGroupId()也可以这里可以直接放进去对象AttrGroupEntity
attrGroupService.getById(attrId.getAttrGroupId());attrRespvo.setGroupName(attrGroupEntity.getAttrGroupName());}}CategoryEntity
categoryService.getById(item.getCatelogId());if
{attrRespvo.setCatelogName(categoryEntity.getName());}//返回最后的封装结果return
attrRespvo;}).collect(Collectors.toList());//返回的结果是一个集合pageUtils.setList(resultList);//
可以看出所属分类和分组都是由这条请求查询的那么我们改这个接口功能就行
attrService.getAttrInfo(attrId);return
this.getById(attrId);BeanUtils.copyProperties(attrEntity,
设置分组信息*/AttrAttrgroupRelationEntity
QueryWrapperAttrAttrgroupRelationEntity().eq(attr_id,
null){respVo.setAttrGroupId(attrgroupRelationEntity.getAttrGroupId());Long
attrgroupRelationEntity.getAttrGroupId();AttrGroupEntity
attrGroupService.getById(attrGroupId);if
{respVo.setGroupName(attrGroupEntity.getAttrGroupName());}}/***
attrEntity.getCatelogId();//有了分类的完整路径接下来就设置分类名字Long[]
categoryService.findCatelogPath(catelogId);respVo.setCatelogPath(catelogPath);//获得分类名字CategoryEntity
categoryService.getById(catelogId);if
{respVo.setCatelogName(categoryEntity.getName());}return
{attrService.updateAttr(attr);return
这里做了优化对于规格参数中没有所属分组的如果指定了不在是修改而是添加
拿attr_id去pms_attr_attrgroup_relation表中查询如果改attr_id存在与该表那就修改关联关系
AttrEntity();BeanUtils.copyProperties(attr,
attrEntity);this.updateById(attrEntity);//修改分组关联AttrAttrgroupRelationEntity
AttrAttrgroupRelationEntity();attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());attrAttrgroupRelationEntity.setAttrId(attr.getAttrId());//统计attr_id的关联属性,如果没有初始分组,则进行添加操作;有则进行修改操作Integer
QueryWrapperAttrAttrgroupRelationEntity().eq(attr_id,
{relation.update(attrAttrgroupRelationEntity,
UpdateWrapperAttrAttrgroupRelationEntity().eq(attr_id,
{relation.insert(attrAttrgroupRelationEntity);}
0);更新index.js哪里更新找老师的源码controller
updateSpuAttr(PathVariable(spuId)
entities){productAttrValueService.updateSpuAttr(spuId,entities);return
{//1、删除spuId之前对应的所有属性this.baseMapper.delete(new
QueryWrapperProductAttrValueEntity().eq(spu_id,spuId));//2、添加商品规格信息ListProductAttrValueEntity
item;}).collect(Collectors.toList());//批量新增this.saveBatch(collect);
如图http://localhost:88/api/product/attr/sale/list/0?t1660181297434page1limit10key这个接口有问题
GetMapping(/{attrType}/list/{catelogId})
attrService.queryBaseAttrPage(params,
在原来对规格参数的基础上加了限制条件如果是规格参数那就是WHERE
这里为了使代码更通用1和0的值我们写一个常量来控制如过后期换值了我们直接更改常量的值即可
AttrEnum{ATTR_TYPE_BASE(1,基本属性),ATTR_TYPE_SALE(0,销售属性);private
}在原来对规格参数的基础上加了限制条件如果是规格参数那就是WHERE
QueryWrapperAttrEntity().eq(attr_type,
ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()
ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());if
?//IgnoreCase忽略大小写wrapper.eq(catelog_id,
catelogId);}//多条件模糊查询//搜索框里的key不但可以对catelog_id进行模糊查询对attr_name也模糊查询String
QueryAttrEntity().getPage(params),wrapper);PageUtils
.map()这个方法是对被筛选过后的流进行映射一般是对属性进行赋值。
ListAttrRespVo
AttrRespVo();BeanUtils.copyProperties(item,
attrRespvo);AttrAttrgroupRelationEntity
QueryWrapperAttrAttrgroupRelationEntity().eq(attr_id,
{//attrgroupRelationEntity.getAttrGroupId()也可以这里可以直接放进去对象AttrGroupEntity
attrGroupService.getById(attrgroupRelationEntity);attrRespvo.setGroupName(attrGroupEntity.getAttrGroupName());}CategoryEntity
categoryService.getById(item.getCatelogId());if
{attrRespvo.setCatelogName(categoryEntity.getName());}//返回最后的封装结果return
attrRespvo;}).collect(Collectors.toList());//返回的结果是一个集合pageUtils.setList(resultList);//
但是销售属性和规格参数用的是同一个回显方法我们也进行更改只有是规格参数的时候才进行分组回显
ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())
销售属性和规格参数用的是同一个修改方法销售属性进行修改时会对关联表进行一个级联更新但销售属性不需要
所以也在对关联表级联更新的时候进行判断只有销售属性修改的时候才进行级联更新
ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())
销售属性和规格参数用的是同一个保存方法销售属性进行保存时会对关联表进行一个级联保存但销售属性不需要
所以也在对关联表级联保存的时候进行判断只有销售属性保存的时候才进行级联保存
ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())
点击分组属性的时候获取到分组id拿分组id去关联表查分组id对应的attr_id拿attr_id去pms_attr表中获取属性controller
RequestMapping(/{attrgroupId}/attr/relation)
attrRelation(PathVariable(attrgroupId)
attrService.getRelationAttr(attrgroupId);return
{//分布查询第一步去关联表中查出所有的组和属性idListAttrAttrgroupRelationEntity
QueryWrapperAttrAttrgroupRelationEntity().eq(attr_group_id,attrgroupId));//第二收集属性idListLong
attr.getAttrId();}).collect(Collectors.toList());ListAttrEntity
/product/attrgroup/attr/relation/deletepost请求会带来json数据要封装成自定义对象vos需要RequestBody注解意思就是将请求体中的数据封装成vos/***
PostMapping(/attr/relation/delete)
{attrService.deleteRelation(vos);return
deleteRelation(AttrGroupRelationVo[]
{ListAttrAttrgroupRelationEntity
Arrays.asList(vos).stream().map((item)
AttrAttrgroupRelationEntity();BeanUtils.copyProperties(item,
entity;}).collect(Collectors.toList());relation.deleteBatchRelation(entities);
deleteBatchRelation(Param(entities)
ListAttrAttrgroupRelationEntity
#{item.attrGroupId})/foreach/delete查询分组未关联的属性
/product/attrgroup/{attrgroupId}/noattr/relation*/
RequestMapping(/{attrgroupId}/noattr/relation)
params,PathVariable(attrgroupId)
attrService.getNoRelationAttr(params,attrgroupId);return
获得当前分类下的所有分组获得这些分组下所有已添加的属性添加新属性时移除这些已添加的属性Override
1.当前分组只能关联自己所属的分类里面的所有属性*/AttrGroupEntity
attrGroupService.getById(attrgroupId);Long
attrGroupEntity.getCatelogId();/***
当前分类下的所有分组。
收集到他们的组id*/ListAttrGroupEntity
QueryWrapperAttrGroupEntity().eq(catelog_id,
item.getAttrGroupId();}).collect(Collectors.toList());/***
2通过关系表实体类对象获得所有分组下的所有属性id*/ListAttrAttrgroupRelationEntity
QueryWrapperAttrAttrgroupRelationEntity().in(attr_group_id,
item.getAttrId();}).collect(Collectors.toList());/***
QueryWrapperAttrEntity().eq(catelog_id,
catelogId).eq(attr_type,ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode());//如果其他分组也没关联属性那么就不加这个条件if
1.IPage对象通过工具类Query获取并通过.getPage(params)封装页面传来分页参数*
QueryAttrEntity().getPage(params),
常规的调用注意点是saveBatch传的参数是数据对应的实体类
/product/attrgroup/attr/relation*/
{relationService.saveBatch(vos);return
saveBatch(ListAttrGroupRelationVo
{ListAttrAttrgroupRelationEntity
AttrAttrgroupRelationEntity();BeanUtils.copyProperties(item,
relationEntity;}).collect(Collectors.toList());this.saveBatch(collect);
/product/categorybrandrelation/brands/list*/
relationBrandList(RequestParam(value
categoryBrandRelationService.getBrandsByCatId(catId);//品牌对象集合在进行筛选赋予品牌对象id和name返回封装的vo给前端ListBrandVo
BrandVo();brandVo.setBrandId(item.getBrandId());brandVo.setBrandName(item.getName());return
brandVo;}).collect(Collectors.toList());return
{//获得CategoryBrandRelationEntity集合对象ListCategoryBrandRelationEntity
QueryWrapperCategoryBrandRelationEntity().eq(catelog_id,
catId));//获得所有集合对象中brandid通过brandService查询所有品牌封装成品牌对象集合ListBrandEntity
brandService.getById(brandId);return
entity;}).collect(Collectors.toList());//返回品牌对象集合return
Controller:处理请求,接受和校验数据Service接受controller传来的数据,进行业务处理Controller接受service处理完的数据,封装页面指定的vo获取分类下所有分组关联属性
也就是说当我们选择手机分类时那就查出手机相关的分组信息并查出每个分组相应属性信息
/product/attrgroup/{catelogId}/withattr*/
GetMapping(/{catelogId}/withattr)
getAttrGroupWithAttrs(PathVariable(catelogId)
attrGroupService.getAttrGroupWithAttrsByCatelogId(catelogId);return
object当相应数据需要自定义时用vo是最好的选择不需要对实体类字段进行修改
getAttrGroupWithAttrsByCatelogId(Long
由于这是mp它会得出所有的这种关系并把结果封装成集合*/ListAttrGroupEntity
QueryWrapperAttrGroupEntity().eq(catelog_id,
要第三张关联表,直接调用关联表的service即查询分组对应的属性id*
以上两步前面已经写好逻辑了直接调用即可attrService.getRelationAttrgroupId*/ListAttrGroupWithAttrsVo
AttrGroupWithAttrsVo();BeanUtils.copyProperties(item,
attrGroupWithAttrsVo);ListAttrEntity
attrService.getRelationAttr(attrGroupWithAttrsVo.getAttrGroupId());if
{attrGroupWithAttrsVo.setAttrs(attrs);}return
attrGroupWithAttrsVo;}).filter((attrvo)
0;}).collect(Collectors.toList());return
在线JSON字符串转Java实体类(JavaBean、Entity)-BeJSON.com
因为所有传来的信息都在vo里所以我们把信息拷贝到对应的实体类中如果vo没有的那就可以自己赋值
这里的infoEntity.setCreateTime(new
Date());infoEntity.setUpdateTime(new
Date());是因为前端传入的是没有这两个字段的我们自己赋值即可
this.saveBaseInfo(infoEntity);保存spu的描述图片
String.join()的作用是把集合中的元素通过,分割形成一个一个的字符串
descEntity.setSpuId(infoEntity.getId());
descEntity.setDecript(String.join(,,
spuInfoDescService.saveSpuInfoDesc(descEntity);保存spu的图片集
imagesService.saveImages(infoEntity.getId(),
ProductAttrValueEntity();valueEntity.setAttrId(attr.getAttrId());AttrEntity
attrService.getById(attr.getAttrId());valueEntity.setAttrName(id.getAttrName());valueEntity.setAttrValue(attr.getAttrValues());valueEntity.setQuickShow(attr.getShowDesc());valueEntity.setSpuId(infoEntity.getId());return
}).collect(Collectors.toList());
attrValueService.saveProductAttr(collect);保存spu的积分信息
BeanUtils.copyProperties(bounds,
spuBoundTo.setSpuId(infoEntity.getId());
couponFeignService.saveSpuBounds(spuBoundTo);
couponFeignService.saveSpuBounds(spuBoundTo);保存当前spu对应的所有sku信息
image.getImgUrl();}}SkuInfoEntity
SkuInfoEntity();BeanUtils.copyProperties(item,
skuInfoEntity);//添加vo中没有的信息skuInfoEntity.setBrandId(infoEntity.getBrandId());skuInfoEntity.setCatalogId(infoEntity.getCatalogId());skuInfoEntity.setSaleCount(0L);skuInfoEntity.setSpuId(infoEntity.getId());skuInfoEntity.setSkuDefaultImg(defalutImg);skuInfoService.saveSkuInfo(skuInfoEntity);//6.2sku图片信息;pms_sku_images//没有图片路径的无需保存Long
skuInfoEntity.getSkuId();ListSkuImagesEntity
item.getImages().stream().map(img
SkuImagesEntity();skuImagesEntity.setSkuId(skuId);skuImagesEntity.setImgUrl(img.getImgUrl());skuImagesEntity.setDefaultImg(img.getDefaultImg());return
skuImagesEntity;}).filter(entity
!StringUtils.isEmpty(entity.getImgUrl());}).collect(Collectors.toList());skuImagesService.saveBatch(imageEntities);//6.3sku的销售属性;pms_sku_sale_attr_valueListAttr
item.getAttr();ListSkuSaleAttrValueEntity
SkuSaleAttrValueEntity();BeanUtils.copyProperties(a,
attrValueEntity);attrValueEntity.setSkuId(skuId);return
attrValueEntity;}).collect(Collectors.toList());skuSaleAttrValueService.saveBatch(skuSaleAttrValueEntities);//6.4sku的优惠满减信息(跨服务);SkuReductionTo
SkuReductionTo();BeanUtils.copyProperties(item,
skuReductionTo);skuReductionTo.setSkuId(skuId);if
skuReductionTo.getFullPrice().compareTo(new
couponFeignService.saveSkuReduction(skuReductionTo);if
{log.error(远程保存spu积分信息异常);}}});
spuInfoService.queryPageByCondition(params);return
queryPageByCondition(MapString,
{queryWrapper.eq(publish_status,
(!StringUtils.isEmpty(catelogId)
!0.equalsIgnoreCase(catelogId))
QuerySpuInfoEntity().getPage(params),queryWrapper);return
skuInfoService.queryPageByParams(params);return
(!StringUtils.isEmpty(catelogId)
!0.equalsIgnoreCase(catelogId))
QuerySkuInfoEntity().getPage(params),queryWrapper);return
加入微服务注册中心加入网关获取仓库列表就是对仓库表的简单查询逆向生成代码以帮我们生成好只要配置好网关就可以直接显示
我们只要记住反是单表操作的逆向生成以帮我们生成好了我们能拿来直接用就像增加仓库、删除、修改都是可以直接用的
QueryWareInfoEntity().getPage(params),queryWrapper);return
}多条件查询都是一样的套路获得你搜索的key然后拿这个key去模糊匹配多个字段
比如这里拿你输入的key会在name、address、areacode做模糊查询条件直接通过or来拼接
查询库存也是单表操作CRUD都帮我们做好了我们就在分页的基础上加上多条件查询即可
QueryWareSkuEntity().getPage(params),queryWrapper);return
{QueryWrapperPurchaseDetailEntity
QueryWrapperPurchaseDetailEntity();String
(String)params.get(key);if(!StringUtils.isEmpty(key)){queryWrapper.and(w-{w.eq(purchase_id,key).or().eq(sku_id,key);});}String
(String)params.get(status);if(!StringUtils.isEmpty(status))
{queryWrapper.eq(status,status);}String
(String)params.get(wareId);if(!StringUtils.isEmpty(wareId))
{queryWrapper.eq(ware_id,wareId);}IPagePurchaseDetailEntity
QueryPurchaseDetailEntity().getPage(params),queryWrapper);return
如果没有选中采购单那么会自动创建采购单进行合并有的话就用采购单idcontroller
purchaseService.mergePurchase(mergeVo);if(flag){return
R.error().put(msg,请选择新建或已分配的采购需求);}
实际上就是创建完采购需求对象和采购单对象后点击合并这两个对象信息会发生变化整体就是做这些操作
具体的看注释这里还用到了一些枚举类的写法通过枚举类获得状态信息了解即可这里就不写了可以去看老师的源码
{//一、获取Vo中的信息//如果指定了采购单那就获取采购单的idLong
mergeVo.getPurchaseId();//获得采购需求的idListLong
mergeVo.getItems();//二、过滤采购需求//对采购需求id进行过滤如果采购需求处于新建或者已分配的收集成新的集合//这样做的目的是为了进行筛选如果你选中正在采购的是不会被合并的ListLong
{//通过采购需求的id获取采购需求实体类PurchaseDetailEntity
purchaseDetailService.getById(i);if
(purchaseDetailEntity.getStatus()
WareConstant.PurchaseDetailStatusEnum.CREATED.getCode()||
purchaseDetailEntity.getStatus()
WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode())
false;}}).collect(Collectors.toList());//三、没有指定采购单逻辑和指定了的逻辑if
PurchaseEntity();//如果是新创建的采购单创建时间更新时间状态都是没有默认值的所以这默认值我们自己来赋值purchaseEntity.setCreateTime(new
Date());purchaseEntity.setUpdateTime(new
Date());//这里设置采购单的状态采用的是枚举类的形式获取purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.CREATED.getCode());this.save(purchaseEntity);//获得自动创建的采购单idpurchaseId
purchaseId;ListPurchaseDetailEntity
{//获取所有的采购需求对象//更新采购需求的状态一共需要该两个点一个是采购状态一个是采购单id。
设置采购需求的id是为了区分是哪一个进行了更改PurchaseDetailEntity
purchaseDetailService.getById(i);purchaseDetailEntity.setPurchaseId(finalPurchaseId);purchaseDetailEntity.setId(i);purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode());return
purchaseDetailEntity;}).collect(Collectors.toList());//批量更改采购需求这里是MP里的接口可直接传入对象MP会自动读取里面的IDpurchaseDetailService.updateBatchById(collect1);//四、优化时间更新为了显示的时间符合我们的样式PurchaseEntity
PurchaseEntity();purchaseEntity.setId(purchaseId);purchaseEntity.setUpdateTime(new
this.updateById(purchaseEntity);}
ids){purchaseService.received(ids);return
采购单状态改为已领取采购需求状态改为正在采购Overridepublic
{//1.确认当前采购单状态ListPurchaseEntity
{//通过采购单id获取采购单对象PurchaseEntity
WareConstant.PurchaseStatusEnum.CREATED.getCode()
WareConstant.PurchaseStatusEnum.ASSIGNED.getCode())
{//对上面收集好的在进行过滤改变采购单状态为已领取RECEIVEitem.setStatus(WareConstant.PurchaseStatusEnum.RECEIVE.getCode());//对上面收集好的在进行过滤改变采购单更新时间item.setUpdateTime(new
item;}).collect(Collectors.toList());//2.批量修改改变采购单状态this.updateBatchById(collect);//3.改变采购需求中的状态if
purchaseDetailService.listDetailByPurchaseId(item.getId());ListPurchaseDetailEntity
PurchaseDetailEntity();purchaseDetailEntity.setId(entity.getId());//将采购需求中的状态改为正在采购purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.BUYING.getCode());return
purchaseDetailEntity;}).collect(Collectors.toList());purchaseDetailService.updateBatchById(detailEntities);});}}完成采购
doneVo){purchaseService.done(doneVo);return
true;//获取采购单id集合ListPurchaseItemDoneVo
doneVo.getItems();//收集结果ListPurchaseDetailEntity
WareConstant.PurchaseDetailStatusEnum.HASERROR.getCode())
false;purchaseDetailEntity.setStatus(item.getStatus());}
{//二、采购需求状态发生变化purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.FINISH.getCode());//由采购单的id获取采购需求对象有什么用呢是用来给增加库存时赋值用的PurchaseDetailEntity
purchaseDetailService.getById(item.getItemId());//三、库存增加wareSkuService.addStock(entity.getSkuId(),
entity.getSkuNum());}//采购完成采购需求中的状态也会发生变化给实体类对象指明id从而修改对象的状态purchaseDetailEntity.setId(item.getItemId());//把要修改的采购需求对象放到集合里updates.add(purchaseDetailEntity);}//因为一个采购单里有多个采购需求合并的所以批量修改采购需求对象purchaseDetailService.updateBatchById(updates);//四.改变采购单状态PurchaseEntity
PurchaseEntity();purchaseEntity.setId(id);purchaseEntity.setStatus(flag
WareConstant.PurchaseStatusEnum.FINISH.getCode()
:WareConstant.PurchaseStatusEnum.HASERROR.getCode());purchaseEntity.setUpdateTime(new
Date());this.updateById(purchaseEntity);}这里id
6是对6号采购单发起操作里面的item9和10是采购单对应的采购需求
{id:16,items:[{itemId:17,status:3,reason:},{itemId:18,status:4,reason:无货}]
怎么显示呢锁定库存就是本表库存表相关的可以直接设置而sku_name是mall-product微服务里才能查询的到的
/product/skuinfo/info/{skuId}给网关发请求
FeignClient(“mall-gateway”)/api/product/skuinfo/info/{skuId}FeignClient(mall-gateway)
{RequestMapping(/api/product/skuinfo/info/{skuId})public
skuId);}增加库存的时候注入FeignService接口即可实现远程调用
{//判断如果没有此库存记录,则为新增操作;如果有则为更改操作ListWareSkuEntity
QueryWrapperWareSkuEntity().eq(sku_id,
WareSkuEntity();wareSkuEntity.setSkuId(skuId);wareSkuEntity.setStock(skuNum);wareSkuEntity.setWareId(wareId);wareSkuEntity.setStockLocked(0);//TODO
远程查询sku的名字//如果查询名字查询失败了事务回滚有点不值得所以用trycatch来捕捉一下try
productFeignService.info(skuId);MapString,Object
0){wareSkuEntity.setSkuName((String)
{e.printStackTrace();}wareSkuDao.insert(wareSkuEntity);}
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback