204 lines
8.9 KiB
Java
204 lines
8.9 KiB
Java
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);
|
||
}
|
||
|
||
}
|