2025-01-27 21:47:33 +08:00

204 lines
8.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.upchina.common.service;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Table;
import com.hazelcast.core.HazelcastInstance;
import com.upchina.common.config.cache.CacheKey;
import com.upchina.common.constant.AdvertPosition;
import com.upchina.common.constant.ProductType;
import com.upchina.common.entity.Advert;
import com.upchina.common.handler.BizException;
import com.upchina.common.mapper.AdvertMapper;
import com.upchina.common.query.ListAdvertQuery;
import com.upchina.common.query.OnlyIdQuery;
import com.upchina.common.query.SaveAdvertQuery;
import com.upchina.common.query.UpdateAdvertQuery;
import com.upchina.common.result.Pager;
import com.upchina.common.result.ResponseStatus;
import com.upchina.common.vo.AdvertAppVO;
import com.upchina.common.vo.AdvertVO;
import com.upchina.common.vo.BackendUserVO;
import com.upchina.common.vo.MergeProductInfoVO;
import com.upchina.rbac.entity.UserDept;
import com.upchina.rbac.service.UserService;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class AdvertService {
@Resource
private AdvertMapper advertMapper;
@Resource
private UserService userService;
@Resource
private MergeProductService mergeProductService;
@Resource
private CacheService cacheService;
@Resource
private HazelcastInstance hazelcastInstance;
@Resource
private RecommendService recommendService;
/**
* 推荐位置和对应类型
* 首页投顾社区首页所有类型包括H5
*/
// 推荐位置和产品类型关系
private static final Multimap<Integer, Integer> positionProductTypeMap = HashMultimap.create();
// 产品类型和推荐位置关系
private static final Multimap<Integer, Integer> productTypePositionMap = HashMultimap.create();
private static void putRelation(Integer advertPosition, Collection<Integer> productTypes) {
productTypes.forEach(productType -> {
positionProductTypeMap.put(advertPosition, productType);
productTypePositionMap.put(productType, advertPosition);
});
}
static {
putRelation(AdvertPosition.HOME_PAGE.value, Arrays.stream(ProductType.values()).map(ProductType::getValue).collect(Collectors.toSet()));
}
public Pager<AdvertVO> list(ListAdvertQuery query) {
Integer productType = query.getProductType();
Integer productId = query.getProductId();
String name = query.getName();
Integer position = query.getPosition();
Integer createUserId = query.getCreateUserId();
QueryWrapper<Advert> wrapper = Wrappers.query();
wrapper.eq(productType != null && productType != 0, "product_type", productType)
.eq(productId != null && productId != 0, "product_id", productId)
.like(StrUtil.isNotEmpty(name), "name", name)
.eq(position != null && position != 0, "position", position)
.eq(createUserId != null && createUserId != 0, "create_user_id", createUserId)
.last("order by weight desc,create_time desc");
Page<Advert> page = advertMapper.selectPage(query.toPage(), wrapper);
Map<Integer, UserDept> userMap = userService.getUserMap();
List<AdvertVO> list = page.getRecords().stream().map(advert -> new AdvertVO(advert, userMap.get(advert.getCreateUserId()))).collect(Collectors.toList());
// 填充非H5类型的产品名称
List<AdvertVO> filterH5List = list.stream().filter(vo -> !ProductType.H5.value.equals(vo.getProductType())).collect(Collectors.toList());
Table<Integer, Integer, MergeProductInfoVO> productTable = mergeProductService.queryMergeProductInfo(filterH5List);
filterH5List.forEach(vo -> {
MergeProductInfoVO productVO = productTable.get(vo.getProductType(), vo.getProductId());
if (productVO != null) {
vo.setName(productVO.getProductName());
vo.setSummary(productVO.getSummary());
}
});
return new Pager<>(list, page.getTotal());
}
@Transactional(rollbackFor = Exception.class)
public void save(SaveAdvertQuery query, BackendUserVO backendUserVO) {
validateProduct(query);
ProductType productType = ProductType.fromValue(query.getProductType());
Advert advert = query.toPO(backendUserVO.getUserId());
try {
advertMapper.insert(advert);
} catch (DuplicateKeyException e) {
throw new BizException(ResponseStatus.ADVERT_DUPLICATE);
}
this.clearCache(AdvertPosition.fromValue(query.getPosition()));
}
@Transactional(rollbackFor = Exception.class)
public void update(UpdateAdvertQuery query, BackendUserVO backendUserVO) {
validateProduct(query);
ProductType productType = ProductType.fromValue(query.getProductType());
Advert advert = query.toPO();
int rows;
try {
rows = advertMapper.updateById(advert);
} catch (DuplicateKeyException e) {
throw new BizException(ResponseStatus.ADVERT_DUPLICATE);
}
if (rows == 0) {
throw new BizException(ResponseStatus.ID_NOT_EXIST_ERROR);
}
this.clearCache(AdvertPosition.fromValue(query.getPosition()));
}
@Transactional(rollbackFor = Exception.class)
public void delete(OnlyIdQuery query, BackendUserVO backendUserVO) {
Advert advert = advertMapper.selectById(query.getId());
if (advert == null) {
throw new BizException(ResponseStatus.ID_NOT_EXIST_ERROR);
}
advertMapper.deleteById(query.getId());
this.clearCache(AdvertPosition.fromValue(advert.getPosition()));
ProductType productType = ProductType.fromValue(advert.getProductType());
}
public List<AdvertAppVO> listForApp(Integer position) {
return cacheService.get(CacheKey.ADVERT, CacheKey.AdvertKey.APP_ADVERT_LIST + position, () -> {
QueryWrapper<Advert> wrapper = Wrappers.query();
wrapper.eq("position", position).last("order by weight desc,create_time desc");
List<Advert> list = advertMapper.selectList(wrapper);
return list.stream().map(AdvertAppVO::new).collect(Collectors.toList());
});
}
public void clearCache(AdvertPosition position) {
Map<String, Object> cacheMap = hazelcastInstance.getMap(CacheKey.ADVERT);
cacheMap.remove(CacheKey.AdvertKey.APP_ADVERT_LIST + position.value);
}
public void clearCache(ProductType productType) {
Map<String, Object> cacheMap = hazelcastInstance.getMap(CacheKey.ADVERT);
Collection<Integer> positionSet = productTypePositionMap.get(productType.value);
positionSet.forEach(position -> cacheMap.remove(CacheKey.AdvertKey.APP_ADVERT_LIST + position));
}
private void validateProduct(SaveAdvertQuery query) {
Integer position = query.getPosition();
Integer productType = query.getProductType();
Collection<Integer> productTypeSet = positionProductTypeMap.get(position);
if (!productTypeSet.contains(productType)) {
throw new BizException(ResponseStatus.PARM_ERROR, "产品类型不符合推荐位置要求");
}
if (ProductType.H5.value.equals(productType)) {
if (StrUtil.isEmpty(query.getName())) {
throw new BizException(ResponseStatus.PARM_ERROR, "H5链接名称不能为空");
}
if (StrUtil.hasText(query.getUrl())) {
throw new BizException(ResponseStatus.PARM_ERROR, "H5链接URL不能为空");
}
} else {
if (query.getProductId() == null) {
throw new BizException(ResponseStatus.PARM_ERROR, "非H5类型产品ID不能为空");
}
}
recommendService.validateProduct(query);
}
public void validateRecommendExist(ProductType productType, Integer productId) {
// TODO 校验关联数据(投顾\观点\观点包\锦囊\三方产品\套餐产品)
QueryWrapper<Advert> advertWrapper = Wrappers.query();
advertWrapper.eq("product_type", productType.value)
.eq("product_id", productId);
Long advertCount = advertMapper.selectCount(advertWrapper);
if (advertCount > 0) throw new BizException(ResponseStatus.ADVERT_CAN_NOT_SOLD_OUT);
}
}