package com.alatus.mall.product.service.impl;
import com.alatus.common.constant.ProductConstant;
import com.alatus.common.to.SkuReductionTo;
import com.alatus.common.to.SpuBoundTo;
import com.alatus.common.to.es.SkuEsModel;
import com.alatus.common.utils.R;
import com.alatus.mall.product.entity.*;
import com.alatus.mall.product.feign.CouponFeignService;
import com.alatus.mall.product.feign.SearchFeignService;
import com.alatus.mall.product.feign.WareFeignService;
import com.alatus.mall.product.service.*;
import com.alatus.mall.product.vo.*;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.alatus.common.utils.PageUtils;
import com.alatus.common.utils.Query;
import com.alatus.mall.product.dao.SpuInfoDao;
import org.springframework.transaction.annotation.Transactional;
@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {
@Autowired
private SpuInfoDescService spuInfoDescService;
@Autowired
private SpuImagesService imagesService;
@Autowired
private AttrService attrService;
@Autowired
private ProductAttrValueService productAttrValueService;
@Autowired
private SkuInfoService skuInfoService;
@Autowired
private SkuImagesService skuImagesService;
@Autowired
private SkuSaleAttrValueService skuSaleAttrValueService;
@Autowired
private CouponFeignService couponFeignService;
@Autowired
private BrandService brandService;
@Autowired
private CategoryService categoryService;
@Autowired
private WareFeignService wareFeignService;
@Autowired
private SearchFeignService searchFeignService;
@Override
public PageUtils queryPage(Map<String, Object> params) {
QueryWrapper<SpuInfoEntity> wrapper = new QueryWrapper<>();
// 处理 "key" 参数
String key = (String) params.get("key");
if (!StringUtils.isEmpty(key) && !"0".equalsIgnoreCase(key)) {
wrapper.and((w) -> w.eq("id", key).or().like("spu_name", key));
}
// 处理 "status" 参数
String status = (String) params.get("status");
if (!StringUtils.isEmpty(status) && !"0".equalsIgnoreCase(status)) {
wrapper.eq("publish_status", status);
}
// 处理 "brandId" 参数
String brandId = (String) params.get("brandId");
if (!StringUtils.isEmpty(brandId) && !"0".equalsIgnoreCase(brandId)) {
wrapper.eq("brand_id", brandId);
}
// 处理 "catelogId" 参数
String catelogId = (String) params.get("catelogId");
if (!StringUtils.isEmpty(catelogId) && !"0".equalsIgnoreCase(catelogId)) {
wrapper.eq("catalog_id", catelogId);
}
// 执行分页查询
IPage<SpuInfoEntity> page = this.page(
new Query<SpuInfoEntity>().getPage(params),
wrapper
);
return new PageUtils(page);
}
@Override
@Transactional
public void saveSpuInfo(SpuSaveVo spuSaveVo) {
// 保存SPU基本信息
SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
BeanUtils.copyProperties(spuSaveVo,spuInfoEntity);
spuInfoEntity.setCreateTime(new Date());
spuInfoEntity.setUpdateTime(new Date());
this.saveBaseSpuInfo(spuInfoEntity);
// 保存SPU的描述图片
List<String> decript = spuSaveVo.getDecript();
SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
spuInfoDescEntity.setSpuId(spuInfoEntity.getId());
spuInfoDescEntity.setDecript(String.join(",",decript));
spuInfoDescService.save(spuInfoDescEntity);
// 保存spu的图片集
List<String> images = spuSaveVo.getImages();
imagesService.saveImages(spuInfoEntity.getId(),images);
// 保存SPU的描述信息
List<BaseAttrs> baseAttrs = spuSaveVo.getBaseAttrs();
List<ProductAttrValueEntity> productAttrValueEntities = 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(productAttrValueEntities);
// 保存积分信息
Bounds bounds = spuSaveVo.getBounds();
SpuBoundTo spuBoundTo = new SpuBoundTo();
BeanUtils.copyProperties(bounds,spuBoundTo);
spuBoundTo.setSpuId(spuInfoEntity.getId());
R r = couponFeignService.saveSpuBounds(spuBoundTo);
if(r.getCode() != 0){
log.error("远程保存spu积分信息失败");
}
// 保存SPU的规格参数
// 保存当前spu对应的所有sku信息
List<Skus> skus = spuSaveVo.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);
skuInfoEntity.setBrandId(skuInfoEntity.getBrandId());
skuInfoEntity.setCatalogId(skuInfoEntity.getCatalogId());
skuInfoEntity.setSaleCount(0L);
skuInfoEntity.setSpuId(spuInfoEntity.getId());
skuInfoEntity.setSkuDefaultImg(defaultImg);
// sku的基本信息
skuInfoService.saveSkuInfo(skuInfoEntity);
Long skuId = skuInfoEntity.getSkuId();
List<SkuImagesEntity> collect = 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就是有值有图片的
return !StringUtils.isEmpty(entity.getImgUrl());
}).collect(Collectors.toList());
// sku的图片信息
skuImagesService.saveBatch(collect);
// sku的销售属性信息
List<Attr> attrs = item.getAttr();
List<SkuSaleAttrValueEntity> skuSaleAttrValueEntities = attrs.stream().map(attr -> {
SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
BeanUtils.copyProperties(attr, skuSaleAttrValueEntity);
skuSaleAttrValueEntity.setSkuId(skuId);
return skuSaleAttrValueEntity;
}).collect(Collectors.toList());
skuSaleAttrValueService.saveBatch(skuSaleAttrValueEntities);
// sku的优惠满减信息
SkuReductionTo skuReductionTo = new SkuReductionTo();
BeanUtils.copyProperties(item,skuReductionTo);
skuReductionTo.setSkuId(skuId);
if(skuReductionTo.getFullCount() > 0 || skuReductionTo.getFullPrice().compareTo(new BigDecimal("0")) == 1){
R result = couponFeignService.saveSkuReduction(skuReductionTo);
if (result.getCode() != 0){
log.error("远程保存sku优惠信息失败");
}
}
});
}
}
@Override
public void saveBaseSpuInfo(SpuInfoEntity spuInfoEntity) {
this.baseMapper.insert(spuInfoEntity);
}
@Override
public void up(Long spuId) {
// 查出当前spuID所对应的所有sku信息,品牌的名字等
List<SkuInfoEntity> skuInfoEntities = skuInfoService.getSkusBySpuId(spuId);
List<Long> skuIdList = skuInfoEntities.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList());
// TODO 查询当前spu所有可以被检索的规格参数
List<ProductAttrValueEntity> productAttrValueEntities = productAttrValueService.baseAttrListForSpu(spuId);
List<Long> attrIds = productAttrValueEntities.stream().map(productAttrValueEntity -> {
return productAttrValueEntity.getAttrId();
}).collect(Collectors.toList());
// 获取可检索的id集合
List<Long> searchAttrIds = attrService.selectSearchAttrs(attrIds);
Set<Long> idSet = new HashSet<>(searchAttrIds);
// 只取所有规格参数中符合可被检索这一条件,我们用filter拦截掉不符合的那部分
List<SkuEsModel.Attrs> attrs = productAttrValueEntities.stream().filter(productAttrValueEntity -> {
return idSet.contains(productAttrValueEntity.getAttrId());
}).map(item -> {
SkuEsModel.Attrs attr = new SkuEsModel.Attrs();
BeanUtils.copyProperties(item,attr);
return attr;
}).collect(Collectors.toList());
// 封装每个sku的信息
// TODO 去库存系统查库存
Map<Long, Boolean> stockMap = null;
try{
R result = wareFeignService.getSkuHasStock(skuIdList);
if(result.getCode() == 0){
ArrayList<SkuHasStockVo> skuHasStockVos = new ArrayList<>();
ArrayList skuHasStockData = (ArrayList) result.get("data");
for (int i = 0; i < skuHasStockData.size(); i++) {
SkuHasStockVo skuHasStockVo = new SkuHasStockVo();
Map map = (Map) skuHasStockData.get(i);
skuHasStockVo.setHasStock((Boolean) map.get("hasStock"));
skuHasStockVo.setSkuId(Long.parseLong(map.get("skuId").toString()));
skuHasStockVos.add(skuHasStockVo);
}
stockMap = skuHasStockVos.stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, item -> item.getHasStock()));
}
}catch (Exception e){
log.error("库存服务查询异常",e);
}
Map<Long, Boolean> finalStockMap = stockMap;
List<SkuEsModel> skuEsModelList = skuInfoEntities.stream().map(skuInfoEntity -> {
// 组装需要的数据
SkuEsModel skuEsModel = new SkuEsModel();
BeanUtils.copyProperties(skuInfoEntity,skuEsModel);
skuEsModel.setSkuPrice(skuInfoEntity.getPrice());
skuEsModel.setSkuImg(skuInfoEntity.getSkuDefaultImg());
if(finalStockMap == null){
skuEsModel.setHasStock(true);
}else{
skuEsModel.setHasStock(finalStockMap.get(skuInfoEntity.getSkuId()));
}
// TODO 热度评分
skuEsModel.setHotScore(0L);
// TODO 查询品牌和分类的名字信息
BrandEntity brand = brandService.getById(skuEsModel.getBrandId());
skuEsModel.setBrandName(brand.getName());
skuEsModel.setBrandImg(brand.getLogo());
CategoryEntity category = categoryService.getById(skuEsModel.getCatalogId());
skuEsModel.setCatalogName(category.getName());
skuEsModel.setAttrs(attrs);
return skuEsModel;
}).collect(Collectors.toList());
// TODO 发给ES做保存处理,这一步需要让检索服务来操作
System.out.println(skuEsModelList);
R r = searchFeignService.productStatusUp(skuEsModelList);
if(r.getCode() == 0){
//远程调用成功
// TODO 修改当前spu的状态
baseMapper.updateSpuStatus(spuId, ProductConstant.SpuStatusEnum.SPU_UP.getCode());
}
else{
//调用失败
// TODO 重复调用,接口幂等性.重试机制
}
}
}
package com.alatus.mall.product.service.impl;
import com.alatus.common.constant.ProductConstant;
import com.alatus.common.to.SkuReductionTo;
import com.alatus.common.to.SpuBoundTo;
import com.alatus.common.to.es.SkuEsModel;
import com.alatus.common.utils.R;
import com.alatus.mall.product.entity.*;
import com.alatus.mall.product.feign.CouponFeignService;
import com.alatus.mall.product.feign.SearchFeignService;
import com.alatus.mall.product.feign.WareFeignService;
import com.alatus.mall.product.service.*;
import com.alatus.mall.product.vo.*;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.alatus.common.utils.PageUtils;
import com.alatus.common.utils.Query;
import com.alatus.mall.product.dao.SpuInfoDao;
import org.springframework.transaction.annotation.Transactional;
@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {
@Autowired
private SpuInfoDescService spuInfoDescService;
@Autowired
private SpuImagesService imagesService;
@Autowired
private AttrService attrService;
@Autowired
private ProductAttrValueService productAttrValueService;
@Autowired
private SkuInfoService skuInfoService;
@Autowired
private SkuImagesService skuImagesService;
@Autowired
private SkuSaleAttrValueService skuSaleAttrValueService;
@Autowired
private CouponFeignService couponFeignService;
@Autowired
private BrandService brandService;
@Autowired
private CategoryService categoryService;
@Autowired
private WareFeignService wareFeignService;
@Autowired
private SearchFeignService searchFeignService;
@Override
public PageUtils queryPage(Map<String, Object> params) {
QueryWrapper<SpuInfoEntity> wrapper = new QueryWrapper<>();
// 处理 "key" 参数
String key = (String) params.get("key");
if (!StringUtils.isEmpty(key) && !"0".equalsIgnoreCase(key)) {
wrapper.and((w) -> w.eq("id", key).or().like("spu_name", key));
}
// 处理 "status" 参数
String status = (String) params.get("status");
if (!StringUtils.isEmpty(status) && !"0".equalsIgnoreCase(status)) {
wrapper.eq("publish_status", status);
}
// 处理 "brandId" 参数
String brandId = (String) params.get("brandId");
if (!StringUtils.isEmpty(brandId) && !"0".equalsIgnoreCase(brandId)) {
wrapper.eq("brand_id", brandId);
}
// 处理 "catelogId" 参数
String catelogId = (String) params.get("catelogId");
if (!StringUtils.isEmpty(catelogId) && !"0".equalsIgnoreCase(catelogId)) {
wrapper.eq("catalog_id", catelogId);
}
// 执行分页查询
IPage<SpuInfoEntity> page = this.page(
new Query<SpuInfoEntity>().getPage(params),
wrapper
);
return new PageUtils(page);
}
@Override
@Transactional
public void saveSpuInfo(SpuSaveVo spuSaveVo) {
// 保存SPU基本信息
SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
BeanUtils.copyProperties(spuSaveVo,spuInfoEntity);
spuInfoEntity.setCreateTime(new Date());
spuInfoEntity.setUpdateTime(new Date());
this.saveBaseSpuInfo(spuInfoEntity);
// 保存SPU的描述图片
List<String> decript = spuSaveVo.getDecript();
SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
spuInfoDescEntity.setSpuId(spuInfoEntity.getId());
spuInfoDescEntity.setDecript(String.join(",",decript));
spuInfoDescService.save(spuInfoDescEntity);
// 保存spu的图片集
List<String> images = spuSaveVo.getImages();
imagesService.saveImages(spuInfoEntity.getId(),images);
// 保存SPU的描述信息
List<BaseAttrs> baseAttrs = spuSaveVo.getBaseAttrs();
List<ProductAttrValueEntity> productAttrValueEntities = 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(productAttrValueEntities);
// 保存积分信息
Bounds bounds = spuSaveVo.getBounds();
SpuBoundTo spuBoundTo = new SpuBoundTo();
BeanUtils.copyProperties(bounds,spuBoundTo);
spuBoundTo.setSpuId(spuInfoEntity.getId());
R r = couponFeignService.saveSpuBounds(spuBoundTo);
if(r.getCode() != 0){
log.error("远程保存spu积分信息失败");
}
// 保存SPU的规格参数
// 保存当前spu对应的所有sku信息
List<Skus> skus = spuSaveVo.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);
skuInfoEntity.setBrandId(skuInfoEntity.getBrandId());
skuInfoEntity.setCatalogId(skuInfoEntity.getCatalogId());
skuInfoEntity.setSaleCount(0L);
skuInfoEntity.setSpuId(spuInfoEntity.getId());
skuInfoEntity.setSkuDefaultImg(defaultImg);
// sku的基本信息
skuInfoService.saveSkuInfo(skuInfoEntity);
Long skuId = skuInfoEntity.getSkuId();
List<SkuImagesEntity> collect = 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就是有值有图片的
return !StringUtils.isEmpty(entity.getImgUrl());
}).collect(Collectors.toList());
// sku的图片信息
skuImagesService.saveBatch(collect);
// sku的销售属性信息
List<Attr> attrs = item.getAttr();
List<SkuSaleAttrValueEntity> skuSaleAttrValueEntities = attrs.stream().map(attr -> {
SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
BeanUtils.copyProperties(attr, skuSaleAttrValueEntity);
skuSaleAttrValueEntity.setSkuId(skuId);
return skuSaleAttrValueEntity;
}).collect(Collectors.toList());
skuSaleAttrValueService.saveBatch(skuSaleAttrValueEntities);
// sku的优惠满减信息
SkuReductionTo skuReductionTo = new SkuReductionTo();
BeanUtils.copyProperties(item,skuReductionTo);
skuReductionTo.setSkuId(skuId);
if(skuReductionTo.getFullCount() > 0 || skuReductionTo.getFullPrice().compareTo(new BigDecimal("0")) == 1){
R result = couponFeignService.saveSkuReduction(skuReductionTo);
if (result.getCode() != 0){
log.error("远程保存sku优惠信息失败");
}
}
});
}
}
@Override
public void saveBaseSpuInfo(SpuInfoEntity spuInfoEntity) {
this.baseMapper.insert(spuInfoEntity);
}
@Override
public void up(Long spuId) {
// 查出当前spuID所对应的所有sku信息,品牌的名字等
List<SkuInfoEntity> skuInfoEntities = skuInfoService.getSkusBySpuId(spuId);
List<Long> skuIdList = skuInfoEntities.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList());
// TODO 查询当前spu所有可以被检索的规格参数
List<ProductAttrValueEntity> productAttrValueEntities = productAttrValueService.baseAttrListForSpu(spuId);
List<Long> attrIds = productAttrValueEntities.stream().map(productAttrValueEntity -> {
return productAttrValueEntity.getAttrId();
}).collect(Collectors.toList());
// 获取可检索的id集合
List<Long> searchAttrIds = attrService.selectSearchAttrs(attrIds);
Set<Long> idSet = new HashSet<>(searchAttrIds);
// 只取所有规格参数中符合可被检索这一条件,我们用filter拦截掉不符合的那部分
List<SkuEsModel.Attrs> attrs = productAttrValueEntities.stream().filter(productAttrValueEntity -> {
return idSet.contains(productAttrValueEntity.getAttrId());
}).map(item -> {
SkuEsModel.Attrs attr = new SkuEsModel.Attrs();
BeanUtils.copyProperties(item,attr);
return attr;
}).collect(Collectors.toList());
// 封装每个sku的信息
// TODO 去库存系统查库存
Map<Long, Boolean> stockMap = null;
try{
R result = wareFeignService.getSkuHasStock(skuIdList);
if(result.getCode() == 0){
ArrayList<SkuHasStockVo> skuHasStockVos = new ArrayList<>();
ArrayList skuHasStockData = (ArrayList) result.get("data");
for (int i = 0; i < skuHasStockData.size(); i++) {
SkuHasStockVo skuHasStockVo = new SkuHasStockVo();
Map map = (Map) skuHasStockData.get(i);
skuHasStockVo.setHasStock((Boolean) map.get("hasStock"));
skuHasStockVo.setSkuId(Long.parseLong(map.get("skuId").toString()));
skuHasStockVos.add(skuHasStockVo);
}
stockMap = skuHasStockVos.stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, item -> item.getHasStock()));
}
}catch (Exception e){
log.error("库存服务查询异常",e);
}
Map<Long, Boolean> finalStockMap = stockMap;
List<SkuEsModel> skuEsModelList = skuInfoEntities.stream().map(skuInfoEntity -> {
// 组装需要的数据
SkuEsModel skuEsModel = new SkuEsModel();
BeanUtils.copyProperties(skuInfoEntity,skuEsModel);
skuEsModel.setSkuPrice(skuInfoEntity.getPrice());
skuEsModel.setSkuImg(skuInfoEntity.getSkuDefaultImg());
if(finalStockMap == null){
skuEsModel.setHasStock(true);
}else{
skuEsModel.setHasStock(finalStockMap.get(skuInfoEntity.getSkuId()));
}
// TODO 热度评分
skuEsModel.setHotScore(0L);
// TODO 查询品牌和分类的名字信息
BrandEntity brand = brandService.getById(skuEsModel.getBrandId());
skuEsModel.setBrandName(brand.getName());
skuEsModel.setBrandImg(brand.getLogo());
CategoryEntity category = categoryService.getById(skuEsModel.getCatalogId());
skuEsModel.setCatalogName(category.getName());
skuEsModel.setAttrs(attrs);
return skuEsModel;
}).collect(Collectors.toList());
// TODO 发给ES做保存处理,这一步需要让检索服务来操作
System.out.println(skuEsModelList);
R r = searchFeignService.productStatusUp(skuEsModelList);
if(r.getCode() == 0){
//远程调用成功
// TODO 修改当前spu的状态
baseMapper.updateSpuStatus(spuId, ProductConstant.SpuStatusEnum.SPU_UP.getCode());
}
else{
//调用失败
// TODO 重复调用,接口幂等性.重试机制
}
}
}
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
datasource:
username: root
password: root
url: jdbc:mysql://192.168.56.10:3306/Mall-pms
driver-class-name: com.mysql.cj.jdbc.Driver
feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 5000
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto
# 配置全局逻辑删除规则
logic-delete-value: 1
logic-not-delete-value: 0
server:
port: 10000
logging:
level:
com.alatus.mall.product: debug
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
datasource:
username: root
password: root
url: jdbc:mysql://192.168.56.10:3306/Mall-pms
driver-class-name: com.mysql.cj.jdbc.Driver
feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 5000
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto
# 配置全局逻辑删除规则
logic-delete-value: 1
logic-not-delete-value: 0
server:
port: 10000
logging:
level:
com.alatus.mall.product: debug
package com.alatus.search.controller;
import com.alatus.common.exception.BizCodeEnum;
import com.alatus.common.to.es.SkuEsModel;
import com.alatus.common.utils.R;
import com.alatus.search.service.ProductSaveService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.List;
@RequestMapping("/search/save")
@RestController
@Slf4j
public class ElasticSaveController {
@Autowired
private ProductSaveService productSaveService;
// 上架商品
@PostMapping("/product")
public R productStatusUp(@RequestBody List<SkuEsModel> skuEsModelList){
boolean b = false;
try {
b = productSaveService.productStatusUp(skuEsModelList);
} catch (IOException e) {
log.error("商品上架错误",e);
return R.error(BizCodeEnum.PRODUCT_UP_EXCEPTION.getCode(),BizCodeEnum.PRODUCT_UP_EXCEPTION.getMsg());
}
if(b){
return R.ok();
}else{
return R.error();
}
}
}
package com.alatus.search.controller;
import com.alatus.common.exception.BizCodeEnum;
import com.alatus.common.to.es.SkuEsModel;
import com.alatus.common.utils.R;
import com.alatus.search.service.ProductSaveService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.List;
@RequestMapping("/search/save")
@RestController
@Slf4j
public class ElasticSaveController {
@Autowired
private ProductSaveService productSaveService;
// 上架商品
@PostMapping("/product")
public R productStatusUp(@RequestBody List<SkuEsModel> skuEsModelList){
boolean b = false;
try {
b = productSaveService.productStatusUp(skuEsModelList);
} catch (IOException e) {
log.error("商品上架错误",e);
return R.error(BizCodeEnum.PRODUCT_UP_EXCEPTION.getCode(),BizCodeEnum.PRODUCT_UP_EXCEPTION.getMsg());
}
if(b){
return R.ok();
}else{
return R.error();
}
}
}
package com.alatus.search.service.impl;
import com.alatus.common.to.es.SkuEsModel;
import com.alatus.search.config.MallElasticSearchConfig;
import com.alatus.search.constant.EsConstant;
import com.alatus.search.service.ProductSaveService;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@Service
@Slf4j
public class ProductSaveServiceImpl implements ProductSaveService {
@Autowired
private RestHighLevelClient restHighLevelClient;
// Feign的执行流程,构造请求对象,将对象转为json
// buildTemplateFromArgs.create(argv)
// 发送请求执行(执行成功会解码响应数据)
// executeAndDecode
// 带有重试机制
// 外围有一个尝试器,尝试器会在失败后进行尝试
// 尝试器是接口形式的,我们可以自己定制这个实现
// 默认有一个次数,超了抛异常,没超继续走
@Override//保存到ES
public Boolean productStatusUp(List<SkuEsModel> skuEsModelList) throws IOException {
// 给ES中建立索引,product,并建立映射关系
// 给ES保存数据
BulkRequest bulkRequest = new BulkRequest();
for (SkuEsModel skuEsModel : skuEsModelList) {
IndexRequest request = new IndexRequest(EsConstant.PRODUCT_INDEX);
request.id(skuEsModel.getSkuId().toString());
String skuJson = JSON.toJSONString(skuEsModel);
request.source(skuJson, XContentType.JSON);
bulkRequest.add(request);
}
BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, MallElasticSearchConfig.COMMON_OPTIONS);
// TODO 如果发生批量错误
boolean b = bulk.hasFailures();
List<String> collect = Arrays.stream(bulk.getItems()).map(item -> {
return item.getId();
}).collect(Collectors.toList());
log.info("商品上架完成",collect);
return b;
}
}
package com.alatus.search.service.impl;
import com.alatus.common.to.es.SkuEsModel;
import com.alatus.search.config.MallElasticSearchConfig;
import com.alatus.search.constant.EsConstant;
import com.alatus.search.service.ProductSaveService;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@Service
@Slf4j
public class ProductSaveServiceImpl implements ProductSaveService {
@Autowired
private RestHighLevelClient restHighLevelClient;
// Feign的执行流程,构造请求对象,将对象转为json
// buildTemplateFromArgs.create(argv)
// 发送请求执行(执行成功会解码响应数据)
// executeAndDecode
// 带有重试机制
// 外围有一个尝试器,尝试器会在失败后进行尝试
// 尝试器是接口形式的,我们可以自己定制这个实现
// 默认有一个次数,超了抛异常,没超继续走
@Override//保存到ES
public Boolean productStatusUp(List<SkuEsModel> skuEsModelList) throws IOException {
// 给ES中建立索引,product,并建立映射关系
// 给ES保存数据
BulkRequest bulkRequest = new BulkRequest();
for (SkuEsModel skuEsModel : skuEsModelList) {
IndexRequest request = new IndexRequest(EsConstant.PRODUCT_INDEX);
request.id(skuEsModel.getSkuId().toString());
String skuJson = JSON.toJSONString(skuEsModel);
request.source(skuJson, XContentType.JSON);
bulkRequest.add(request);
}
BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, MallElasticSearchConfig.COMMON_OPTIONS);
// TODO 如果发生批量错误
boolean b = bulk.hasFailures();
List<String> collect = Arrays.stream(bulk.getItems()).map(item -> {
return item.getId();
}).collect(Collectors.toList());
log.info("商品上架完成",collect);
return b;
}
}
package com.alatus.mall.ware.controller;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import com.alatus.mall.ware.vo.SkuHasStockVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.alatus.mall.ware.entity.WareSkuEntity;
import com.alatus.mall.ware.service.WareSkuService;
import com.alatus.common.utils.PageUtils;
import com.alatus.common.utils.R;
/**
* 商品库存
*
* @author alatus
* @email 1571345941@qq.com
* @date 2024-03-12 14:08:46
*/
@RestController
@RequestMapping("ware/waresku")
public class WareSkuController {
@Autowired
private WareSkuService wareSkuService;
/**
* 查询SKU是否有库存
*/
@PostMapping("/hasstock")
public R getSkuHasStock(@RequestBody List<Long> skuIds){
List<SkuHasStockVo> skuHasStockVos = wareSkuService.getSkuHasStock(skuIds);
return R.ok().put("data", skuHasStockVos);
}
/**
* 列表
*/
@RequestMapping("/list")
public R list(@RequestParam Map<String, Object> params){
PageUtils page = wareSkuService.queryPage(params);
return R.ok().put("page", page);
}
/**
* 信息
*/
@RequestMapping("/info/{id}")
public R info(@PathVariable("id") Long id){
WareSkuEntity wareSku = wareSkuService.getById(id);
return R.ok().put("wareSku", wareSku);
}
/**
* 保存
*/
@RequestMapping("/save")
public R save(@RequestBody WareSkuEntity wareSku){
wareSkuService.save(wareSku);
return R.ok();
}
/**
* 修改
*/
@RequestMapping("/update")
public R update(@RequestBody WareSkuEntity wareSku){
wareSkuService.updateById(wareSku);
return R.ok();
}
/**
* 删除
*/
@RequestMapping("/delete")
public R delete(@RequestBody Long[] ids){
wareSkuService.removeByIds(Arrays.asList(ids));
return R.ok();
}
}
package com.alatus.mall.ware.controller;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import com.alatus.mall.ware.vo.SkuHasStockVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.alatus.mall.ware.entity.WareSkuEntity;
import com.alatus.mall.ware.service.WareSkuService;
import com.alatus.common.utils.PageUtils;
import com.alatus.common.utils.R;
/**
* 商品库存
*
* @author alatus
* @email 1571345941@qq.com
* @date 2024-03-12 14:08:46
*/
@RestController
@RequestMapping("ware/waresku")
public class WareSkuController {
@Autowired
private WareSkuService wareSkuService;
/**
* 查询SKU是否有库存
*/
@PostMapping("/hasstock")
public R getSkuHasStock(@RequestBody List<Long> skuIds){
List<SkuHasStockVo> skuHasStockVos = wareSkuService.getSkuHasStock(skuIds);
return R.ok().put("data", skuHasStockVos);
}
/**
* 列表
*/
@RequestMapping("/list")
public R list(@RequestParam Map<String, Object> params){
PageUtils page = wareSkuService.queryPage(params);
return R.ok().put("page", page);
}
/**
* 信息
*/
@RequestMapping("/info/{id}")
public R info(@PathVariable("id") Long id){
WareSkuEntity wareSku = wareSkuService.getById(id);
return R.ok().put("wareSku", wareSku);
}
/**
* 保存
*/
@RequestMapping("/save")
public R save(@RequestBody WareSkuEntity wareSku){
wareSkuService.save(wareSku);
return R.ok();
}
/**
* 修改
*/
@RequestMapping("/update")
public R update(@RequestBody WareSkuEntity wareSku){
wareSkuService.updateById(wareSku);
return R.ok();
}
/**
* 删除
*/
@RequestMapping("/delete")
public R delete(@RequestBody Long[] ids){
wareSkuService.removeByIds(Arrays.asList(ids));
return R.ok();
}
}
package com.alatus.common.utils;
import org.apache.http.HttpStatus;
import java.util.HashMap;
import java.util.Map;
/**
* 返回数据
*
*/
public class R extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
public R() {
put("code", 0);
put("msg", "success");
}
public static R error() {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
}
public static R error(String msg) {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
}
public static R error(int code, String msg) {
R r = new R();
r.put("code", code);
r.put("msg", msg);
return r;
}
public static R ok(String msg) {
R r = new R();
r.put("msg", msg);
return r;
}
public static R ok(Map<String, Object> map) {
R r = new R();
r.putAll(map);
return r;
}
public static R ok() {
return new R();
}
public R put(String key, Object value) {
super.put(key, value);
return this;
}
public Integer getCode(){
return Integer.parseInt(this.get("code").toString());
}
}
package com.alatus.common.utils;
import org.apache.http.HttpStatus;
import java.util.HashMap;
import java.util.Map;
/**
* 返回数据
*
*/
public class R extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
public R() {
put("code", 0);
put("msg", "success");
}
public static R error() {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
}
public static R error(String msg) {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
}
public static R error(int code, String msg) {
R r = new R();
r.put("code", code);
r.put("msg", msg);
return r;
}
public static R ok(String msg) {
R r = new R();
r.put("msg", msg);
return r;
}
public static R ok(Map<String, Object> map) {
R r = new R();
r.putAll(map);
return r;
}
public static R ok() {
return new R();
}
public R put(String key, Object value) {
super.put(key, value);
return this;
}
public Integer getCode(){
return Integer.parseInt(this.get("code").toString());
}
}
package com.alatus.mall.product.feign;
import com.alatus.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
@FeignClient("Mall-ware")
public interface WareFeignService {
@PostMapping("/ware/waresku/hasstock")
R getSkuHasStock(@RequestBody List<Long> skuIds);
}
package com.alatus.mall.product.feign;
import com.alatus.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
@FeignClient("Mall-ware")
public interface WareFeignService {
@PostMapping("/ware/waresku/hasstock")
R getSkuHasStock(@RequestBody List<Long> skuIds);
}