Commit 093ec286 authored by 吴泽佳's avatar 吴泽佳
parents f7f2e2af 6c3d0c3d
......@@ -23,21 +23,31 @@ public class TopicRankQo {
@ApiModelProperty(value = "讨论量")
private Integer disscussCount;
@ApiModelProperty(value = "阅读量-格式化")
private String formatViewCount;
@ApiModelProperty(value = "讨论量-格式化")
private String formatDisscussCount;
@ApiModelProperty(value = "是否置顶")
private Integer isTop;
@ApiModelProperty(value = "浏览量调整基数")
private Integer viewCntAdjust;
@ApiModelProperty(value = "话题下的帖子权重")
private Integer themeWeight;
/**
* TODO 热度计算算法
*
* @return
*/
public Integer getRank(){
public Integer getRank() {
//顶置话题
if (isTop>0){
if (isTop > 0) {
return Integer.MAX_VALUE;
}
return this.viewCount+this.disscussCount*3+viewCount;
return this.disscussCount * 3 + viewCount + themeWeight;
}
}
......@@ -9,5 +9,5 @@ import java.util.List;
public class ThemeFullSearchReq {
public Pageable page;
public String keyword;
public List<String> excludeIds;
public String ident;
}
......@@ -6,7 +6,6 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data
public class ThemeListReq {
......@@ -19,11 +18,9 @@ public class ThemeListReq {
@ApiModelProperty(value = "话题Id")
public String topicId;
@ApiModelProperty(value = "当前浏览的最后一个themeId,可以为空")
public String lastId="";
@NotNull(message = "分页")
public Pageable page;
public List<String> excludeIds;
@ApiModelProperty(value = "session_id")
public String ident;
}
......@@ -8,11 +8,9 @@ import java.util.List;
@Data
public class ThemeFullSearchResp {
public List<String> excludeIds;
public List<ThemeQo> themes;
public ThemeFullSearchResp() {
this.excludeIds = new ArrayList<>();
this.themes = new ArrayList<>();
}
}
......@@ -8,5 +8,4 @@ import java.util.List;
@Data
public class ThemeListResp {
public List<ThemeQo> themes;
public List<String> excludeIds;
}
......@@ -46,12 +46,12 @@ public class RedisCache {
delete(key);
}
private String get(String key) {
public String get(String key) {
key = cacheName + ":" + key;
return redisHelper.get(key);
}
private void put(String key, Object obj, Integer expireSeconds) {
public void put(String key, Object obj, Integer expireSeconds) {
key = cacheName + ":" + key;
String value = JsonUtil.toJson(obj);
if (expireSeconds == 0) {
......
......@@ -3,12 +3,10 @@ package com.tanpu.community.config;
import com.tanpu.community.cache.RedisCache;
import com.tanpu.community.util.SpringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import java.util.Arrays;
@Configuration
......@@ -19,7 +17,7 @@ public class CacheConfig {
@Bean
public RedisCache redisCache() {
return new RedisCache.Builder().cacheName("redis").build();
return new RedisCache.Builder().cacheName("community2").build();
}
@Bean
......
package com.tanpu.community.controller;
import com.fasterxml.jackson.core.type.TypeReference;
import com.tanpu.common.api.CommonResp;
import com.tanpu.common.util.JsonUtil;
import com.tanpu.community.api.beans.qo.ThemeQo;
import com.tanpu.community.api.beans.resp.FileUploadResp;
import com.tanpu.community.cache.RedisCache;
import com.tanpu.community.manager.FileManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -9,6 +13,9 @@ import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.Arrays;
import java.util.List;
@RestController
@Slf4j
@RequestMapping(value = "/api/file")
......@@ -16,6 +23,9 @@ public class FileController {
@Autowired
private FileManager fileManager;
@Autowired
private RedisCache redisCache;
@Autowired
private CaffeineCacheManager localCache;
......@@ -29,17 +39,25 @@ public class FileController {
@GetMapping("/test")
public String test() {
localCache.getCache("local").put("999", "6666666");
System.out.println((String) localCache.getCache("local").get("999").get());
for (int i = 0; i < 30; i++) {
System.out.println(fileManager.getId("" + i / 2));
}
for (int i = 30; i > 0; i--) {
System.out.println(fileManager.getId("" + i / 2));
}
// redisCache.put("11111", JsonUtil.toJson(list), 60);
//
// String v = redisCache.get("11111");
// System.out.println(v);
// System.out.println(JsonUtil.toJson(JsonUtil.toBean(v, new TypeReference<List<String>>() {
// })));
// localCache.getCache("local").put("999", "6666666");
// System.out.println((String) localCache.getCache("local").get("999").get());
//
//
// for (int i = 0; i < 30; i++) {
// System.out.println(fileManager.getId("" + i / 2));
// }
//
// for (int i = 30; i > 0; i--) {
// System.out.println(fileManager.getId("" + i / 2));
// }
return "";
}
}
......@@ -32,7 +32,7 @@ public class SearchController {
@PostMapping(value = "/themeFullText")
@ResponseBody
public CommonResp<ThemeFullSearchResp> themeFullText(@RequestBody ThemeFullSearchReq req) {
ThemeFullSearchResp resp = themeManager.themeFullSearch(req.keyword, req.page.pageNumber, req.page.pageSize, req.excludeIds, userHolder.getUserId());
ThemeFullSearchResp resp = themeManager.themeFullSearch(req.keyword, req.page.pageNumber, req.page.pageSize, req.ident, userHolder.getUserId());
return CommonResp.success(resp);
}
......
......@@ -42,7 +42,7 @@ public class ThemeController {
@ResponseBody
public CommonResp<ThemeListResp> selectInterestList(@Validated @RequestBody ThemeListReq req) {
String userId = userHolder.getUserId();
ThemeListResp result = themeManager.queryThemes(req, userId);
ThemeListResp result = themeManager.queryList(req, userId);
return CommonResp.success(result);
}
......
......@@ -121,7 +121,7 @@ public class CommentManager {
//更改举报状态
commentService.updateReportStatus(req.getCommentId());
//写入举报记录表
CommentEntity commentEntity = commentService.queryByCommentId(req.getCommentId());
CommentEntity commentEntity = commentService.queryByIdIncludeDelete(req.getCommentId());
reportLogService.insert(ReportTypeEnum.COMMENT, userId, req.getCommentId(), commentEntity.getAuthorId(), req.getReason());
}
......
package com.tanpu.community.manager;
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.collect.Sets;
import com.tanpu.common.api.CommonResp;
import com.tanpu.common.exception.BizException;
......@@ -59,9 +60,6 @@ public class ThemeManager {
@Autowired
private BlackListService blackListService;
@Autowired
private UserInfoService userInfoService;
@Autowired
private ThemeAttachmentService themeAttachmentService;
......@@ -89,7 +87,16 @@ public class ThemeManager {
@Autowired
private RecommendService recommendService;
public ThemeFullSearchResp themeFullSearch(String keyword, Integer pageNo, Integer pageSize, List<String> excludeIds, String userId) {
public ThemeFullSearchResp themeFullSearch(String keyword, Integer pageNo, Integer pageSize, String ident, String userId) {
List<String> excludeIds;
if (pageNo > 1) {
String l = redisCache.get("themeFullSearch_" + ident);
excludeIds = StringUtils.isBlank(l) ? new ArrayList<>() : JsonUtil.toBean(l, new TypeReference<List<String>>() {
});
} else {
excludeIds = new ArrayList<>();
}
Integer from = (pageNo - 1) * pageSize;
ThemeFullSearchResp resp = new ThemeFullSearchResp();
......@@ -115,7 +122,9 @@ public class ThemeManager {
for (ThemeQo theme : resp.themes) {
theme.briefContent4FullSearch = BizUtils.getThemeContent(keyword, theme);
}
resp.excludeIds.addAll(filterEsIds);
excludeIds.addAll(resp.themes.stream().map(ThemeQo::getThemeId).collect(Collectors.toList()));
redisCache.put("themeFullSearch_" + ident, excludeIds, 60 * 60 * 6);
return resp;
}
......@@ -126,7 +135,6 @@ public class ThemeManager {
*/
@Transactional
public CreateThemeResp publishTheme(CreateThemeReq req, String userId) {
// 保存主题表
ThemeEntity themeEntity = new ThemeEntity();
BeanUtils.copyProperties(req, themeEntity);
......@@ -192,27 +200,36 @@ public class ThemeManager {
* 推荐:由最热,最新和python推荐三个部分组成,比例为6,3,1
*/
// 查询主题列表:推荐/关注/热门/最新
public ThemeListResp queryThemes(ThemeListReq req, String userId) {
public ThemeListResp queryList(ThemeListReq req, String userId) {
List<String> excludeIds;
if (req.page.pageNumber > 1) {
String l = redisCache.get("queryThemes_" + req.ident);
excludeIds = StringUtils.isBlank(l) ? new ArrayList<>() : JsonUtil.toBean(l, new TypeReference<List<String>>() {
});
} else {
excludeIds = new ArrayList<>();
}
Integer pageStart = (req.page.pageNumber - 1) * req.page.pageSize;
Integer pageSize = req.page.pageSize;
Integer querySize = pageSize * 3;
List<ThemeEntity> themes = new ArrayList<>();
if (ThemeListTypeEnum.RECOMMEND.getCode().equals(req.getType())) {
//推荐
// 推荐
// 需要筛掉用户访问过详情的 & 最近出现在列表页过的.
List<String> visitedIds = visitLogService.queryUserRecentVisited(userId);
List<String> excludes = ListUtils.union(req.excludeIds, visitedIds);
List<String> recmdIds = recommendService.getRecommendThemes(pageStart, querySize, userId, excludes);
List<String> excludes = ListUtils.union(excludeIds, visitedIds);
List<String> recmdIds = recommendService.getRecommendThemes(pageStart, pageSize, userId, excludes);
recmdIds = BizUtils.subList(recmdIds, pageStart, pageSize);
themes = themeService.queryByThemeIds(recmdIds);
themes = RankUtils.sortThemeEntityByIds(themes, recmdIds);
themes = RankUtils.sortThemeEntityByIds(themes, recmdIds).stream().limit(pageSize).collect(Collectors.toList());
} else if (ThemeListTypeEnum.FOLLOW.getCode().equals(req.getType())) {
// TODO 临时埋点,接入新埋点后删除
if (CollectionUtils.isEmpty(req.getExcludeIds())) {
if (CollectionUtils.isEmpty(excludeIds)) {
visitLogService.addPageView(userId, userId, VisitTypeEnum.FOLLOW_THEME_VIEW);
}
// 根据关注列表查询,按时间倒序
......@@ -225,7 +242,7 @@ public class ThemeManager {
throw new BizException("TopicId为空");
}
List<String> rankThemeIds = rankService.getRankThemeListByTopic(req.getTopicId(), req.excludeIds);
List<String> rankThemeIds = rankService.getRankThemeListByTopic(req.getTopicId(), excludeIds);
rankThemeIds = BizUtils.subList(rankThemeIds, pageStart, pageSize);
themes = themeService.queryByThemeIds(rankThemeIds);
......@@ -236,14 +253,15 @@ public class ThemeManager {
if (StringUtils.isEmpty(req.getTopicId())) {
throw new BizException("TopicId为空");
}
themes = themeService.queryNewestByTopic(req.topicId, pageStart, querySize, req.excludeIds);
themes = themeService.queryNewestByTopic(req.topicId, pageStart, pageSize, excludeIds);
}
ThemeListResp resp = new ThemeListResp();
resp.excludeIds = req.excludeIds;
resp.excludeIds.addAll(themes.stream().map(ThemeEntity::getThemeId).collect(Collectors.toList()));
resp.themes = convertEntityToQo(themes, userId);
excludeIds.addAll(resp.themes.stream().map(ThemeQo::getThemeId).collect(Collectors.toList()));
redisCache.put("queryThemes_" + req.ident, excludeIds, 60 * 60 * 6);
//组装详情
return resp;
}
......
......@@ -204,19 +204,14 @@ public class BatchFeignCallService {
}
if (!CollectionUtils.isEmpty(courseIds)) {
// 新版课程列表
CommonResp<List<CourseSimpleResp>> commonResp =
feignForCourse.getCourseSimpleList(setToList(courseIds));
if (commonResp.isSuccess() & !CollectionUtils.isEmpty(commonResp.getData())) {
courseMap.putAll(commonResp.getData().stream().collect(Collectors.toMap(CourseSimpleResp::getCourseId, item -> item,(oldValue,newValue)->oldValue)));
}
List<CourseSimpleResp> list = feignService.getCourseSimpleList(setToList(courseIds));
courseMap.putAll(list.stream().collect(Collectors.toMap(CourseSimpleResp::getCourseId, item -> item,(oldValue,newValue)->oldValue)));
}
if (!CollectionUtils.isEmpty(zhiboIds)) {
// 直播列表
CommonResp<List<ZhiboListResp>> commonResp =
List<ZhiboListResp> list = feignService.getZhiboSimpleList(setToList(zhiboIds));
feignClientForZhibo.simpleList(setToList(zhiboIds));
if (commonResp.isSuccess() && !CollectionUtils.isEmpty(commonResp.getData())) {
zhiboMap.putAll(commonResp.getData().stream().collect(Collectors.toMap(ZhiboListResp::getId, item -> item,(oldValue,newValue)->oldValue)));
}
zhiboMap.putAll(list.stream().collect(Collectors.toMap(ZhiboListResp::getId, item -> item,(oldValue,newValue)->oldValue)));
}
if (!CollectionUtils.isEmpty(imageIds)) {
// 查询图片
......@@ -239,7 +234,7 @@ public class BatchFeignCallService {
}
if (!CollectionUtils.isEmpty(userIds)) {
// 查询用户信息
List<UserInfoResp> queryUsersListNew = feignClientForFatools.queryUserListNew(setToList(userIds));
List<UserInfoResp> queryUsersListNew = feignService.getUserList(setToList(userIds));
if (!CollectionUtils.isEmpty(userIds)) {
userMap.putAll(queryUsersListNew.stream().collect(Collectors
.toMap(UserInfoResp::getUserId, o -> o)));
......@@ -273,16 +268,13 @@ public class BatchFeignCallService {
// .fundIds(Lists.newArrayList(tanpuFundIds))
// .build();
// 探普产品
CommonResp<List<ProductInfoVO>> commonResp =
feignForProduct.getProductInfoByIds(setToList(tanpuFundIds));
if (commonResp.isSuccess() && !CollectionUtils.isEmpty(commonResp.getData())) {
List<FundInfoBaseResp> fundInfoBaseRespList = commonResp.getData().stream().map(item -> {
FundInfoBaseResp fundInfoBaseResp = FundInfoBaseResp.builder().build();
BeanUtils.copyProperties(item, fundInfoBaseResp);
return fundInfoBaseResp;
}).collect(Collectors.toList());
tampFundMap = fundInfoBaseRespList.stream().collect(Collectors.toMap(FundInfoBaseResp::getFundId, item -> item));
}
List<ProductInfoVO> list = feignService.getProductInfoByIds(setToList(tanpuFundIds));
List<FundInfoBaseResp> fundInfoBaseRespList = list.stream().map(item -> {
FundInfoBaseResp fundInfoBaseResp = FundInfoBaseResp.builder().build();
BeanUtils.copyProperties(item, fundInfoBaseResp);
return fundInfoBaseResp;
}).collect(Collectors.toList());
tampFundMap = fundInfoBaseRespList.stream().collect(Collectors.toMap(FundInfoBaseResp::getFundId, item -> item));
if (tampFundMap != null && tampFundMap.size() > 0) {
fundMap.putAll(tampFundMap);
......@@ -291,16 +283,13 @@ public class BatchFeignCallService {
// 私募产品
if (!CollectionUtils.isEmpty(fundIds)) {
// 私募产品
CommonResp<List<ProductInfoVO>> fundResult =
feignForFund.getProductList(setToList(fundIds));
if (fundResult.isSuccess() && !CollectionUtils.isEmpty(fundResult.getData())) {
List<FundInfoBaseResp> fundInfoBaseRespList = fundResult.getData().stream().map(item -> {
FundInfoBaseResp fundInfoBaseResp = FundInfoBaseResp.builder().build();
BeanUtils.copyProperties(item, fundInfoBaseResp);
return fundInfoBaseResp;
}).collect(Collectors.toList());
privateFundMap = fundInfoBaseRespList.stream().collect(Collectors.toMap(FundInfoBaseResp::getFundId, item -> item));
}
List<ProductInfoVO> list = feignService.getFundList(setToList(fundIds));
List<FundInfoBaseResp> fundInfoBaseRespList = list.stream().map(item -> {
FundInfoBaseResp fundInfoBaseResp = FundInfoBaseResp.builder().build();
BeanUtils.copyProperties(item, fundInfoBaseResp);
return fundInfoBaseResp;
}).collect(Collectors.toList());
privateFundMap = fundInfoBaseRespList.stream().collect(Collectors.toMap(FundInfoBaseResp::getFundId, item -> item));
if (privateFundMap != null && privateFundMap.size() > 0) {
fundMap.putAll(privateFundMap);
......@@ -309,16 +298,14 @@ public class BatchFeignCallService {
// 理财师导入产品
if (!CollectionUtils.isEmpty(ifaFundIds)) {
CommonResp<List<ProductInfoVO>> ifaFundResult =
feignForFund.getPrivateFundList(setToList(ifaFundIds));
if (ifaFundResult.isSuccess() && !CollectionUtils.isEmpty(ifaFundResult.getData())) {
List<FundInfoBaseResp> fundInfoBaseRespList = ifaFundResult.getData().stream().map(item -> {
FundInfoBaseResp fundInfoBaseResp = FundInfoBaseResp.builder().build();
BeanUtils.copyProperties(item, fundInfoBaseResp);
return fundInfoBaseResp;
}).collect(Collectors.toList());
ifaFundMap = fundInfoBaseRespList.stream().collect(Collectors.toMap(FundInfoBaseResp::getFundId, item -> item));
}
List<ProductInfoVO> list = feignService.getPrivateFundList(setToList(ifaFundIds));
List<FundInfoBaseResp> fundInfoBaseRespList = list.stream().map(item -> {
FundInfoBaseResp fundInfoBaseResp = FundInfoBaseResp.builder().build();
BeanUtils.copyProperties(item, fundInfoBaseResp);
return fundInfoBaseResp;
}).collect(Collectors.toList());
ifaFundMap = fundInfoBaseRespList.stream().collect(Collectors.toMap(FundInfoBaseResp::getFundId, item -> item));
if (ifaFundMap != null && ifaFundMap.size() > 0) {
fundMap.putAll(ifaFundMap);
......@@ -327,16 +314,14 @@ public class BatchFeignCallService {
if (!CollectionUtils.isEmpty(publicFundIds)) {
// 公募产品
CommonResp<List<ProductInfoVO>> publicFundResult =
feignForPublicFund.getProductList(setToList(publicFundIds));
if (publicFundResult.isSuccess() && !CollectionUtils.isEmpty(publicFundResult.getData())) {
List<FundInfoBaseResp> fundInfoBaseRespList = publicFundResult.getData().stream().map(item -> {
FundInfoBaseResp fundInfoBaseResp = FundInfoBaseResp.builder().build();
BeanUtils.copyProperties(item, fundInfoBaseResp);
return fundInfoBaseResp;
}).collect(Collectors.toList());
publicFundMap = fundInfoBaseRespList.stream().collect(Collectors.toMap(FundInfoBaseResp::getFundId, item -> item));
}
List<ProductInfoVO> list = feignService.getPublicFundList(setToList(publicFundIds));
List<FundInfoBaseResp> fundInfoBaseRespList = list.stream().map(item -> {
FundInfoBaseResp fundInfoBaseResp = FundInfoBaseResp.builder().build();
BeanUtils.copyProperties(item, fundInfoBaseResp);
return fundInfoBaseResp;
}).collect(Collectors.toList());
publicFundMap = fundInfoBaseRespList.stream().collect(Collectors.toMap(FundInfoBaseResp::getFundId, item -> item));
if (publicFundMap != null && publicFundMap.size() > 0) {
fundMap.putAll(publicFundMap);
}
......
......@@ -42,12 +42,12 @@ public class CommentService {
commentEntity.setCommentId(uuidGenHelper.getUuidStr());
commentMapper.insert(commentEntity);
//失效缓存
redisCache.evict(StringUtils.joinWith("_", CACHE_COMMENT_THEMEID, commentEntity.getThemeId()));
redisCache.evict(StringUtils.joinWith("_", CACHE_THEME_ID, commentEntity.getThemeId()));
evictThemeCache(commentEntity.getThemeId());
}
public CommentEntity queryByCommentId(String commmentId) {
public CommentEntity queryByIdIncludeDelete(String commmentId) {
return commentMapper.selectOne(new LambdaQueryWrapper<CommentEntity>()
.eq(CommentEntity::getCommentId, commmentId));
}
......@@ -58,14 +58,16 @@ public class CommentService {
return 0;
}
return commentMapper.selectList((new LambdaQueryWrapper<CommentEntity>()
.in(CommentEntity::getThemeId, themeIds)))
.in(CommentEntity::getThemeId, themeIds))
.eq(CommentEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED))
.size();
}
//统计主题集合的评论量
public Integer getCommentCountByThemeId(String themeId) {
return commentMapper.selectList((new LambdaQueryWrapper<CommentEntity>()
.eq(CommentEntity::getThemeId, themeId)))
.eq(CommentEntity::getThemeId, themeId))
.eq(CommentEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED))
.size();
}
......@@ -115,27 +117,36 @@ public class CommentService {
return commentMapper.selectList(queryWrapper);
}
//修改举报状态,可修改已删除
public void updateReportStatus(String commentId) {
CommentEntity commentEntity = queryByCommentId(commentId);
CommentEntity commentEntity = queryByIdIncludeDelete(commentId);
if (commentEntity == null) {
throw new BizException("评论未找到,id:" + commentId);
}
commentEntity.setReportStatus(ReportStatusEnum.REPORTED.getCode());
commentMapper.updateById(commentEntity);
redisCache.evict(StringUtils.joinWith("_", CAHCE_COMMENT_ID, commentId));
//失效缓存
evictThemeCache(commentEntity.getThemeId());
}
//删除评论
@Transactional
public void delete(String commentId, String userId) {
CommentEntity commentEntity = this.queryByCommentId(commentId);
CommentEntity commentEntity = this.queryByIdIncludeDelete(commentId);
if (commentEntity==null || !commentEntity.getAuthorId().equals(userId)){
throw new BizException("删除评论与用户不匹配,commentId:"+commentId+",userId:"+userId);
}
commentEntity.setDeleteTag(DeleteTagEnum.DELETED.getCode());
commentMapper.updateById(commentEntity);
//删除主题的评论列表缓存
redisCache.evict(StringUtils.joinWith("_", CAHCE_COMMENT_ID, commentEntity.getThemeId()));
//失效缓存
evictThemeCache(commentEntity.getThemeId());
}
// 失效关联主题缓存
private void evictThemeCache(String themeId){
redisCache.evict(StringUtils.joinWith("_", CACHE_COMMENT_THEMEID, themeId));
redisCache.evict(StringUtils.joinWith("_", CACHE_THEME_ID, themeId));
}
}
......@@ -3,8 +3,11 @@ package com.tanpu.community.service;
import com.alibaba.fastjson.JSON;
import com.tanpu.common.api.CommonResp;
import com.tanpu.common.exception.BizException;
import com.tanpu.community.api.beans.vo.feign.course.CourseSimpleResp;
import com.tanpu.community.api.beans.vo.feign.fatools.UserInfoResp;
import com.tanpu.community.api.beans.vo.feign.course.ShortVideoBaseInfoResp;
import com.tanpu.community.api.beans.vo.feign.product.ProductInfoVO;
import com.tanpu.community.api.beans.vo.feign.zhibo.ZhiboListResp;
import com.tanpu.community.cache.LocalCache;
import com.tanpu.community.feign.course.FeignClientForCourse;
import com.tanpu.community.feign.fatools.FeignClientForFatools;
......@@ -76,6 +79,87 @@ public class FeignService {
});
}
public List<CourseSimpleResp> getCourseSimpleList(List<String> courseIds) {
return batchExecute("getCourseSimpleList_", courseIds, CourseSimpleResp.class,
CourseSimpleResp::getCourseId, ids -> {
CommonResp<List<CourseSimpleResp>> resp = feignForCourse.getCourseSimpleList(ids);
if (resp.isSuccess()) {
return resp.getData();
} else {
return new ArrayList<>();
}
});
}
public List<ZhiboListResp> getZhiboSimpleList(List<String> zhiboIds) {
return batchExecute("getZhiboSimpleList_", zhiboIds, ZhiboListResp.class,
ZhiboListResp::getId, ids -> {
CommonResp<List<ZhiboListResp>> resp = feignClientForZhibo.simpleList(ids);
if (resp.isSuccess()) {
return resp.getData();
} else {
return new ArrayList<>();
}
});
}
public List<UserInfoResp> getUserList(List<String> userIds) {
return batchExecute("getUserList_", userIds, UserInfoResp.class,
UserInfoResp::getUserId, ids -> {
return feignClientForFatools.queryUserListNew(ids);
});
}
public List<ProductInfoVO> getProductInfoByIds(List<String> fundIds) {
return batchExecute("getProductInfoByIds_", fundIds, ProductInfoVO.class,
ProductInfoVO::getFundId, ids -> {
CommonResp<List<ProductInfoVO>> resp = feignForProduct.getProductInfoByIds(ids);
if (resp.isSuccess()) {
return resp.getData();
} else {
return new ArrayList<>();
}
});
}
public List<ProductInfoVO> getFundList(List<String> fundIds) {
return batchExecute("getFundList", fundIds, ProductInfoVO.class,
ProductInfoVO::getFundId, ids -> {
CommonResp<List<ProductInfoVO>> resp = feignForFund.getProductList(ids);
if (resp.isSuccess()) {
return resp.getData();
} else {
return new ArrayList<>();
}
});
}
public List<ProductInfoVO> getPrivateFundList(List<String> fundIds) {
return batchExecute("getPrivateFundList", fundIds, ProductInfoVO.class,
ProductInfoVO::getFundId, ids -> {
CommonResp<List<ProductInfoVO>> resp = feignForFund.getPrivateFundList(ids);
if (resp.isSuccess()) {
return resp.getData();
} else {
return new ArrayList<>();
}
});
}
public List<ProductInfoVO> getPublicFundList(List<String> fundIds) {
return batchExecute("getPublicFundList", fundIds, ProductInfoVO.class,
ProductInfoVO::getFundId, ids -> {
CommonResp<List<ProductInfoVO>> resp = feignForPublicFund.getProductList(ids);
if (resp.isSuccess()) {
return resp.getData();
} else {
return new ArrayList<>();
}
});
}
private <T> List<T> batchExecute(String keyPrefix,
List<String> keys,
Class<T> clz,
......@@ -92,18 +176,20 @@ public class FeignService {
} else {
feignIds.add(key);
}
}
if (!feignIds.isEmpty()) {
List<T> remoteList = feignFunc.apply(feignIds);
// log.info("batchExecute feign returns {} -> {}", JSON.toJSONString(feignIds), JSON.toJSONString(remoteList));
if (!feignIds.isEmpty()) {
List<T> remoteList = feignFunc.apply(feignIds);
if (remoteList != null) {
retList.addAll(remoteList);
retList.forEach(r -> {
localCache.putObject(keyPrefix + getKeyFunc.apply(r), r);
});
}
if (remoteList != null) {
retList.addAll(remoteList);
retList.forEach(r -> {
localCache.putObject(keyPrefix + getKeyFunc.apply(r), r);
});
}
}
log.info("batchExecute {} : {} -> {}", keyPrefix, JSON.toJSONString(keys), JSON.toJSONString(retList));
// log.info("batchExecute {} : {} -> {}", keyPrefix, JSON.toJSONString(keys), JSON.toJSONString(retList));
return retList;
}
}
......@@ -10,6 +10,7 @@ import com.tanpu.community.cache.RedisCache;
import com.tanpu.community.dao.entity.community.ThemeEntity;
import com.tanpu.community.dao.entity.community.TopicEntity;
import com.tanpu.community.feign.fatools.FeignClientForFatools;
import com.tanpu.community.util.BizUtils;
import com.tanpu.community.util.ConvertUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
......@@ -120,10 +121,18 @@ public class RankService {
// 浏览量
Integer topicPV = countMapByTargetIds.getOrDefault(topic.getTopicId(), 0);
Integer themePV = visitLogService.queryThemeVisit(themeIds);
topic.setViewCount(topicPV + themePV);
topic.setViewCount(topicPV + themePV + topic.getViewCntAdjust());
//讨论数=发布主题贴数+回复总数
Integer commentCount = commentService.getTotalCountByThemeIds(themeIds);
topic.setDisscussCount(themeIds.size() + commentCount);
//帖子权重,求和
double themeSum = getHotestThemes().stream().filter(o -> topic.getTopicId().equals(o.getTopicId()))
.mapToDouble(ThemeAnalysDO::calcScore)
.sum();
topic.setThemeWeight((int) themeSum);
//格式化浏览量、讨论量
topic.setFormatViewCount(BizUtils.formatCountNumber(topic.getViewCount()));
topic.setFormatDisscussCount(BizUtils.formatCountNumber(topic.getDisscussCount()));
}
Map<TopicRankQo, Integer> map = topicRankQos.stream().collect(Collectors.toMap(o -> o, TopicRankQo::getRank));
List<TopicRankQo> rankList = map.entrySet().stream()
......
......@@ -240,6 +240,7 @@ public class ThemeService {
if (CollectionUtils.isEmpty(userIds)){
return Collections.emptyList();
}
//TODO 索引优化
LambdaQueryWrapper<ThemeEntity> queryWrapper = new LambdaQueryWrapper<ThemeEntity>()
.in(ThemeEntity::getAuthorId, userIds)
.last("limit " + pageStart + ", " + pageSize)
......
......@@ -8,6 +8,7 @@ import com.tanpu.community.api.beans.qo.ThemeQo;
import com.tanpu.community.dao.entity.community.ThemeEntity;
import com.tanpu.community.model.ESWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
......@@ -45,12 +46,17 @@ public class ESService {
SearchSourceBuilder search = new SearchSourceBuilder();
BoolQueryBuilder boolQb = QueryBuilders.boolQuery();
MatchPhraseQueryBuilder contentQb = QueryBuilders.matchPhraseQuery("textContent", keyword);
MatchPhraseQueryBuilder titleQb = QueryBuilders.matchPhraseQuery("title", keyword);
boolQb.should(contentQb);
boolQb.should(titleQb);
String[] includes = new String[]{"id", "themeId", "createTime"};
// 如果关键词带空格,则拆分
String[] ks = StringUtils.split(keyword, ' ');
for (String k : ks) {
MatchPhraseQueryBuilder contentQb = QueryBuilders.matchPhraseQuery("textContent", k);
MatchPhraseQueryBuilder titleQb = QueryBuilders.matchPhraseQuery("title", k);
boolQb.should(contentQb);
boolQb.should(titleQb);
}
String[] includes = new String[]{"id", "themeId", "createTime", "_score"};
String[] excludes = new String[]{};
search.query(boolQb).fetchSource(includes, excludes).sort("createTime", SortOrder.DESC).from(from).size(size);
search.query(boolQb).sort("createTime", SortOrder.DESC).from(from).size(size);
......
package com.tanpu.community.util;
import com.alibaba.fastjson.JSON;
import com.tanpu.community.api.beans.qo.ThemeContentQo;
import com.tanpu.community.api.beans.qo.ThemeQo;
import com.tanpu.community.api.enums.RelTypeEnum;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
......@@ -37,4 +35,19 @@ public class BizUtils {
}
return "";
}
public static String formatCountNumber(Integer number) {
if (number < 10000) {
return number.toString();
} else {
double d = number * 1.0 / 10000;
return String.format("%.1f",d)+"w";
}
}
public static void main(String[] args) {
System.out.println(formatCountNumber(110400));
System.out.println(formatCountNumber(111100));
System.out.println(formatCountNumber(1000));
}
}
......@@ -10,12 +10,21 @@ import java.util.stream.Collectors;
public class RankUtils {
/**
* 根据id排序主题对象
* @param list 主题
* @param ids 主题Id,list中可重复
* @return
*/
public static List<ThemeEntity> sortThemeEntityByIds(List<ThemeEntity> list, List<String> ids){
int count=0;
HashMap<String, Integer> indexMap = new HashMap<>();
for (String id : ids) {
indexMap.put(id,count++);
//list中出现重复元素时,优化取第一次出现的顺序
if (!indexMap.containsKey(id)){
indexMap.put(id,count++);
}
}
List<ThemeEntity> collect = list.stream().filter(o -> indexMap.containsKey(o.getThemeId()))
.sorted(Comparator.comparingInt(o -> indexMap.get(o.getThemeId())))
......
......@@ -29,10 +29,12 @@ public class TimeUtils {
return duration + "分钟前";
} else if (duration < 60 * 24) {
return duration / 60 + "小时前";
} else if (start.getYear() == LocalDateTime.now().getYear()) {
return start.format(DateTimeFormatter.ofPattern("MM-dd HH:mm:ss"));
} else if (duration < 60 * 48) {
return "1天前";
} else if (duration < 60 * 24 * 180) {
return start.format(DateTimeFormatter.ofPattern("MM-dd HH:mm"));
}
return start.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
return start.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
}
//计算迄今时间
......@@ -43,8 +45,17 @@ public class TimeUtils {
//计算n天前的时间
public static LocalDateTime getDaysBefore(Integer number){
public static LocalDateTime getDaysBefore(Integer number) {
return LocalDateTime.now().minusDays(number);
}
public static void main(String[] args) {
System.out.println(calUpToNowTime(LocalDateTime.now().minusDays(180)));
System.out.println(calUpToNowTime(LocalDateTime.now().minusDays(1)));
System.out.println(calUpToNowTime(LocalDateTime.now().minusDays(18)));
System.out.println(calUpToNowTime(LocalDateTime.now().minusHours(2)));
System.out.println(calUpToNowTime(LocalDateTime.now().minusMinutes(12)));
System.out.println(calUpToNowTime(LocalDateTime.now().minusSeconds(12)));
}
}
......@@ -79,7 +79,7 @@ es:
port: 9200
userName: 1
userPasswd: 2
index: dev
index: new-community
tencent:
cloud:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment