You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

368 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 商品服务
## 1.新增商品
### 1.1 品牌的关联
#### 1.1.1 PubSub依赖缺失
打开新增商品页面的时候会出现的错误提示:
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/b1b4a6b9a7624e849280d6828ed4f9a1.png)
原因是缺少PubSub相关依赖
解决办法
* 使用npm添加依赖npm install --save pubsub-js失败的话使用此命令cnpm install --save pubsub-js
* 在src下的main.js中引用
import PubSub from 'pubsub-js'
Vue.prototype.PubSub = PubSub![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/af8c6d863ec5448dbd4e564ccc6dd9dd.png)
* 在.eslintrc.js中添加一下配置
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/0e7110b3ace442beb044dd53ce811d9e.png)
#### 1.1.2 品牌关联
拷贝对应的前端页面文件
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/5e4dda5ba51943e3b1e8fa969511af85.png)
添加后端对应的服务
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/b1e7a45389ef4957a99e79433a45847c.png)
然后service中查询处理
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/d758f664510c4149b5f801a7b4a2d330.png)
最后的显示效果
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/5b390464bebb46ba89a51033cd58dbd8.png)
#### 1.1.3 会员等级
  首先我们需要启动会员模块,并且配置对应的网关路由信息
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/5fdec2527ef1499ca8215f99d6121cb5.png)
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/7f823adb394b48199bdd6254dedfa765.png)
#### 1.1.4 规格参数
  在新增商品的第二步我们就需要设置对应的规格参数,而这些规格参数是根据前面一步选择的三级分类来查询出来的。
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/7d77b5be10e54253bacdbe8d009ae7a9.png)
  响应对应的数据我们需要先创建对应的VO对象。
```java
package com.msb.mall.product.vo;
import com.baomidou.mybatisplus.annotation.TableId;
import com.msb.mall.product.entity.AttrEntity;
import lombok.Data;
import java.util.List;
@Data
public class AttrGroupWithAttrsVo {
/**
* 分组id
*/
@TableId
private Long attrGroupId;
/**
* 组名
*/
private String attrGroupName;
/**
* 排序
*/
private Integer sort;
/**
* 描述
*/
private String descript;
/**
* 组图标
*/
private String icon;
/**
* 所属分类id
*/
private Long catelogId;
// 关联对应的属性信息
private List<AttrEntity> attrs;
}
```
&emsp;&emsp;然后创建对应的controller
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/a7078b97cb0544c5ba05408de08c6a3e.png)
&emsp;&emsp;然后创建对应的service
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/912bae3485214766b660912fdaa357b6.png)
### 1.2 发布商品
#### 1.2.1 VO 接收数据
&emsp;&emsp;前端页面提交的JSON数据非常复杂我们需要在后端服务通过对应的VO对象来接收这些相关的数据。
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/1b4838b74d2d49a0af05e47fa0275b00.png)
然后通过在线的json格式处理工具生成对应的VO工具类
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/7712c743b6de438db49f84571b20272f.png)
#### 1.2.2 保存对应的数据
&emsp;&emsp;需要保存的数据拆解为一下六个部分。
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/25915127d4964ad587fc50dab643a71f.png)
#### 1.2.3 保存商品基本信息
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/1490f95f6356461f9a151b0387b66b79.png)
#### 1.2.4 保存商品描述
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/0c0c13e1dc694bb7b668c85e8687b2f3.png)
需要注意的地方:
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/6d55a77633d942608a8c459c717f27ab.png)
#### 1.2.4 保存图集信息
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/84b916fc4fd34b1aa5e3cb4f96836cc8.png)
#### 1.2.5 保存规格参数
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/fd340ae1bcb44af59bc88b35e2dc03b5.png)
#### 1.2.6 SKU基本信息存储
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/d1ad9f46ad974fcfb160e5e8b30f359b.png)
#### 1.2.7 SKU的图集
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/ba052a777a8541c28c0e98ea4e650b82.png)
#### 1.2.8 SKU的销售属性
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/fa003c96fe4c4632ba5ca6b95c3b3426.png)
### 1.3 远程服务调用
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/656b476ec82841438e38a72ee644711e.png)
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/84ddf4367c2d4abe92ee60aa92a3a862.png)
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/ce1a0bc63e914fe3a1600af93b03ccf5.png)
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/0acf26569cb84342bdf5cb7d7a7e75b9.png)
#### 1.3.1 满减,折扣,会员价保存
在coupon服务中定义相关的接口及处理的service
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/322260877ab446ceaaa2b742881ee0c5.png)
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/47a6923ff4464172aaadb54d17b51698.png)
然后我们在Product服务中来处理接口的调用
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/e062594520f94b3db2855d5818b75450.png)
然后在商品的service中完成服务的调用
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/0bed55cbbbbf4f8fb07d9406d63aed00.png)
完成满减折扣和会员价的service存储
```java
public void saveSkuReduction(SkuReductionDTO dto) {
// 5.3 保存满减信息,折扣,会员价
// mall_sms: sms_sku_ladder sms_full_reduction sms_member_price
// 1.折扣
SkuLadderEntity ladderEntity = new SkuLadderEntity();
ladderEntity.setSkuId(dto.getSkuId());
ladderEntity.setFullCount(dto.getFullCount());
ladderEntity.setDiscount(dto.getDiscount());
ladderEntity.setAddOther(dto.getCountStatus());
if(ladderEntity.getFullCount() > 0){
ladderService.save(ladderEntity);
}
// 2.满减
SkuFullReductionEntity fullReductionEntity = new SkuFullReductionEntity();
BeanUtils.copyProperties(dto,fullReductionEntity);
if(fullReductionEntity.getFullPrice().compareTo(new BigDecimal(0)) == 1){
this.save(fullReductionEntity);
}
// 3.会员价
List<MemberPriceEntity> memberPriceEntities = dto.getMemberPrice().stream().map(item -> {
MemberPriceEntity priceEntity = new MemberPriceEntity();
priceEntity.setSkuId(dto.getSkuId());
priceEntity.setMemberLevelId(item.getId());
priceEntity.setMemberPrice(item.getPrice());
priceEntity.setAddOther(1); // 是否可叠加
return priceEntity;
}).collect(Collectors.toList());
memberPriceService.saveBatch(memberPriceEntities);
}
```
#### 1.3.2 会员积分存储
会员积分信息也是存储在Coupon服务中我们同样需要通过Fegin来调用。
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/530b79035bb74453a9cec99f279f3152.png)
## 2.SPU管理
&emsp;&emsp;提供不同条件的检索,分类,品牌,状态,关键字检索。
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/ab5431c1b87a42f5a101c95692d1f37e.png)
&emsp;&emsp;后台我们需要在Service中完成对应的操作。
```java
/**
* SPU信息检索
* 分页查询
* 分类 品牌 状态 关键字查询
* @param params
* @return
*/
@Override
public PageUtils queryPageByCondition(Map<String, Object> params) {
QueryWrapper<SpuInfoEntity> wrapper = new QueryWrapper<>();
// 设置对应的检索条件
// 1. 关键字查询
String key = (String) params.get("key");
if(!StringUtils.isEmpty(key)){
// 需要添加关键字查询
wrapper.and((w)->{
w.eq("id",key)
.or().like("spu_name",key)
.or().like("spu_description",key);
});
}
// status
String status = (String) params.get("status");
if(!StringUtils.isEmpty(status)){
wrapper.eq("publish_status",status);
}
// catalogId
String catalogId = (String) params.get("catalogId");
if(!StringUtils.isEmpty(catalogId) && !"0".equalsIgnoreCase(catalogId)){
wrapper.eq("catalog_id",catalogId);
}
// brandId
String brandId = (String) params.get("brandId");
if(!StringUtils.isEmpty(brandId) && !"0".equalsIgnoreCase(brandId)){
wrapper.eq("brand_id",brandId);
}
IPage<SpuInfoEntity> page = this.page(
new Query<SpuInfoEntity>().getPage(params),
wrapper
);
return new PageUtils(page);
}
```
&emsp;&emsp;然后解决页面显示数据的问题,比如类别和品牌显示的编号,创建时间和更新时间显示格式问题。
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/a949bc1846e94773bb167cfb165f81da.png)
重启服务
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/f2380f63f30741039528bbcd6b6f56db.png)
上面的是设置全局的格式化方式如果我也特殊设置这时我们可以在对应的entity对象的属性上通过@JsonFormat 来指定,此处指定的会覆盖掉全局的设置。
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/50a4c0fa699941f2bed16c0485464a92.png)
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/b41d0c1e59f04fdda0a0a62780e93c10.png)
针对显示的分类和品牌显示id的问题我们需要通过对应的vo对象来传输同时我们需要在service中完成对应的逻辑
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/8f2a4b71785d41dc945b1d90532ad9b6.png)
显示的效果
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/5d798daf16ab4ae5b951be8abf4e9962.png)
## 3.商品管理
&emsp;&emsp;商品管理也就是我们讲的SKU管理。实现多条件的检索比如 类别,品牌,价格区间。关键字等查询。
```java
/**
* SKU 信息检索的方法
* 类别
* 品牌
* 价格区间
* 检索的关键字
* 分页查询
*
* @param params
* @return
*/
@Override
public PageUtils queryPageByCondition(Map<String, Object> params) {
QueryWrapper<SkuInfoEntity> wrapper = new QueryWrapper<>();
// 检索关键字
String key = (String) params.get("key");
if(!StringUtils.isEmpty(key)){
wrapper.and(w->{
w.eq("sku_id",key).or().like("sku_name",key);
});
}
// 分类
String catalogId = (String)params.get("catalogId");
if(!StringUtils.isEmpty(catalogId) && !"0".equalsIgnoreCase(catalogId)){
wrapper.eq("catalog_id",catalogId);
}
// 品牌
String brandId = (String)params.get("brandId");
if(!StringUtils.isEmpty(brandId) && !"0".equalsIgnoreCase(brandId)){
wrapper.eq("brand_id",brandId);
}
// 价格区间
String min = (String) params.get("min");
if(!StringUtils.isEmpty(min)){
wrapper.ge("price",min);
}
String max = (String) params.get("max");
if(!StringUtils.isEmpty(max)){
try {
// 如果max=0那么我们也不需要加这个条件
BigDecimal bigDecimal = new BigDecimal(max);
if(bigDecimal.compareTo(new BigDecimal(0)) == 1){
// 说明 max > 0
wrapper.le("price",max);
}
}catch (Exception e){
e.printStackTrace();
}
}
IPage<SkuInfoEntity> page = this.page(
new Query<SkuInfoEntity>().getPage(params),
wrapper
);
return new PageUtils(page);
}
```
![image.png](https://fynotefile.oss-cn-zhangjiakou.aliyuncs.com/fynote/1462/1641455939000/36ef14929a21484bb5937bc6fbcb88c7.png)