diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java index 321211465d..dcf93d3a24 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java @@ -8,6 +8,8 @@ package com.epmet.commons.tools.redis; +import com.epmet.commons.tools.constant.StrConstant; + /** * @author Mark sunlightcs@gmail.com * @since 1.0.0 @@ -213,4 +215,43 @@ public class RedisKeys { public static String getAgencyByIdKey(String agencyId) { return rootPrefix.concat("gov:agency:").concat(agencyId); } + + /** + * 客户标签排行 缓存Key + * @param customerId + * @return + */ + public static String getCustomerTagKey(String customerId) { + return rootPrefix.concat("tags:customer:rankingTag:").concat(customerId); + } + + /** + * 客户关联标签 缓存Key + * @param customerId + * @param tagId + * @return + */ + public static String getCustomerReTagKey(String customerId,String tagId) { + return rootPrefix.concat("tags:customer:relationTag:").concat(customerId).concat(StrConstant.COLON).concat(tagId); + } + + /** + * 网格标签排行 缓存Key + * @param gridId + * @return + */ + public static String getGridTagKey(String gridId) { + return rootPrefix.concat("tags:grid:rankingTag:").concat(gridId); + } + + /** + * 网格关联标签 缓存Key + * @param gridId + * @param tagId + * @return + */ + public static String getGridReTagKey(String gridId,String tagId) { + return rootPrefix.concat("tags:grid:relationTag:").concat(gridId).concat(StrConstant.COLON).concat(tagId); + } + } diff --git a/epmet-module/gov-voice/gov-voice-client/src/main/java/com/epmet/dto/form/InitTagFormDTO.java b/epmet-module/gov-voice/gov-voice-client/src/main/java/com/epmet/dto/form/InitTagFormDTO.java new file mode 100644 index 0000000000..c8517f896d --- /dev/null +++ b/epmet-module/gov-voice/gov-voice-client/src/main/java/com/epmet/dto/form/InitTagFormDTO.java @@ -0,0 +1,18 @@ +package com.epmet.dto.form; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * desc:初始化/重新加载标签数据到数据库 + */ +@Data +public class InitTagFormDTO implements Serializable { + private static final long serialVersionUID = -4982447946629101341L; + /** + * 客户列表 list,非必填,如果不填则初始化或重新加载所有客户 + */ + private List customerIdList; +} diff --git a/epmet-module/gov-voice/gov-voice-client/src/main/java/com/epmet/dto/result/UpdateTagUseCountsResultDTO.java b/epmet-module/gov-voice/gov-voice-client/src/main/java/com/epmet/dto/result/UpdateTagUseCountsResultDTO.java index 8bc0f69d21..fba5e29854 100644 --- a/epmet-module/gov-voice/gov-voice-client/src/main/java/com/epmet/dto/result/UpdateTagUseCountsResultDTO.java +++ b/epmet-module/gov-voice/gov-voice-client/src/main/java/com/epmet/dto/result/UpdateTagUseCountsResultDTO.java @@ -13,6 +13,15 @@ public class UpdateTagUseCountsResultDTO implements Serializable { private static final long serialVersionUID = -6331586672885417576L; + public UpdateTagUseCountsResultDTO() { + super(); + } + + public UpdateTagUseCountsResultDTO(String tagId, String tagName) { + this.tagId = tagId; + this.tagName = tagName; + } + /** * 标签id */ diff --git a/epmet-module/gov-voice/gov-voice-server/README.md b/epmet-module/gov-voice/gov-voice-server/README.md new file mode 100644 index 0000000000..0d08501df5 --- /dev/null +++ b/epmet-module/gov-voice/gov-voice-server/README.md @@ -0,0 +1,6 @@ +## epmet-cloud + +客户(网格)标签如果redis中需要重新加载数据到redis +执行以下命令: +参数:customerIdList 数组 非必填;不填则刷新全部客户 +curl -H "Content-Type:application/json" -X POST --data '{"customerIdList": ["客户ID"]}' http://localhost:8105/gov/voice/tag/inittag diff --git a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/constant/TagConstant.java b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/constant/TagConstant.java index b5e1375746..7e51e3a3d1 100644 --- a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/constant/TagConstant.java +++ b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/constant/TagConstant.java @@ -17,21 +17,25 @@ public interface TagConstant { /** * 客户维度(政府端) 热度标签 key的前缀 【zset】 + * 完整key:GRID_TAG_KEY:客户ID */ String GOV_TAG_KEY = "epmet:tags:customer:rankingTag:"; /** * 客户维度(政府端) 关联标签 key的前缀 【set】 + * 完整key:GRID_TAG_KEY:标签ID */ String GOV_RETAG_KEY = "epmet:tags:customer:relationTag:"; /** * 网格热度标签(居民端) key的前缀 【zset】 + * 完整key:GRID_TAG_KEY:网格ID */ String GRID_TAG_KEY = "epmet:tags:grid:rankingTag:"; /** * 网格关联标签(居民端) key的前缀 【set】 + * 完整key:GRID_RETAG_KEY:网格ID:标签ID */ String GRID_RETAG_KEY ="epmet:tags:grid:relationTag:"; diff --git a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/controller/TagController.java b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/controller/TagController.java index 5dbec6fa20..bd2603685b 100644 --- a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/controller/TagController.java +++ b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/controller/TagController.java @@ -1,12 +1,11 @@ package com.epmet.controller; import com.epmet.commons.tools.annotation.LoginUser; -import com.epmet.commons.tools.annotation.RequirePermission; -import com.epmet.commons.tools.enums.RequirePermissionEnum; import com.epmet.commons.tools.security.dto.TokenDto; import com.epmet.commons.tools.utils.Result; import com.epmet.commons.tools.validator.ValidatorUtils; import com.epmet.dto.form.CorrelationTagListFormDTO; +import com.epmet.dto.form.InitTagFormDTO; import com.epmet.dto.form.ResiTagListFormDTO; import com.epmet.dto.form.TagCascadeListFormDTO; import com.epmet.dto.result.CorrelationTagListResultDTO; @@ -72,4 +71,14 @@ public class TagController { return new Result>().ok(tagService.tagCascadeList(formDto)); } + /** + * desc:初始化/重新加载 db标签到redis + * @param formDto + * @return + */ + @PostMapping("inittag") + public Result initTag(@RequestBody InitTagFormDTO formDto){ + return new Result().ok(tagService.initTag(formDto)); + } + } diff --git a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/dao/ArticlePublishRangeDao.java b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/dao/ArticlePublishRangeDao.java index 9d9ffa0830..9fe5fa1614 100644 --- a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/dao/ArticlePublishRangeDao.java +++ b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/dao/ArticlePublishRangeDao.java @@ -18,7 +18,6 @@ package com.epmet.dao; import com.epmet.commons.mybatis.dao.BaseDao; -import com.epmet.dto.ArticlePublishRangeDTO; import com.epmet.entity.ArticlePublishRangeEntity; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -42,5 +41,10 @@ public interface ArticlePublishRangeDao extends BaseDao selectByArticleId(ArticlePublishRangeEntity rangeEntity); - + /** + * desc:获取网格发布的文章 用于初始化数据库标签数据到redis + * @param customerIdList + * @return + */ + List selectInitData(@Param("customerIdList") List customerIdList); } \ No newline at end of file diff --git a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/dao/ArticleTagsDao.java b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/dao/ArticleTagsDao.java index 4bba49e743..e6a006e166 100644 --- a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/dao/ArticleTagsDao.java +++ b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/dao/ArticleTagsDao.java @@ -40,5 +40,11 @@ public interface ArticleTagsDao extends BaseDao { * @author zxc */ void addArticleTags(@Param("addArticleTags")List addArticleTags); - + + /** + * desc:获取文章标签数据 用于初始化到redis + * @param customerIdList + * @return + */ + List selectInitData(@Param("customerIdList")List customerIdList); } \ No newline at end of file diff --git a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/dao/TagCustomerDao.java b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/dao/TagCustomerDao.java index ea9faaef02..edcc5ec3b5 100644 --- a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/dao/TagCustomerDao.java +++ b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/dao/TagCustomerDao.java @@ -49,4 +49,10 @@ public interface TagCustomerDao extends BaseDao { */ void initTags(@Param("tags") List tags); + /** + * desc:获取需要初始化的客户标签 + * @param customerIdList + * @return + */ + List selectInitData(@Param("customerIdList") List customerIdList); } \ No newline at end of file diff --git a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/dao/TagGridDao.java b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/dao/TagGridDao.java index 8dc949f8cd..26c393f3ce 100644 --- a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/dao/TagGridDao.java +++ b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/dao/TagGridDao.java @@ -40,5 +40,11 @@ public interface TagGridDao extends BaseDao { * @author zxc */ void updateGridTag(@Param("gridTags") List gridTags,@Param("userId")String userId); - + + /** + * desc:获取网格初始化数据 用于加载数据库数据到redis + * @param customerIdList + * @return + */ + List selectInitData(@Param("customerIdList") List customerIdList); } \ No newline at end of file diff --git a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/redis/TagRedis.java b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/redis/TagRedis.java index 47957e68dd..9902437427 100644 --- a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/redis/TagRedis.java +++ b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/redis/TagRedis.java @@ -19,6 +19,7 @@ package com.epmet.redis; import com.epmet.commons.tools.constant.NumConstant; import com.epmet.commons.tools.exception.RenException; +import com.epmet.commons.tools.redis.RedisKeys; import com.epmet.commons.tools.redis.RedisUtils; import com.epmet.constant.TagConstant; import com.epmet.dto.form.CorrelationTagListFormDTO; @@ -49,11 +50,28 @@ public class TagRedis { @Autowired private RedisTemplate redisTemplate; - public void delete(Object[] ids) { + private Long zAdd(String key,Set> value) { + return redisTemplate.opsForZSet().add(key,value); + } + /** + * desc:添加或修改客户标签排行 + * @param customerId + * @param value + * @return + */ + public Long zAddCustomerTag(String customerId,Set> value){ + return this.zAdd(RedisKeys.getCustomerTagKey(customerId),value); } - public void set(){ + /** + * desc:添加或修改网格标签排行 + * @param gridId + * @param value + * @return + */ + public Long zAddGridTag(String gridId,Set> value){ + return this.zAdd(RedisKeys.getGridTagKey(gridId),value); } /** diff --git a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/service/TagService.java b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/service/TagService.java index b78a9f837a..c4e3e85f49 100644 --- a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/service/TagService.java +++ b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/service/TagService.java @@ -2,6 +2,7 @@ package com.epmet.service; import com.epmet.commons.tools.security.dto.TokenDto; import com.epmet.dto.form.CorrelationTagListFormDTO; +import com.epmet.dto.form.InitTagFormDTO; import com.epmet.dto.form.ResiTagListFormDTO; import com.epmet.dto.form.TagCascadeListFormDTO; import com.epmet.dto.result.CorrelationTagListResultDTO; @@ -40,4 +41,10 @@ public interface TagService { */ List tagCascadeList(TagCascadeListFormDTO formDto); + /** + * desc:初始化/重新加载 客户标签到redis,用于数据库与redis数据同步的 + * @param formDto + * @return + */ + Boolean initTag(InitTagFormDTO formDto); } \ No newline at end of file diff --git a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/service/impl/TagServiceImpl.java b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/service/impl/TagServiceImpl.java index 19dcbf3d5d..4ac5d67ac0 100644 --- a/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/service/impl/TagServiceImpl.java +++ b/epmet-module/gov-voice/gov-voice-server/src/main/java/com/epmet/service/impl/TagServiceImpl.java @@ -1,25 +1,33 @@ package com.epmet.service.impl; import com.epmet.commons.tools.constant.NumConstant; +import com.epmet.commons.tools.constant.StrConstant; +import com.epmet.commons.tools.exception.RenException; import com.epmet.commons.tools.security.dto.TokenDto; import com.epmet.constant.TagConstant; -import com.epmet.dao.ArticleDao; -import com.epmet.dao.TagCustomerDao; -import com.epmet.dao.TagDefaultDao; +import com.epmet.dao.*; import com.epmet.dto.form.*; import com.epmet.dto.result.CorrelationTagListResultDTO; import com.epmet.dto.result.TagInfoResultDTO; import com.epmet.dto.result.UpdateTagUseCountsResultDTO; +import com.epmet.entity.ArticlePublishRangeEntity; +import com.epmet.entity.ArticleTagsEntity; +import com.epmet.entity.TagCustomerEntity; +import com.epmet.entity.TagGridEntity; import com.epmet.redis.TagRedis; import com.epmet.service.TagService; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.DefaultTypedTuple; +import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; +import java.util.*; +import java.util.stream.Collectors; +@Slf4j @Service public class TagServiceImpl implements TagService { @@ -31,6 +39,12 @@ public class TagServiceImpl implements TagService { private TagDefaultDao tagDefaultDao; @Autowired private TagCustomerDao tagCustomerDao; + @Autowired + private ArticleTagsDao articleTagsDao; + @Autowired + private TagGridDao tagGridDao; + @Autowired + private ArticlePublishRangeDao articlePublishRangeDao; /** * @Description 已发布列表页的标签——政府端 @@ -118,4 +132,114 @@ public class TagServiceImpl implements TagService { } return tagRedis.getResiTag(formDto); } + + @Override + public Boolean initTag(InitTagFormDTO formDto) { + List customerTagList = tagCustomerDao.selectInitData(formDto.getCustomerIdList()); + if (CollectionUtils.isEmpty(customerTagList)) { + throw new RenException("客户标签数为空"); + } + + Map>> customerTag = new HashMap<>(); + customerTagList.stream().forEach(tag -> { + buildZset(customerTag, tag.getCustomerId(), tag.getId(), tag.getTagName(), tag.getUseCount()); + }); + + if (customerTag.size() > 0) { + customerTag.forEach((customerId, tagSet) -> tagRedis.zAddCustomerTag(customerId, tagSet)); + } + //key customerId:tagId + Map> reCustomerTagMap = new HashMap<>(); + List articleTagList = articleTagsDao.selectInitData(formDto.getCustomerIdList()); + Map> articleReTagMap = new HashMap<>(); + if (!CollectionUtils.isEmpty(articleTagList)) { + articleReTagMap = articleTagList.stream().collect(Collectors.groupingBy(ArticleTagsEntity::getArticleId)); + articleReTagMap.forEach((articleId, articleReTagList) -> { + buildReTag(reCustomerTagMap, articleReTagList); + }); + } + if (reCustomerTagMap.size() > 0) { + reCustomerTagMap.forEach((customerAndTagId, tagSet) -> tagRedis.updateMoreTag(TagConstant.GOV_RETAG_KEY.concat(customerAndTagId), tagSet)); + } + + + //初始化 网格级标签 + List gridTagList = tagGridDao.selectInitData(formDto.getCustomerIdList()); + if (CollectionUtils.isEmpty(gridTagList)) { + throw new RenException("网格标签数为空"); + } + customerTag.clear(); + gridTagList.stream().forEach(tag -> buildZset(customerTag, tag.getGridId(), tag.getTagId(), tag.getTagName(), tag.getUseCount())); + if (customerTag.size() > 0) { + customerTag.forEach((gridId, tagSet) -> tagRedis.zAddGridTag(gridId, tagSet)); + } + + //获取网格发布的文章 按网格排序 + List publishRangeTagList = articlePublishRangeDao.selectInitData(formDto.getCustomerIdList()); + if (CollectionUtils.isEmpty(publishRangeTagList)){ + log.error("publishRangeTagList return empty"); + return false; + } + //网格关联标签结果 key:gridId:tagId + Map> resultMap = new HashMap<>(); + Map> gridArticleListMap = publishRangeTagList.stream().collect(Collectors.groupingBy(ArticlePublishRangeEntity::getGridId)); + for (Map.Entry> entry : gridArticleListMap.entrySet()) { + String gridId = entry.getKey(); + List articleIdList = entry.getValue(); + for (ArticlePublishRangeEntity publishRange : articleIdList) { + List articleTagsEntities = articleReTagMap.get(publishRange.getArticleId()); + if (CollectionUtils.isEmpty(articleTagsEntities)){ + //该文章诶呦标签 + continue; + } + buildGridReTag(resultMap,gridId,articleTagsEntities); + } + } + if (resultMap.size() > 0) { + resultMap.forEach((gridIdAndTagId, tagSet) -> tagRedis.updateMoreTag(TagConstant.GRID_RETAG_KEY.concat(gridIdAndTagId), tagSet)); + } + return true; + } + + private void buildReTag(Map> reCustomerTagMap, List articleReTagList) { + articleReTagList.forEach(articleTag -> { + + String key = articleTag.getCustomerId().concat(StrConstant.COLON).concat(articleTag.getTagId()); + Set reTagSet = reCustomerTagMap.get(key); + if (reTagSet == null) { + reTagSet = new HashSet<>(); + reCustomerTagMap.put(key, reTagSet); + } + Set newReTagSet = articleReTagList.stream().filter(o -> !o.getTagId().equals(articleTag.getTagId())) + .map(tag -> new UpdateTagUseCountsResultDTO(tag.getTagId(), tag.getTagName())).collect(Collectors.toSet()); + reTagSet.addAll(newReTagSet); + }); + } + + private void buildGridReTag(Map> resultMap,String gridId, List articleReTagList) { + articleReTagList.forEach(articleTag -> { + String key = gridId.concat(StrConstant.COLON).concat(articleTag.getTagId()); + Set reTagSet = resultMap.get(key); + if (reTagSet == null) { + reTagSet = new HashSet<>(); + resultMap.put(key, reTagSet); + } + Set newReTagSet = articleReTagList.stream().filter(o -> !o.getTagId().equals(articleTag.getTagId())) + .map(tag -> new UpdateTagUseCountsResultDTO(tag.getTagId(), tag.getTagName())).collect(Collectors.toSet()); + reTagSet.addAll(newReTagSet); + }); + } + + private void buildZset(Map>> customerTag, String customerId, String id, String tagName, Integer useCount) { + Set> typedTupleSet = customerTag.get(customerId); + if (typedTupleSet == null) { + typedTupleSet = new HashSet<>(); + customerTag.put(customerId, typedTupleSet); + } + UpdateTagUseCountsResultDTO initTag = new UpdateTagUseCountsResultDTO(); + initTag.setTagId(id); + initTag.setTagName(tagName); + ZSetOperations.TypedTuple typedTuple1 = new DefaultTypedTuple<>(initTag, Double.valueOf(useCount)); + typedTupleSet.add(typedTuple1); + } } \ No newline at end of file diff --git a/epmet-module/gov-voice/gov-voice-server/src/main/resources/mapper/ArticlePublishRangeDao.xml b/epmet-module/gov-voice/gov-voice-server/src/main/resources/mapper/ArticlePublishRangeDao.xml index b80067be18..c58c230891 100644 --- a/epmet-module/gov-voice/gov-voice-server/src/main/resources/mapper/ArticlePublishRangeDao.xml +++ b/epmet-module/gov-voice/gov-voice-server/src/main/resources/mapper/ArticlePublishRangeDao.xml @@ -18,6 +18,22 @@ ORDER BY created_time ASC + \ No newline at end of file diff --git a/epmet-module/gov-voice/gov-voice-server/src/main/resources/mapper/ArticleTagsDao.xml b/epmet-module/gov-voice/gov-voice-server/src/main/resources/mapper/ArticleTagsDao.xml index 974966df8c..4995354629 100644 --- a/epmet-module/gov-voice/gov-voice-server/src/main/resources/mapper/ArticleTagsDao.xml +++ b/epmet-module/gov-voice/gov-voice-server/src/main/resources/mapper/ArticleTagsDao.xml @@ -12,5 +12,22 @@ #{tag.revision}, #{tag.createdBy}, NOW(),#{tag.updatedBy}, NOW()) + \ No newline at end of file diff --git a/epmet-module/gov-voice/gov-voice-server/src/main/resources/mapper/TagCustomerDao.xml b/epmet-module/gov-voice/gov-voice-server/src/main/resources/mapper/TagCustomerDao.xml index edca182943..12da65d434 100644 --- a/epmet-module/gov-voice/gov-voice-server/src/main/resources/mapper/TagCustomerDao.xml +++ b/epmet-module/gov-voice/gov-voice-server/src/main/resources/mapper/TagCustomerDao.xml @@ -36,5 +36,22 @@ ON DUPLICATE KEY UPDATE UPDATED_TIME = NOW() + \ No newline at end of file diff --git a/epmet-module/gov-voice/gov-voice-server/src/main/resources/mapper/TagGridDao.xml b/epmet-module/gov-voice/gov-voice-server/src/main/resources/mapper/TagGridDao.xml index c3000b425c..c4b54c4dfa 100644 --- a/epmet-module/gov-voice/gov-voice-server/src/main/resources/mapper/TagGridDao.xml +++ b/epmet-module/gov-voice/gov-voice-server/src/main/resources/mapper/TagGridDao.xml @@ -17,5 +17,23 @@ UPDATED_TIME = NOW(), UPDATED_BY = #{userId} + \ No newline at end of file