improve esGoods parameter selector buckets(not get category and brand from db, add EsGoodsIndex Field BrandName,BrandUrl,CategoryNamePath)

This commit is contained in:
paulGao 2021-09-07 01:55:58 +08:00
parent 8f10b6b2a6
commit 4063c8b063
19 changed files with 650 additions and 195 deletions

View File

@ -1,17 +1,23 @@
package cn.lili.listener;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.event.GoodsCommentCompleteEvent;
import cn.lili.modules.distribution.entity.dos.DistributionGoods;
import cn.lili.modules.distribution.entity.dos.DistributionSelectedGoods;
import cn.lili.modules.distribution.service.DistributionGoodsService;
import cn.lili.modules.distribution.service.DistributionSelectedGoodsService;
import cn.lili.modules.goods.entity.dos.Brand;
import cn.lili.modules.goods.entity.dos.Category;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dto.GoodsCompleteMessage;
import cn.lili.modules.goods.entity.dto.GoodsParamsDTO;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
import cn.lili.modules.goods.service.BrandService;
import cn.lili.modules.goods.service.CategoryService;
import cn.lili.modules.goods.service.GoodsService;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.member.entity.dos.FootPrint;
@ -20,6 +26,8 @@ import cn.lili.modules.member.service.FootprintService;
import cn.lili.modules.member.service.GoodsCollectionService;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.search.service.EsGoodsIndexService;
import cn.lili.modules.store.entity.dos.StoreGoodsLabel;
import cn.lili.modules.store.service.StoreGoodsLabelService;
import cn.lili.modules.store.service.StoreService;
import cn.lili.rocketmq.tags.GoodsTagsEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -31,6 +39,8 @@ import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
@ -89,6 +99,21 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
*/
@Autowired
private DistributionSelectedGoodsService distributionSelectedGoodsService;
/**
* 分类
*/
@Autowired
private CategoryService categoryService;
/**
* 品牌
*/
@Autowired
private BrandService brandService;
/**
* 店铺商品分类
*/
@Autowired
private StoreGoodsLabelService storeGoodsLabelService;
@Override
public void onMessage(MessageExt messageExt) {
@ -101,37 +126,34 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
break;
//生成索引
case GENERATOR_GOODS_INDEX:
String goodsJsonStr = new String(messageExt.getBody());
Goods goods = JSONUtil.toBean(goodsJsonStr, Goods.class);
//如果商品通过审核&&并且已上架
List<GoodsSku> goodsSkuList = this.goodsSkuService.list(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getGoodsId, goods.getId()));
if (goods.getIsAuth().equals(GoodsAuthEnum.PASS.name())
&& goods.getMarketEnable().equals(GoodsStatusEnum.UPPER.name())
&& Boolean.FALSE.equals(goods.getDeleteFlag())) {
for (GoodsSku goodsSku : goodsSkuList) {
EsGoodsIndex esGoodsOld = goodsIndexService.findById(goodsSku.getId());
EsGoodsIndex goodsIndex = new EsGoodsIndex(goodsSku);
if (goods.getParams() != null && !goods.getParams().isEmpty()) {
List<GoodsParamsDTO> goodsParamDTOS = JSONUtil.toList(goods.getParams(), GoodsParamsDTO.class);
goodsIndex = new EsGoodsIndex(goodsSku, goodsParamDTOS);
}
//如果商品库存不为0并且es中有数据
if (goodsSku.getQuantity() > 0 && esGoodsOld == null) {
log.info("生成商品索引 {}", goodsIndex);
this.goodsIndexService.addIndex(goodsIndex);
} else if (goodsSku.getQuantity() > 0 && esGoodsOld != null) {
goodsIndexService.updateIndex(goodsIndex);
}
}
try {
String goodsJsonStr = new String(messageExt.getBody());
Goods goods = JSONUtil.toBean(goodsJsonStr, Goods.class);
updateGoodsIndex(goods);
} catch (Exception e) {
log.error("生成商品索引事件执行异常,商品信息 {}", new String(messageExt.getBody()));
}
//如果商品状态值不支持es搜索那么将商品信息做下架处理
else {
for (GoodsSku goodsSku : goodsSkuList) {
EsGoodsIndex esGoodsOld = goodsIndexService.findById(goodsSku.getId());
if (esGoodsOld != null) {
goodsIndexService.deleteIndexById(goodsSku.getId());
}
break;
case UPDATE_GOODS_INDEX:
try {
String goodsIdsJsonStr = new String(messageExt.getBody());
List<Goods> goodsList = new ArrayList<>();
for (String goodsId : JSONUtil.toList(goodsIdsJsonStr, String.class)) {
Goods goods = goodsService.getById(goodsId);
goodsList.add(goods);
}
this.updateGoodsIndex(goodsList);
} catch (Exception e) {
log.error("更新商品索引事件执行异常,商品信息 {}", new String(messageExt.getBody()));
}
break;
case RESET_GOODS_INDEX:
try {
String goodsIdsJsonStr = new String(messageExt.getBody());
List<EsGoodsIndex> goodsIndices = JSONUtil.toList(goodsIdsJsonStr, EsGoodsIndex.class);
goodsIndexService.updateBulkIndex(goodsIndices);
} catch (Exception e) {
log.error("重置商品索引事件执行异常,商品信息 {}", new String(messageExt.getBody()));
}
break;
//审核商品
@ -177,6 +199,117 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
}
}
/**
* 更新商品索引
*
* @param goodsList 商品列表消息
*/
private void updateGoodsIndex(List<Goods> goodsList) {
List<EsGoodsIndex> goodsIndices = new ArrayList<>();
for (Goods goods : goodsList) {
//如果商品通过审核&&并且已上架
List<GoodsSku> goodsSkuList = this.goodsSkuService.list(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getGoodsId, goods.getId()).gt(GoodsSku::getQuantity, 0));
if (goods.getIsAuth().equals(GoodsAuthEnum.PASS.name())
&& goods.getMarketEnable().equals(GoodsStatusEnum.UPPER.name())
&& Boolean.FALSE.equals(goods.getDeleteFlag())) {
goodsSkuList.forEach(goodsSku -> {
EsGoodsIndex goodsIndex = this.settingUpGoodsIndexData(goods, goodsSku);
goodsIndices.add(goodsIndex);
});
}
//如果商品状态值不支持es搜索那么将商品信息做下架处理
else {
for (GoodsSku goodsSku : goodsSkuList) {
EsGoodsIndex esGoodsOld = goodsIndexService.findById(goodsSku.getId());
if (esGoodsOld != null) {
goodsIndexService.deleteIndexById(goodsSku.getId());
}
}
}
}
goodsIndexService.updateBulkIndex(goodsIndices);
}
/**
* 更新商品索引
*
* @param goods 商品消息
*/
private void updateGoodsIndex(Goods goods) {
//如果商品通过审核&&并且已上架
List<GoodsSku> goodsSkuList = this.goodsSkuService.list(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getGoodsId, goods.getId()));
if (goods.getIsAuth().equals(GoodsAuthEnum.PASS.name())
&& goods.getMarketEnable().equals(GoodsStatusEnum.UPPER.name())
&& Boolean.FALSE.equals(goods.getDeleteFlag())) {
this.generatorGoodsIndex(goods, goodsSkuList);
}
//如果商品状态值不支持es搜索那么将商品信息做下架处理
else {
for (GoodsSku goodsSku : goodsSkuList) {
EsGoodsIndex esGoodsOld = goodsIndexService.findById(goodsSku.getId());
if (esGoodsOld != null) {
goodsIndexService.deleteIndexById(goodsSku.getId());
}
}
}
}
/**
* 生成商品索引
*
* @param goods 商品信息
* @param goodsSkuList 商品sku信息
*/
private void generatorGoodsIndex(Goods goods, List<GoodsSku> goodsSkuList) {
for (GoodsSku goodsSku : goodsSkuList) {
EsGoodsIndex esGoodsOld = goodsIndexService.findById(goodsSku.getId());
EsGoodsIndex goodsIndex = this.settingUpGoodsIndexData(goods, goodsSku);
//如果商品库存不为0并且es中有数据
if (goodsSku.getQuantity() > 0 && esGoodsOld == null) {
log.info("生成商品索引 {}", goodsIndex);
this.goodsIndexService.addIndex(goodsIndex);
} else if (goodsSku.getQuantity() > 0 && esGoodsOld != null) {
goodsIndexService.updateIndex(goodsIndex);
}
}
}
private EsGoodsIndex settingUpGoodsIndexData(Goods goods, GoodsSku goodsSku) {
EsGoodsIndex goodsIndex = new EsGoodsIndex(goodsSku);
if (goods.getParams() != null && !goods.getParams().isEmpty()) {
List<GoodsParamsDTO> goodsParamDTOS = JSONUtil.toList(goods.getParams(), GoodsParamsDTO.class);
goodsIndex = new EsGoodsIndex(goodsSku, goodsParamDTOS);
}
goodsIndex.setIsAuth(goods.getIsAuth());
goodsIndex.setMarketEnable(goods.getMarketEnable());
this.settingUpGoodsIndexOtherParam(goodsIndex);
return goodsIndex;
}
/**
* 设置商品索引的其他参数非商品自带
*
* @param goodsIndex 商品索引信息
*/
private void settingUpGoodsIndexOtherParam(EsGoodsIndex goodsIndex) {
List<Category> categories = categoryService.listByIdsOrderByLevel(Arrays.asList(goodsIndex.getCategoryPath().split(",")));
if (!categories.isEmpty()) {
goodsIndex.setCategoryNamePath(ArrayUtil.join(categories.stream().map(Category::getName).toArray(), ","));
}
Brand brand = brandService.getById(goodsIndex.getBrandId());
if (brand != null) {
goodsIndex.setBrandName(brand.getName());
goodsIndex.setBrandUrl(brand.getLogo());
}
if (goodsIndex.getStoreCategoryPath() != null && CharSequenceUtil.isNotEmpty(goodsIndex.getStoreCategoryPath())) {
List<StoreGoodsLabel> storeGoodsLabels = storeGoodsLabelService.listByStoreIds(Arrays.asList(goodsIndex.getStoreCategoryPath().split(",")));
if (!storeGoodsLabels.isEmpty()) {
goodsIndex.setStoreCategoryNamePath(ArrayUtil.join(storeGoodsLabels.stream().map(StoreGoodsLabel::getLabelName).toArray(), ","));
}
}
}
/**
* 删除商品
* 1.更新店铺的商品数量
@ -203,7 +336,7 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
/**
* 修改商品数量
*
* @param messageExt
* @param messageExt 信息体
*/
private void updateGoodsNum(MessageExt messageExt) {
@ -224,7 +357,7 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
* 2.更新SKU购买数量
* 3.更新索引购买数量
*
* @param messageExt
* @param messageExt 信息体
*/
private void goodsBuyComplete(MessageExt messageExt) {
String goodsCompleteMessageStr = new String(messageExt.getBody());
@ -252,7 +385,7 @@ public class GoodsMessageListener implements RocketMQListener<MessageExt> {
int buyCount = goodsSku.getBuyCount() + goodsCompleteMessage.getBuyNum();
goodsSku.setBuyCount(buyCount);
goodsSkuService.update(goodsSku);
goodsIndexService.updateIndexBuyNum(goodsCompleteMessage.getSkuId(), buyCount);
goodsIndexService.updateIndex(goodsCompleteMessage.getSkuId(), new EsGoodsIndex().setBuyCount(buyCount));
} else {
log.error("商品SkuId为[" + goodsCompleteMessage.getGoodsId() + "的商品不存在,更新商品失败!");
}

View File

@ -7,7 +7,6 @@ import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.Arrays;
import java.util.Collections;
/**
@ -35,7 +34,6 @@ public class SecurityBean {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
// config.addAllowedOrigin(CorsConfiguration.ALL);
config.setAllowedOriginPatterns(Collections.singletonList(CorsConfiguration.ALL));
config.addAllowedHeader(CorsConfiguration.ALL);
config.addAllowedMethod(CorsConfiguration.ALL);

View File

@ -140,6 +140,26 @@ public abstract class BaseElasticsearchService {
" }\n" +
" }\n" +
" },\n" +
" \"brandName\": {\n" +
" \"type\": \"text\",\n" +
" \"fielddata\": true,\n" +
" \"fields\": {\n" +
" \"keyword\": {\n" +
" \"type\": \"keyword\",\n" +
" \"ignore_above\": 256\n" +
" }\n" +
" }\n" +
" },\n" +
" \"brandUrl\": {\n" +
" \"type\": \"text\",\n" +
" \"fielddata\": true,\n" +
" \"fields\": {\n" +
" \"keyword\": {\n" +
" \"type\": \"keyword\",\n" +
" \"ignore_above\": 256\n" +
" }\n" +
" }\n" +
" },\n" +
" \"buyCount\": {\n" +
" \"type\": \"long\"\n" +
" },\n" +
@ -163,6 +183,16 @@ public abstract class BaseElasticsearchService {
" }\n" +
" }\n" +
" },\n" +
" \"categoryNamePath\": {\n" +
" \"type\": \"text\",\n" +
" \"fielddata\": true,\n" +
" \"fields\": {\n" +
" \"keyword\": {\n" +
" \"type\": \"keyword\",\n" +
" \"ignore_above\": 256\n" +
" }\n" +
" }\n" +
" },\n" +
" \"commentNum\": {\n" +
" \"type\": \"long\"\n" +
" },\n" +

View File

@ -25,6 +25,14 @@ public interface CategoryService extends IService<Category> {
*/
List<Category> dbList(String parentId);
/**
* 根据分类id集合获取所有分类根据层级排序
*
* @param ids 分类ID集合
* @return 商品分类列表
*/
List<Category> listByIdsOrderByLevel(List<String> ids);
/**
* 获取分类树
*

View File

@ -11,4 +11,14 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface ParametersService extends IService<Parameters> {
/**
* 更新参数组信息
*
* @param parameters 参数组信息
* @return 是否更新成功
*/
boolean updateParameter(Parameters parameters);
}

View File

@ -1,6 +1,6 @@
package cn.lili.modules.goods.serviceimpl;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.ResultCode;
@ -48,6 +48,17 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
return this.list(new LambdaQueryWrapper<Category>().eq(Category::getParentId, parentId));
}
/**
* 根据分类id集合获取所有分类根据层级排序
*
* @param ids 分类ID集合
* @return 商品分类列表
*/
@Override
public List<Category> listByIdsOrderByLevel(List<String> ids) {
return this.list(new LambdaQueryWrapper<Category>().in(Category::getId, ids).orderByAsc(Category::getLevel));
}
@Override
public List<CategoryVO> categoryTree() {
List<CategoryVO> categoryVOList = (List<CategoryVO>) cache.get(CachePrefix.CATEGORY.getPrefix());
@ -69,13 +80,8 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
categoryVOList.add(categoryVO);
}
}
categoryVOList.sort(new Comparator<CategoryVO>() {
@Override
public int compare(CategoryVO o1, CategoryVO o2) {
return o1.getSortOrder().compareTo(o2.getSortOrder());
}
});
if (categoryVOList.size() != 0) {
categoryVOList.sort(Comparator.comparing(Category::getSortOrder));
if (!categoryVOList.isEmpty()) {
cache.put(CachePrefix.CATEGORY.getPrefix(), categoryVOList);
cache.put(CachePrefix.CATEGORY_ARRAY.getPrefix(), list);
}
@ -85,15 +91,13 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
@Override
public List<CategoryVO> getStoreCategory(String[] categories) {
List<String> arr = Arrays.asList(categories.clone());
List<CategoryVO> categoryVOList = categoryTree().stream()
return categoryTree().stream()
.filter(item -> arr.contains(item.getId())).collect(Collectors.toList());
return categoryVOList;
}
@Override
public List<Category> firstCategory() {
QueryWrapper queryWrapper = Wrappers.query();
QueryWrapper<Category> queryWrapper = Wrappers.query();
queryWrapper.eq("level", 0);
return list(queryWrapper);
}
@ -108,8 +112,9 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
for (CategoryVO item : topCatList) {
if (item.getId().equals(parentId)) {
return item.getChildren();
} else {
return getChildren(parentId, item.getChildren());
}
return getChildren(parentId, item.getChildren());
}
return new ArrayList<>();
}
@ -129,12 +134,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
categoryVOList.add(categoryVO);
}
}
categoryVOList.sort(new Comparator<CategoryVO>() {
@Override
public int compare(CategoryVO o1, CategoryVO o2) {
return o1.getSortOrder().compareTo(o2.getSortOrder());
}
});
categoryVOList.sort(Comparator.comparing(Category::getSortOrder));
return categoryVOList;
}
@ -155,7 +155,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
}
//还为空的话直接返回
if (categoryVOList == null) {
return null;
return new ArrayList<>();
}
//循环顶级分类
for (Category category : categoryVOList) {
@ -174,7 +174,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
public List<Category> findByAllBySortOrder(Category category) {
QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(category.getLevel() != null, "level", category.getLevel())
.eq(StrUtil.isNotBlank(category.getName()), "name", category.getName())
.eq(CharSequenceUtil.isNotBlank(category.getName()), "name", category.getName())
.eq(category.getParentId() != null, "parent_id", category.getParentId())
.ne(category.getId() != null, "id", category.getId())
.eq(DELETE_FLAG_COLUMN, false)
@ -329,7 +329,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
/**
* 递归自身找到id等于parentId的对象获取他的children 返回
*
* @param parentId 父ID
* @param parentId 父ID
* @param categoryVOList 分类VO
* @return 子分类列表VO
*/
@ -338,11 +338,11 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
if (item.getId().equals(parentId)) {
return item.getChildren();
}
if (item.getChildren() != null && item.getChildren().size() > 0) {
if (item.getChildren() != null && !item.getChildren().isEmpty()) {
return getChildren(parentId, categoryVOList);
}
}
return null;
return categoryVOList;
}
/**

View File

@ -117,7 +117,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
}
this.updateStock(newSkuList);
generateEsCheck(goods);
generateEs(goods);
}
@Override
@ -164,7 +164,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
this.updateBatchById(newSkuList);
}
this.updateStock(newSkuList);
generateEsCheck(goods);
generateEs(goods);
}
/**
@ -248,6 +248,10 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
EsGoodsIndex goodsIndex = goodsIndexService.findById(skuId);
if (goodsIndex == null) {
goodsIndex = goodsIndexService.resetEsGoodsIndex(goodsSku, goodsVO.getGoodsParamsDTOList());
//发送mq消息
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.RESET_GOODS_INDEX.name();
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(Collections.singletonList(goodsIndex)), RocketmqSendCallbackBuilder.commonCallback());
}
//商品规格
@ -300,7 +304,7 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
cache.remove(GoodsSkuService.getCacheKeys(sku.getId()));
cache.put(GoodsSkuService.getCacheKeys(sku.getId()), sku);
}
generateEsCheck(goods);
generateEs(goods);
}
}
@ -473,18 +477,18 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
//修改规格
this.update(goodsSku);
//修改规格索引
goodsIndexService.updateIndexCommentNum(goodsSku.getId(), goodsSku.getCommentNum(), highPraiseNum, grade);
goodsIndexService.updateIndex(goodsSku.getId(), new EsGoodsIndex().setCommentNum(goodsSku.getCommentNum()).setHighPraiseNum(highPraiseNum).setGrade(grade));
//修改商品的评价数量
goodsService.updateGoodsCommentNum(goodsSku.getGoodsId());
}
/**
* 生成ES商品索引
* 发送生成ES商品索引
*
* @param goods 商品信息
*/
private void generateEsCheck(Goods goods) {
private void generateEs(Goods goods) {
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.GENERATOR_GOODS_INDEX.name();
//发送mq消息
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(goods), RocketmqSendCallbackBuilder.commonCallback());

View File

@ -1,13 +1,30 @@
package cn.lili.modules.goods.serviceimpl;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.Parameters;
import cn.lili.modules.goods.entity.dto.GoodsParamsDTO;
import cn.lili.modules.goods.entity.dto.GoodsParamsItemDTO;
import cn.lili.modules.goods.mapper.ParametersMapper;
import cn.lili.modules.goods.service.GoodsService;
import cn.lili.modules.goods.service.ParametersService;
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
import cn.lili.rocketmq.tags.GoodsTagsEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 商品参数业务层实现
@ -17,4 +34,92 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Service
public class ParametersServiceImpl extends ServiceImpl<ParametersMapper, Parameters> implements ParametersService {
@Autowired
private GoodsService goodsService;
@Autowired
private RocketmqCustomProperties rocketmqCustomProperties;
@Autowired
private RocketMQTemplate rocketMQTemplate;
/**
* 更新参数组信息
*
* @param parameters 参数组信息
* @return 是否更新成功
*/
@Override
public boolean updateParameter(Parameters parameters) {
Parameters origin = this.getById(parameters.getId());
if (origin == null) {
throw new ServiceException(ResultCode.CATEGORY_NOT_EXIST);
}
List<String> goodsIds = new ArrayList<>();
LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.select(Goods::getId, Goods::getParams);
queryWrapper.like(Goods::getParams, parameters.getGroupId());
List<Map<String, Object>> goodsList = this.goodsService.listMaps(queryWrapper);
for (Map<String, Object> goods : goodsList) {
String params = (String) goods.get("params");
List<GoodsParamsDTO> goodsParamsDTOS = JSONUtil.toList(params, GoodsParamsDTO.class);
List<GoodsParamsDTO> goodsParamsDTOList = goodsParamsDTOS.stream().filter(i -> i.getGroupId() != null && i.getGroupId().equals(parameters.getGroupId())).collect(Collectors.toList());
this.setGoodsItemDTOList(goodsParamsDTOList, parameters);
LambdaUpdateWrapper<Goods> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Goods::getId, goods.get("id"));
updateWrapper.set(Goods::getParams, JSONUtil.toJsonStr(goodsParamsDTOS));
this.goodsService.update(updateWrapper);
goodsIds.add(goods.get("id").toString());
}
String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.UPDATE_GOODS_INDEX.name();
//发送mq消息
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(goodsIds), RocketmqSendCallbackBuilder.commonCallback());
return this.updateById(parameters);
}
/**
* 更新商品参数信息
*
* @param goodsParamsDTOList 商品参数项列表
* @param parameters 参数信息
*/
private void setGoodsItemDTOList(List<GoodsParamsDTO> goodsParamsDTOList, Parameters parameters) {
for (GoodsParamsDTO goodsParamsDTO : goodsParamsDTOList) {
List<GoodsParamsItemDTO> goodsParamsItemDTOList = goodsParamsDTO.getGoodsParamsItemDTOList().stream().filter(i -> i.getParamId() != null && i.getParamId().equals(parameters.getId())).collect(Collectors.toList());
for (GoodsParamsItemDTO goodsParamsItemDTO : goodsParamsItemDTOList) {
this.setGoodsItemDTO(goodsParamsItemDTO, parameters);
}
}
}
/**
* 更新商品参数详细信息
*
* @param goodsParamsItemDTO 商品参数项信息
* @param parameters 参数信息
*/
private void setGoodsItemDTO(GoodsParamsItemDTO goodsParamsItemDTO, Parameters parameters) {
if (goodsParamsItemDTO.getParamId().equals(parameters.getId())) {
goodsParamsItemDTO.setParamId(parameters.getId());
goodsParamsItemDTO.setParamName(parameters.getParamName());
goodsParamsItemDTO.setRequired(parameters.getRequired());
goodsParamsItemDTO.setIsIndex(parameters.getIsIndex());
goodsParamsItemDTO.setSort(parameters.getSort());
if (CharSequenceUtil.isNotEmpty(parameters.getOptions()) && !parameters.getOptions().contains(goodsParamsItemDTO.getParamValue())) {
if (parameters.getOptions().contains(",")) {
goodsParamsItemDTO.setParamValue(parameters.getOptions().substring(0, parameters.getOptions().indexOf(",")));
} else {
goodsParamsItemDTO.setParamValue(parameters.getOptions());
}
}
}
}
}

