|
|
@ -20,8 +20,13 @@ package com.epmet.redis; |
|
|
|
import com.epmet.commons.tools.constant.NumConstant; |
|
|
|
import com.epmet.commons.tools.redis.RedisUtils; |
|
|
|
import com.epmet.constant.GovIssueRedisKeys; |
|
|
|
import com.epmet.dao.IssueProjectCategoryDictDao; |
|
|
|
import com.epmet.dao.IssueProjectTagDictDao; |
|
|
|
import com.epmet.dto.result.IssueCategoryTagResultDTO; |
|
|
|
import com.epmet.entity.IssueProjectCategoryDictEntity; |
|
|
|
import com.epmet.entity.IssueProjectTagDictEntity; |
|
|
|
import com.epmet.utils.ModuleConstants; |
|
|
|
import com.fasterxml.jackson.databind.Module; |
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.apache.commons.lang.StringUtils; |
|
|
@ -51,6 +56,10 @@ public class IssueProjectTagDictRedis { |
|
|
|
private RedisUtils redisUtils; |
|
|
|
@Autowired |
|
|
|
private RedisTemplate redisTemplate; |
|
|
|
@Autowired |
|
|
|
private IssueProjectTagDictDao poolDao; |
|
|
|
@Autowired |
|
|
|
private IssueProjectCategoryDictDao categoryDictDao; |
|
|
|
public void delete(Object[] ids) { |
|
|
|
|
|
|
|
} |
|
|
@ -74,66 +83,103 @@ public class IssueProjectTagDictRedis { |
|
|
|
* @author wangc |
|
|
|
* @date 2020.12.09 11:16 |
|
|
|
*/ |
|
|
|
public List<IssueCategoryTagResultDTO> getTagsOrderByRank(String customerId,List<String> category){ |
|
|
|
if(StringUtils.isBlank(customerId)) { |
|
|
|
public Map<String,List<IssueCategoryTagResultDTO>> getTagsOrderByRank(String customerId,List<String> category) { |
|
|
|
if (StringUtils.isBlank(customerId)) { |
|
|
|
log.error("customerId can not be null when obtain govern tags."); |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
IssueProjectCategoryDictEntity otherCategory = categoryDictDao.selectSingleByCustomerIdAndCategoryNameAndCategoryType(customerId, ModuleConstants.CATEGORY_NAME_OTHERS, null); |
|
|
|
boolean ifOther = null == otherCategory ? false : (!CollectionUtils.isEmpty(category) && category.size() == NumConstant.ONE && category.contains(otherCategory.getId()) ? true : false); |
|
|
|
Set<String> keys; |
|
|
|
if(CollectionUtils.isEmpty(category)) |
|
|
|
keys = redisUtils.keys(GovIssueRedisKeys.getGovernmentTagKey(customerId,null)); |
|
|
|
else keys = category.stream().map(key -> {return GovIssueRedisKeys.getGovernmentTagKey(customerId,key);}).collect(Collectors.toSet()); |
|
|
|
|
|
|
|
List<Set<ZSetOperations.TypedTuple<Object>>> heatTuple = redisTemplate.executePipelined(new RedisCallback<Set<ZSetOperations.TypedTuple<Object>>>() { |
|
|
|
@Nullable |
|
|
|
@Override |
|
|
|
public Set<ZSetOperations.TypedTuple<Object>> doInRedis(RedisConnection connection) throws DataAccessException { |
|
|
|
connection.openPipeline(); |
|
|
|
keys.forEach(key -> { |
|
|
|
connection.zSetCommands().zRangeByScoreWithScores(redisTemplate.getKeySerializer().serialize(key), NumConstant.ZERO_L, (long) (NumConstant.ONE_NEG)); |
|
|
|
if (CollectionUtils.isEmpty(category) || ifOther) |
|
|
|
keys = redisUtils.keys(GovIssueRedisKeys.getGovernmentTagKey(customerId, null)); |
|
|
|
else keys = category.stream().map(key -> { |
|
|
|
return GovIssueRedisKeys.getGovernmentTagKey(customerId, key); |
|
|
|
}).collect(Collectors.toSet()); |
|
|
|
//如果keys集合为空,说明缓存中没有当前客户的标签排行信息,直接进行补偿
|
|
|
|
if (!CollectionUtils.isEmpty(keys)){ |
|
|
|
keys.remove(GovIssueRedisKeys.getGovernmentTagKey(customerId,ModuleConstants.CUSTOMIZED_TAG_CATEGORY_NAME)); |
|
|
|
List<Set<ZSetOperations.TypedTuple<Object>>> heatTuple = redisTemplate.executePipelined(new RedisCallback<Set<ZSetOperations.TypedTuple<Object>>>() { |
|
|
|
@Nullable |
|
|
|
@Override |
|
|
|
public Set<ZSetOperations.TypedTuple<Object>> doInRedis(RedisConnection connection) throws DataAccessException { |
|
|
|
connection.openPipeline(); |
|
|
|
keys.forEach(key -> { |
|
|
|
connection.zSetCommands().zRangeByScoreWithScores(redisTemplate.getKeySerializer().serialize(key), NumConstant.ZERO_L, (long) (NumConstant.ONE_NEG)); |
|
|
|
}); |
|
|
|
return null; |
|
|
|
} |
|
|
|
}, redisTemplate.getValueSerializer()); |
|
|
|
//热度Map 分数为key
|
|
|
|
Map<Double, List<IssueCategoryTagResultDTO>> heatMap = new HashMap<>(); |
|
|
|
if (!CollectionUtils.isEmpty(heatTuple)) { |
|
|
|
heatTuple.forEach(tupleSet -> { |
|
|
|
tupleSet.forEach(tuple -> { |
|
|
|
Double heatScore = tuple.getScore(); |
|
|
|
List<IssueCategoryTagResultDTO> queue = heatMap.get(heatScore); |
|
|
|
if (CollectionUtils.isEmpty(queue)) queue = new LinkedList<>(); |
|
|
|
queue.add(parseObject(tuple.getValue(), IssueCategoryTagResultDTO.class)); |
|
|
|
heatMap.put(heatScore,queue); |
|
|
|
}); |
|
|
|
}); |
|
|
|
return null; |
|
|
|
List<IssueCategoryTagResultDTO> defaultResult = new LinkedList<>(); |
|
|
|
heatMap.keySet().stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).forEach(count -> { |
|
|
|
defaultResult.addAll(heatMap.get(count)); |
|
|
|
}); |
|
|
|
Map<String,List<IssueCategoryTagResultDTO>> result = new HashMap<>(); |
|
|
|
result.put(ModuleConstants.DEFAULT_TAG_CATEGORY_NAME,defaultResult); |
|
|
|
Set<ZSetOperations.TypedTuple<Object>> customizedTuples = redisUtils.zReverseRangeWithScores(GovIssueRedisKeys.getGovernmentTagKey(customerId, null), NumConstant.ZERO_L, (long) (NumConstant.ONE_NEG)); |
|
|
|
if(!CollectionUtils.isEmpty(customizedTuples)){ |
|
|
|
Map<Double, List<IssueCategoryTagResultDTO>> customizedHeatMap = new HashMap<>(); |
|
|
|
customizedTuples.forEach(tuple -> { |
|
|
|
List<IssueCategoryTagResultDTO> queue = customizedHeatMap.get(tuple.getValue()); |
|
|
|
if((CollectionUtils.isEmpty(queue))) queue = new LinkedList<>(); |
|
|
|
queue.add(parseObject(tuple.getValue(), IssueCategoryTagResultDTO.class)); |
|
|
|
heatMap.put((Double) tuple.getValue(),queue); |
|
|
|
}); |
|
|
|
List<IssueCategoryTagResultDTO> customizedResult = new LinkedList<>(); |
|
|
|
customizedHeatMap.keySet().stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).forEach(count -> { |
|
|
|
customizedResult.addAll(customizedHeatMap.get(count)); |
|
|
|
}); |
|
|
|
result.put(ModuleConstants.CUSTOMIZED_TAG_CATEGORY_NAME,customizedResult); |
|
|
|
} |
|
|
|
return result; |
|
|
|
|
|
|
|
} |
|
|
|
},redisTemplate.getValueSerializer()); |
|
|
|
//热度Map 分数为key
|
|
|
|
Map<Double,List<IssueCategoryTagResultDTO>> heatMap = new HashMap<>(); |
|
|
|
if(!CollectionUtils.isEmpty(heatTuple)){ |
|
|
|
heatTuple.forEach(tupleSet -> { |
|
|
|
tupleSet.forEach( tuple -> { |
|
|
|
IssueCategoryTagResultDTO entity = parseObject(tuple.getValue(),IssueCategoryTagResultDTO.class); |
|
|
|
Double heatScore = tuple.getScore(); |
|
|
|
List<IssueCategoryTagResultDTO> queue = heatMap.get(heatScore); |
|
|
|
if(CollectionUtils.isEmpty(queue)) queue = new LinkedList<>(); |
|
|
|
queue.add(entity); |
|
|
|
} ); |
|
|
|
}); |
|
|
|
List<IssueCategoryTagResultDTO> result = new LinkedList<>(); |
|
|
|
heatMap.keySet().stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).forEach(count -> { |
|
|
|
result.addAll(heatMap.get(count)); |
|
|
|
}); |
|
|
|
return result; |
|
|
|
|
|
|
|
} |
|
|
|
log.warn("fetch customer govern tag cache blankly,customerId:{},now begin compensation...", customerId); |
|
|
|
|
|
|
|
if(CollectionUtils.isEmpty(keys) || !keys.iterator().next().contains(ModuleConstants.CUSTOMIZED_TAG_CATEGORY_ID)) { |
|
|
|
log.warn("fetch customer govern tag cache blankly , customerId:{} , now begin compensation...", customerId); |
|
|
|
|
|
|
|
List<IssueCategoryTagResultDTO> compensate = compensate(customerId, category); |
|
|
|
Map<String,List<IssueCategoryTagResultDTO>> compensate = compensate(customerId, category, ifOther); |
|
|
|
|
|
|
|
if (CollectionUtils.isEmpty(compensate)) { |
|
|
|
log.error("compensation failure or there is no default tag data in database !!"); |
|
|
|
log.error("compensation failure or there is no default tag data in database!!"); |
|
|
|
return null; |
|
|
|
} else { |
|
|
|
log.warn("compensation completed !!"); |
|
|
|
log.warn("compensation completed!!"); |
|
|
|
return compensate; |
|
|
|
} |
|
|
|
}return null; |
|
|
|
} |
|
|
|
|
|
|
|
public List<IssueCategoryTagResultDTO> compensate(String customerId,List<String> category){ |
|
|
|
/** |
|
|
|
* @Description category为空,则补偿全部,返回全部 |
|
|
|
* category不为空,则补偿集合中的类别标签以及自定义标签 |
|
|
|
* category为"customize",只补偿自定义标签 |
|
|
|
* 只需查询标签库(issue_project_tag_dict)中的issueUseCount和projectUseCount即可 |
|
|
|
* @param customerId |
|
|
|
* @param category |
|
|
|
* @return java.util.List<com.epmet.dto.result.IssueCategoryTagResultDTO> |
|
|
|
* @author wangc |
|
|
|
* @date 2020.12.10 09:34 |
|
|
|
*/ |
|
|
|
public Map<String,List<IssueCategoryTagResultDTO>> compensate(String customerId,List<String> category,boolean ifOther){ |
|
|
|
//TODO 补偿机制
|
|
|
|
|
|
|
|
List<IssueProjectTagDictEntity> _default = poolDao.selectTagByCategory(ifOther || CollectionUtils.isEmpty(category) ? null : category, NumConstant.ZERO_STR, customerId);//默认
|
|
|
|
List<IssueProjectTagDictEntity> _customized = poolDao.selectTagByCategory(null,NumConstant.ONE_STR,customerId);//自定义
|
|
|
|
|
|
|
|
|
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|