View File

@ -9,6 +9,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
@ -30,6 +31,7 @@ import java.util.Map;
@Document(indexName = "#{@elasticsearchProperties.indexPrefix}_" + EsSuffix.GOODS_INDEX_NAME)
@ToString
@NoArgsConstructor
@Accessors(chain = true)
public class EsGoodsIndex implements Serializable {
private static final long serialVersionUID = -6856471777036048874L;
@ -99,6 +101,20 @@ public class EsGoodsIndex implements Serializable {
@ApiModelProperty("品牌id")
private String brandId;
/**
* 品牌名称
*/
@Field(type = FieldType.Keyword, fielddata = true)
@ApiModelProperty("品牌名称")
private String brandName;
/**
* 品牌图片地址
*/
@Field(type = FieldType.Keyword, fielddata = true)
@ApiModelProperty("品牌图片地址")
private String brandUrl;
/**
* 分类path
*/
@ -106,6 +122,13 @@ public class EsGoodsIndex implements Serializable {
@ApiModelProperty("分类path")
private String categoryPath;
/**
* 分类名称path
*/
@Field(type = FieldType.Keyword)
@ApiModelProperty("分类名称path")
private String categoryNamePath;
/**
* 店铺分类id
*/
@ -113,6 +136,13 @@ public class EsGoodsIndex implements Serializable {
@ApiModelProperty("店铺分类id")
private String storeCategoryPath;
/**
* 店铺分类名称
*/
@Field(type = FieldType.Keyword)
@ApiModelProperty("店铺分类名称")
private String storeCategoryNamePath;
/**
* 商品价格
*/
@ -279,8 +309,8 @@ public class EsGoodsIndex implements Serializable {
/**
* 参数索引增加
*
* @param sku
* @param goodsParamDTOS
* @param sku 商品sku信息
* @param goodsParamDTOS 商品参数信息
*/
public EsGoodsIndex(GoodsSku sku, List<GoodsParamsDTO> goodsParamDTOS) {
this(sku);

View File

@ -1,10 +1,10 @@
package cn.lili.modules.search.service;
import cn.lili.modules.goods.entity.dto.GoodsParamsDTO;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dto.GoodsParamsDTO;
import cn.lili.modules.promotion.entity.dos.PromotionGoods;
import cn.lili.modules.promotion.entity.dto.BasePromotion;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import java.util.List;
@ -33,22 +33,19 @@ public interface EsGoodsIndexService {
void updateIndex(EsGoodsIndex goods);
/**
* 更新商品索引的购买数量
* 更新商品索引的的部分属性只填写更新的字段不需要更新的字段不要填写
*
* @param id 商品索引id
* @param buyCount 更新后的购买数量
* @param goods 更新后的购买数量
*/
void updateIndexBuyNum(String id, Integer buyCount);
void updateIndex(String id, EsGoodsIndex goods);
/**
* 更新商品索引的评论相关数据
* 批量商品索引的的属性ID 必填, 其他字段只填写更新的字段不需要更新的字段不要填写
*
* @param id 商品索引ID
* @param commentNum 评论数量
* @param highPraiseNum 好评数量
* @param grade 好评率
* @param goodsIndices 商品索引列表
*/
void updateIndexCommentNum(String id, Integer commentNum, Integer highPraiseNum, Double grade);
void updateBulkIndex(List<EsGoodsIndex> goodsIndices);
/**
* 删除索引

View File

@ -2,8 +2,10 @@ package cn.lili.modules.search.serviceimpl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.PromotionTypeEnum;
@ -28,6 +30,8 @@ import cn.lili.modules.search.service.EsGoodsSearchService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.IterableUtil;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.indices.AnalyzeRequest;
import org.elasticsearch.client.indices.AnalyzeResponse;
@ -39,6 +43,7 @@ import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
@ -52,6 +57,10 @@ import java.util.stream.Collectors;
@Service
public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements EsGoodsIndexService {
private static final String IGNORE_FIELD = "serialVersionUID,promotionMap,id,goodsId";
private final Map<String, Field> fieldMap = ReflectUtil.getFieldMap(EsGoodsIndex.class);
@Autowired
private ElasticsearchProperties elasticsearchProperties;
@Autowired
@ -99,34 +108,49 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
}
/**
* 更新商品索引的购买数量
* 更新商品索引的的部分属性只填写更新的字段不需要更新的字段不要填写
*
* @param id 商品索引id
* @param buyCount 更新后的购买数量
* @param id 商品索引id
* @param goods 更新后的购买数量
*/
@Override
public void updateIndexBuyNum(String id, Integer buyCount) {
public void updateIndex(String id, EsGoodsIndex goods) {
EsGoodsIndex goodsIndex = this.findById(id);
goodsIndex.setBuyCount(buyCount);
this.updateIndex(goodsIndex);
// 通过反射获取全部字段在根据参数字段是否为空设置要更新的字段
for (Map.Entry<String, Field> entry : fieldMap.entrySet()) {
Object fieldValue = ReflectUtil.getFieldValue(goods, entry.getValue());
if (fieldValue != null && !IGNORE_FIELD.contains(entry.getKey())) {
ReflectUtil.setFieldValue(goodsIndex, entry.getValue(), fieldValue);
}
}
goodsIndexRepository.save(goods);
}
/**
* 更新商品索引的评论相关数据
* 批量商品索引的的属性ID 必填, 其他字段只填写更新的字段不需要更新的字段不要填写
*
* @param id 商品索引ID
* @param commentNum 评论数量
* @param highPraiseNum 好评数量
* @param grade 好评率
* @param goodsIndices 商品索引列表
*/
@Override
public void updateIndexCommentNum(String id, Integer commentNum, Integer highPraiseNum, Double grade) {
EsGoodsIndex goodsIndex = this.findById(id);
//写入新的商品数据
goodsIndex.setCommentNum(commentNum);
goodsIndex.setHighPraiseNum(highPraiseNum);
goodsIndex.setGrade(grade);
this.updateIndex(goodsIndex);
public void updateBulkIndex(List<EsGoodsIndex> goodsIndices) {
try {
//索引名称拼接
String indexName = elasticsearchProperties.getIndexPrefix() + "_" + EsSuffix.GOODS_INDEX_NAME;
BulkRequest request = new BulkRequest();
for (EsGoodsIndex goodsIndex : goodsIndices) {
UpdateRequest updateRequest = new UpdateRequest(indexName, goodsIndex.getId());
JSONObject jsonObject = JSONUtil.parseObj(goodsIndex);
jsonObject.set("releaseTime", goodsIndex.getReleaseTime().getTime());
updateRequest.doc(jsonObject);
request.add(updateRequest);
}
client.bulk(request, RequestOptions.DEFAULT);
} catch (IOException e) {
log.error("批量更新商品索引异常", e);
}
}
@Override
@ -208,7 +232,7 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
//更新索引
this.updateGoodsIndexPromotion(goodsIndex, key, promotion);
} else {
log.error("更新索引商品促销信息失败skuId 为 【{}】的索引不存在!", id);
log.error("更新索引商品促销信息失败skuId 为 {} 的索引不存在!", id);
}
}
@ -402,7 +426,6 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
Map<String, Object> goodsCurrentPromotionMap = promotionService.getGoodsCurrentPromotionMap(index);
//写入促销信息
index.setPromotionMap(goodsCurrentPromotionMap);
this.addIndex(index);
return index;
}
@ -473,7 +496,7 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
* @param words 商品关键字
*/
private void wordsToDb(String words) {
if (StrUtil.isEmpty(words)) {
if (CharSequenceUtil.isEmpty(words)) {
return;
}
try {
@ -493,16 +516,4 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
}
}
// public List<EsGoodsIndex> searchList(String index) {
// SearchResponse searchResponse = search(index);
// SearchHit[] hits = searchResponse.getHits().getHits();
// List<EsGoodsIndex> goodsIndices = new ArrayList<>();
// Arrays.stream(hits).forEach(hit -> {
// Map<String, Object> sourceAsMap = hit.getSourceAsMap();
// EsGoodsIndex person = BeanUtil.mapToBean(sourceAsMap, EsGoodsIndex.class, false, CopyOptions.create());
// goodsIndices.add(person);
// });
// return goodsIndices;
// }
}

View File

@ -2,22 +2,18 @@ package cn.lili.modules.search.serviceimpl;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.goods.entity.dos.Brand;
import cn.lili.modules.goods.entity.dos.Category;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
import cn.lili.modules.goods.service.BrandService;
import cn.lili.modules.goods.service.CategoryService;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.search.entity.dos.EsGoodsRelatedInfo;
import cn.lili.modules.search.entity.dto.EsGoodsSearchDTO;
import cn.lili.modules.search.entity.dto.HotWordsDTO;
import cn.lili.modules.search.entity.dto.ParamOptions;
import cn.lili.modules.search.entity.dto.SelectorOptions;
import cn.lili.modules.search.repository.EsGoodsIndexRepository;
import cn.lili.modules.search.service.EsGoodsSearchService;
import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.search.join.ScoreMode;
@ -61,21 +57,9 @@ public class EsGoodsSearchServiceImpl implements EsGoodsSearchService {
private static final String ATTR_VALUE = "attrList.value";
private static final String ATTR_NAME = "attrList.name";
private static final String ATTR_SORT = "attrList.sort";
private static final String ATTR_BRAND_ID = "brandId";
private static final String ATTR_NAME_KEY = "nameList";
private static final String ATTR_VALUE_KEY = "valueList";
@Autowired
private EsGoodsIndexRepository goodsIndexRepository;
/**
* 商品分类
*/
@Autowired
private CategoryService categoryService;
/**
* 品牌
*/
@Autowired
private BrandService brandService;
/**
* ES
*/
@ -123,9 +107,14 @@ public class EsGoodsSearchServiceImpl implements EsGoodsSearchService {
public EsGoodsRelatedInfo getSelector(EsGoodsSearchDTO goodsSearch, PageVO pageVo) {
NativeSearchQueryBuilder builder = createSearchQueryBuilder(goodsSearch, null, true);
//分类
builder.addAggregation(AggregationBuilders.terms("categoryAgg").field("categoryPath"));
AggregationBuilder categoryNameBuilder = AggregationBuilders.terms("categoryNameAgg").field("categoryNamePath.keyword");
builder.addAggregation(AggregationBuilders.terms("categoryAgg").field("categoryPath").subAggregation(categoryNameBuilder));
//品牌
builder.addAggregation(AggregationBuilders.terms("brandAgg").field("brandId").size(Integer.MAX_VALUE));
AggregationBuilder brandNameBuilder = AggregationBuilders.terms("brandNameAgg").field("brandName.keyword");
builder.addAggregation(AggregationBuilders.terms("brandIdNameAgg").field(ATTR_BRAND_ID).size(Integer.MAX_VALUE).subAggregation(brandNameBuilder));
AggregationBuilder brandUrlBuilder = AggregationBuilders.terms("brandUrlAgg").field("brandUrl.keyword");
builder.addAggregation(AggregationBuilders.terms("brandIdUrlAgg").field(ATTR_BRAND_ID).size(Integer.MAX_VALUE).subAggregation(brandUrlBuilder));
//参数
AggregationBuilder valuesBuilder = AggregationBuilders.terms("valueAgg").field(ATTR_VALUE);
AggregationBuilder sortBuilder = AggregationBuilders.sum("sortAgg").field(ATTR_SORT);
@ -162,18 +151,22 @@ public class EsGoodsSearchServiceImpl implements EsGoodsSearchService {
if (categoryBuckets != null && !categoryBuckets.isEmpty()) {
for (Terms.Bucket categoryBucket : categoryBuckets) {
String categoryPath = categoryBucket.getKey().toString();
String[] split = categoryPath.split(",");
for (String s : split) {
if (CharSequenceUtil.isNotEmpty(s)) {
Category category = categoryService.getById(s);
if (category != null) {
SelectorOptions so = new SelectorOptions();
so.setName(category.getName());
so.setValue(category.getId());
if (!categoryOptions.contains(so)) {
categoryOptions.add(so);
}
}
ParsedStringTerms categoryNameAgg = categoryBucket.getAggregations().get("categoryNameAgg");
List<? extends Terms.Bucket> categoryNameBuckets = categoryNameAgg.getBuckets();
String categoryNamePath = categoryPath;
if (!categoryBuckets.isEmpty()) {
categoryNamePath = categoryNameBuckets.get(0).getKey().toString();
}
String[] split = ArrayUtil.distinct(categoryPath.split(","));
String[] nameSplit = categoryNamePath.split(",");
for (int i = 0; i < split.length; i++) {
SelectorOptions so = new SelectorOptions();
so.setName(nameSplit[i]);
so.setValue(split[i]);
if (!categoryOptions.contains(so)) {
categoryOptions.add(so);
}
}
@ -182,25 +175,47 @@ public class EsGoodsSearchServiceImpl implements EsGoodsSearchService {
esGoodsRelatedInfo.setCategories(categoryOptions);
//品牌
ParsedStringTerms brandTerms = (ParsedStringTerms) aggregationMap.get("brandAgg");
List<? extends Terms.Bucket> brandBuckets = brandTerms.getBuckets();
ParsedStringTerms brandNameTerms = (ParsedStringTerms) aggregationMap.get("brandIdNameAgg");
ParsedStringTerms brandUrlTerms = (ParsedStringTerms) aggregationMap.get("brandIdUrlAgg");
List<? extends Terms.Bucket> brandBuckets = brandNameTerms.getBuckets();
List<? extends Terms.Bucket> brandUrlBuckets = brandUrlTerms.getBuckets();
List<SelectorOptions> brandOptions = new ArrayList<>();
if (brandBuckets != null && !brandBuckets.isEmpty()) {
for (Terms.Bucket brandBucket : brandBuckets) {
for (int i = 0; i < brandBuckets.size(); i++) {
String brandId = brandBuckets.get(i).getKey().toString();
if (CharSequenceUtil.isNotEmpty(goodsSearch.getBrandId())) {
List<String> brandList = Arrays.asList(goodsSearch.getBrandId().split("@"));
if (brandList.contains(brandBucket.getKey().toString())) {
if (brandList.contains(brandId)) {
continue;
}
}
Brand brand = brandService.getById(brandBucket.getKey().toString());
if (brand != null) {
SelectorOptions so = new SelectorOptions();
so.setName(brand.getName());
so.setValue(brand.getId());
so.setUrl(brand.getLogo());
brandOptions.add(so);
String brandName = "";
if (brandBuckets.get(i).getAggregations() != null && brandBuckets.get(i).getAggregations().get("brandNameAgg") != null) {
ParsedStringTerms brandNameAgg = brandBuckets.get(i).getAggregations().get("brandNameAgg");
List<? extends Terms.Bucket> categoryNameBuckets = brandNameAgg.getBuckets();
if (categoryNameBuckets != null && !categoryNameBuckets.isEmpty()) {
brandName = categoryNameBuckets.get(0).getKey().toString();
}
}
String brandUrl = "";
if (brandUrlBuckets != null && !brandUrlBuckets.isEmpty() &&
brandUrlBuckets.get(i).getAggregations() != null &&
brandUrlBuckets.get(i).getAggregations().get("brandUrlAgg") != null) {
ParsedStringTerms brandUrlAgg = brandUrlBuckets.get(i).getAggregations().get("brandUrlAgg");
List<? extends Terms.Bucket> categoryUrlBuckets = brandUrlAgg.getBuckets();
if (categoryUrlBuckets != null && !categoryUrlBuckets.isEmpty()) {
brandUrl = categoryUrlBuckets.get(0).getKey().toString();
}
}
SelectorOptions so = new SelectorOptions();
so.setName(brandName);
so.setValue(brandId);
so.setUrl(brandUrl);
brandOptions.add(so);
}
}
esGoodsRelatedInfo.setBrands(brandOptions);
@ -339,7 +354,7 @@ public class EsGoodsSearchServiceImpl implements EsGoodsSearchService {
//品牌判定
if (CharSequenceUtil.isNotEmpty(searchDTO.getBrandId())) {
String[] brands = searchDTO.getBrandId().split("@");
filterBuilder.must(QueryBuilders.termsQuery("brandId", brands));
filterBuilder.must(QueryBuilders.termsQuery(ATTR_BRAND_ID, brands));
}
if (searchDTO.getRecommend() != null) {
filterBuilder.filter(QueryBuilders.termQuery("storeId", searchDTO.getRecommend()));

View File

@ -22,6 +22,14 @@ public interface StoreGoodsLabelService extends IService<StoreGoodsLabel> {
*/
List<StoreGoodsLabelVO> listByStoreId(String storeId);
/**
* 根据分类id集合获取所有店铺分类根据层级排序
*
* @param ids 商家ID
* @return 店铺分类列表
*/
List<StoreGoodsLabel> listByStoreIds(List<String> ids);
/**
* 添加商品分类
*

View File

@ -1,7 +1,10 @@
package cn.lili.modules.store.serviceimpl;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.modules.store.entity.dos.StoreGoodsLabel;
@ -61,23 +64,32 @@ public class StoreGoodsLabelServiceImpl extends ServiceImpl<StoreGoodsLabelMappe
});
//调整店铺分类排序
storeGoodsLabelVOList.sort(new Comparator<StoreGoodsLabelVO>() {
@Override
public int compare(StoreGoodsLabelVO o1, StoreGoodsLabelVO o2) {
return o1.getSortOrder().compareTo(o2.getSortOrder());
}
});
storeGoodsLabelVOList.sort(Comparator.comparing(StoreGoodsLabelVO::getSortOrder));
if (storeGoodsLabelVOList.size() != 0) {
if (!storeGoodsLabelVOList.isEmpty()) {
cache.put(CachePrefix.CATEGORY.getPrefix() + storeId + "tree", storeGoodsLabelVOList);
}
return storeGoodsLabelVOList;
}
/**
* 根据分类id集合获取所有店铺分类根据层级排序
*
* @param ids 商家ID
* @return 店铺分类列表
*/
@Override
public List<StoreGoodsLabel> listByStoreIds(List<String> ids) {
return this.list(new LambdaQueryWrapper<StoreGoodsLabel>().in(StoreGoodsLabel::getId, ids).orderByAsc(StoreGoodsLabel::getLevel));
}
@Override
public StoreGoodsLabel addStoreGoodsLabel(StoreGoodsLabel storeGoodsLabel) {
//获取当前登录商家账号
AuthUser tokenUser = UserContext.getCurrentUser();
if (tokenUser == null || CharSequenceUtil.isEmpty(tokenUser.getStoreId())) {
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
}
storeGoodsLabel.setStoreId(tokenUser.getStoreId());
//保存店铺分类
this.save(storeGoodsLabel);
@ -90,6 +102,9 @@ public class StoreGoodsLabelServiceImpl extends ServiceImpl<StoreGoodsLabelMappe
public StoreGoodsLabel editStoreGoodsLabel(StoreGoodsLabel storeGoodsLabel) {
//修改当前店铺的商品分类
AuthUser tokenUser = UserContext.getCurrentUser();
if (tokenUser == null || CharSequenceUtil.isEmpty(tokenUser.getStoreId())) {
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
}
LambdaUpdateWrapper<StoreGoodsLabel> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
lambdaUpdateWrapper.eq(StoreGoodsLabel::getStoreId, tokenUser.getStoreId());
lambdaUpdateWrapper.eq(StoreGoodsLabel::getId, storeGoodsLabel.getId());
@ -103,11 +118,15 @@ public class StoreGoodsLabelServiceImpl extends ServiceImpl<StoreGoodsLabelMappe
@Override
public void removeStoreGoodsLabel(String storeLabelId) {
AuthUser tokenUser = UserContext.getCurrentUser();
if (tokenUser == null || CharSequenceUtil.isEmpty(tokenUser.getStoreId())) {
throw new ServiceException(ResultCode.USER_NOT_LOGIN);
}
//删除店铺分类
this.removeById(storeLabelId);
//清除缓存
removeCache(UserContext.getCurrentUser().getStoreId());
removeCache(tokenUser.getStoreId());
}
/**

View File

@ -10,6 +10,14 @@ public enum GoodsTagsEnum {
* "生成商品索引"
*/
GENERATOR_GOODS_INDEX("生成商品索引"),
/**
* "更新商品索引"
*/
UPDATE_GOODS_INDEX("更新商品索引"),
/**
* "重置商品索引"
*/
RESET_GOODS_INDEX("重置商品索引"),
/**
* "删除商品"
*/

View File

@ -44,7 +44,7 @@ public class ParameterManagerController {
@PutMapping
public ResultMessage<Parameters> update(@Valid Parameters parameters) {
if (parametersService.updateById(parameters)) {
if (parametersService.updateParameter(parameters)) {
return ResultUtil.data(parameters);
}
throw new ServiceException(ResultCode.PARAMETER_UPDATE_ERROR);

View File

@ -1,32 +1,39 @@
package cn.lili.controller.other;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.goods.entity.dos.Brand;
import cn.lili.modules.goods.entity.dos.Category;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dto.GoodsParamsDTO;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
import cn.lili.modules.goods.service.BrandService;
import cn.lili.modules.goods.service.CategoryService;
import cn.lili.modules.goods.service.GoodsService;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.promotion.service.PromotionService;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.search.service.EsGoodsIndexService;
import cn.lili.modules.store.entity.dos.StoreGoodsLabel;
import cn.lili.modules.store.service.StoreGoodsLabelService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.parameters.P;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@ -57,6 +64,15 @@ public class ElasticsearchController {
@Autowired
private PromotionService promotionService;
@Autowired
private CategoryService categoryService;
@Autowired
private BrandService brandService;
@Autowired
private StoreGoodsLabelService storeGoodsLabelService;
@Autowired
private Cache cache;
@ -67,7 +83,6 @@ public class ElasticsearchController {
if (Boolean.TRUE.equals(flag)) {
return ResultUtil.error(100000, "当前有任务在执行");
}
cache.put(CachePrefix.INIT_INDEX_FLAG.getPrefix(), false);
ThreadUtil.execAsync(() -> {
//查询商品信息
LambdaQueryWrapper<GoodsSku> queryWrapper = new LambdaQueryWrapper<>();
@ -84,6 +99,23 @@ public class ElasticsearchController {
List<GoodsParamsDTO> goodsParamDTOS = JSONUtil.toList(goods.getParams(), GoodsParamsDTO.class);
index = new EsGoodsIndex(goodsSku, goodsParamDTOS);
}
if (goods.getCategoryPath() != null) {
List<Category> categories = categoryService.listByIdsOrderByLevel(Arrays.asList(goods.getCategoryPath().split(",")));
if (!categories.isEmpty()) {
index.setCategoryNamePath(ArrayUtil.join(categories.stream().map(Category::getName).toArray(), ","));
}
}
Brand brand = brandService.getById(goods.getBrandId());
if (brand != null) {
index.setBrandName(brand.getName());
index.setBrandUrl(brand.getLogo());
}
if (goods.getStoreCategoryPath() != null && CharSequenceUtil.isNotEmpty(goods.getStoreCategoryPath())) {
List<StoreGoodsLabel> storeGoodsLabels = storeGoodsLabelService.listByStoreIds(Arrays.asList(goods.getStoreCategoryPath().split(",")));
if (!storeGoodsLabels.isEmpty()) {
index.setStoreCategoryNamePath(ArrayUtil.join(storeGoodsLabels.stream().map(StoreGoodsLabel::getLabelName).toArray(), ","));
}
}
Map<String, Object> goodsCurrentPromotionMap = promotionService.getGoodsCurrentPromotionMap(index);
index.setPromotionMap(goodsCurrentPromotionMap);
esGoodsIndices.add(index);

View File

@ -1,5 +1,6 @@
package cn.lili.test.elasticsearch;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.goods.entity.dos.GoodsSku;
@ -20,12 +21,13 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.SearchPage;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@ -56,6 +58,50 @@ class EsTest {
private PromotionService promotionService;
public static void main(String[] args) {
EsGoodsIndex goodsIndex = new EsGoodsIndex();
goodsIndex.setGoodsName("1111");
goodsIndex.setBuyCount(99);
goodsIndex.setCommentNum(99);
goodsIndex.setGrade(100D);
goodsIndex.setHighPraiseNum(100);
goodsIndex.setIntro("I'd like a cup of tea, please");
goodsIndex.setIsAuth("1");
goodsIndex.setMarketEnable("1");
goodsIndex.setMobileIntro("I want something cold to drink");
goodsIndex.setPoint(0);
goodsIndex.setSelfOperated(true);
goodsIndex.setThumbnail("picture");
goodsIndex.setStoreCategoryPath("1");
String ignoreField = "serialVersionUID,promotionMap,id,goodsId";
List<EsGoodsIndex> goodsIndices = new ArrayList<>();
Map<String, Field> fieldMap = ReflectUtil.getFieldMap(EsGoodsIndex.class);
for (int i = 0; i < 10; i++) {
EsGoodsIndex a = new EsGoodsIndex();
for (Map.Entry<String, Field> entry : fieldMap.entrySet()) {
Object fieldValue = ReflectUtil.getFieldValue(goodsIndex, entry.getValue());
if (fieldValue != null && !ignoreField.contains(entry.getKey())) {
ReflectUtil.setFieldValue(a, entry.getValue(), fieldValue);
}
}
goodsIndices.add(a);
}
;
// BeanUtil.copyProperties(goodsIndex, a);
System.out.println(cn.hutool.core.date.DateUtil.endOfDay(new Date()));
// ReflectUtil.getFieldValue(goodsIndex, )
// for (Object o : ReflectUtil.getFieldsValue(goodsIndex)) {
// if (o != null) {
// System.out.println(o);
// }
// }
}
@Test
void searchGoods() {
EsGoodsSearchDTO goodsSearchDTO = new EsGoodsSearchDTO();

View File

@ -35,18 +35,19 @@ class SeckillTest {
@Test
void add() {
SeckillVO seckillVO = new SeckillVO();
seckillVO.setId("123456");
seckillVO.setId("10000");
seckillVO.setStoreIds("132");
seckillVO.setSeckillApplyStatus(SeckillApplyStatusEnum.NOT_APPLY.name());
seckillVO.setPromotionStatus(PromotionStatusEnum.NEW.name());
seckillVO.setApplyEndTime(DateUtil.parse("2020-11-13 23:50:00"));
seckillVO.setStartTime(DateUtil.parse("2020-11-14 12:00:00"));
seckillVO.setEndTime(DateUtil.parse("2020-11-14 18:00:00"));
seckillVO.setHours("13,14,15,16,17");
seckillVO.setApplyEndTime(DateUtil.parse("2021-09-06 14:20:00"));
seckillVO.setStartTime(DateUtil.parse("2021-09-06 14:22:00"));
seckillVO.setEndTime(DateUtil.parse("2021-09-06 23:59:00"));
seckillVO.setHours("15,17,19");
seckillVO.setPromotionName("Seckill" + seckillVO.getId());
seckillVO.setSeckillRule("rule" + seckillVO.getId());
seckillVO.setStoreId("0");
seckillVO.setStoreId("1376433565247471616");
seckillVO.setStoreName("platform");
Assertions.assertTrue(seckillService.saveSeckill(seckillVO));
}
@ -54,32 +55,32 @@ class SeckillTest {
void addApply() {
List<SeckillApplyVO> seckillApplyVOS = new ArrayList<>();
SeckillApplyVO seckillApplyVO = new SeckillApplyVO();
seckillApplyVO.setGoodsName("Apple MacBook Pro 13.3 新款八核M1芯片 8G 256G SSD 深空灰 笔记本电脑 轻薄本 MYD82CH/A");
seckillApplyVO.setSkuId("50111");
seckillApplyVO.setOriginalPrice(20000D);
seckillApplyVO.setPrice(19000D);
seckillApplyVO.setGoodsName("Apple iPhone 12");
seckillApplyVO.setSkuId("1387977574860193792");
seckillApplyVO.setOriginalPrice(4000D);
seckillApplyVO.setPrice(3600D);
seckillApplyVO.setPromotionApplyStatus(PromotionApplyStatusEnum.APPLY.name());
seckillApplyVO.setQuantity(100);
seckillApplyVO.setQuantity(1);
seckillApplyVO.setSalesNum(0);
seckillApplyVO.setSeckillId("123456");
seckillApplyVO.setStoreId("501");
seckillApplyVO.setStoreName("Apple产品自营旗舰");
seckillApplyVO.setTimeLine(17);
seckillApplyVO.setSeckillId("10000");
seckillApplyVO.setStoreId("1376369067769724928");
seckillApplyVO.setStoreName("Lilishop自营");
seckillApplyVO.setTimeLine(15);
seckillApplyVOS.add(seckillApplyVO);
seckillApplyVO = new SeckillApplyVO();
seckillApplyVO.setGoodsName("RedmiBook 16 锐龙版 超轻薄全面屏(6核R5-4500U 16G 512G 100% sRGB高色域)灰 手提 笔记本电脑 小米 红米");
seckillApplyVO.setSkuId("141");
seckillApplyVO.setOriginalPrice(10000D);
seckillApplyVO.setPrice(9000D);
seckillApplyVO.setGoodsName("Apple iPhone 12");
seckillApplyVO.setSkuId("1387977574864388096");
seckillApplyVO.setOriginalPrice(4000D);
seckillApplyVO.setPrice(3600D);
seckillApplyVO.setPromotionApplyStatus(PromotionApplyStatusEnum.APPLY.name());
seckillApplyVO.setQuantity(100);
seckillApplyVO.setQuantity(1);
seckillApplyVO.setSalesNum(0);
seckillApplyVO.setSeckillId("123456");
seckillApplyVO.setStoreId("131");
seckillApplyVO.setStoreName("小米自营旗舰");
seckillApplyVO.setTimeLine(16);
seckillApplyVO.setSeckillId("10000");
seckillApplyVO.setStoreId("1376369067769724928");
seckillApplyVO.setStoreName("Lilishop自营");
seckillApplyVO.setTimeLine(15);
seckillApplyVOS.add(seckillApplyVO);
seckillApplyService.addSeckillApply("123456", "501", seckillApplyVOS);
seckillApplyService.addSeckillApply("10000", "1376369067769724928", seckillApplyVOS);
Assertions.assertTrue(true);
}