Commit 5d1635a6 authored by 刘基明's avatar 刘基明

全局搜索

parent 686ce025
package com.tanpu.community.api.beans.qo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("评论概要")
public class CommentSimpleQo {
@ApiModelProperty(value = "uuid")
private String commentId;
@ApiModelProperty(value = "文本内容")
private String content;
@ApiModelProperty(value = "作者id")
private String authorId;
@ApiModelProperty(value = "作者昵称")
private String nickName;
}
package com.tanpu.community.api.beans.qo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel("讨论区")
public class DiscussionAeraQo {
@ApiModelProperty(value = "话题ID")
private String topicId;
@ApiModelProperty(value = "话题名称")
private String topicTitle;
@ApiModelProperty(value = "讨论量")
private Integer disscussCount;
@ApiModelProperty(value = "讨论量-格式化,超过99条的显示99+")
private String formatDisscussCount;
@ApiModelProperty(value = "是否专属 0否,1是")
private Integer specialPermission;
@ApiModelProperty(value = "是否有权限")
private boolean hasPermission;
@ApiModelProperty(value = "讨论帖")
private List<ThemeSimpleQo> themes;
}
......@@ -83,6 +83,12 @@ public class ThemeQo implements Serializable {
@ApiModelProperty(value = "当前用户是否收藏")
private boolean hasCollect;
@ApiModelProperty(value = "是否讨论区管理员,讨论区中使用")
private boolean isManager;
@ApiModelProperty(value = "最新评论")
private List<CommentSimpleQo> recentComments;
@ApiModelProperty(value = "图片九宫格")
public List<ImagesDTO> imgList;
......
package com.tanpu.community.api.beans.qo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@ApiModel("讨论区讨论")
public class ThemeSimpleQo {
@ApiModelProperty(value = "uuid")
private String themeId;
@ApiModelProperty(value = "作者id")
private String authorId;
@ApiModelProperty(value = "作者昵称")
private String nickName;
@ApiModelProperty(value = "作者头像")
private String userImg;
@ApiModelProperty(value = "文本内容")
private String content;
@ApiModelProperty(value = "评论时间")
private LocalDateTime updateTime;
@ApiModelProperty(value = "评论时间,格式化")
private String commentTime;
}
......@@ -2,6 +2,7 @@ package com.tanpu.community.api.beans.resp;
import com.tanpu.community.api.beans.qo.FollowQo;
import com.tanpu.community.api.beans.qo.ThemeQo;
import com.tanpu.community.api.beans.qo.TopicRankQo;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
......@@ -19,8 +20,11 @@ public class ThemeAndUserSearchResp {
public List<FollowQo> users;
public List<TopicRankQo> topics;
public ThemeAndUserSearchResp() {
this.themes = new ArrayList<>();
this.users = new ArrayList<>();
this.topics = new ArrayList<>();
}
}
......@@ -3,15 +3,16 @@ package com.tanpu.community.controller;
import com.tanpu.common.api.CommonResp;
import com.tanpu.common.auth.UserHolder;
import com.tanpu.community.api.beans.qo.FollowQo;
import com.tanpu.community.api.beans.qo.TopicRankQo;
import com.tanpu.community.api.beans.req.search.ThemeFullSearchReq;
import com.tanpu.community.api.beans.resp.ThemeAndUserSearchResp;
import com.tanpu.community.api.beans.resp.ThemeFullSearchResp;
import com.tanpu.community.api.beans.resp.UserSearchResp;
import com.tanpu.community.manager.HomePageManager;
import com.tanpu.community.manager.ThemeManager;
import com.tanpu.community.manager.TopicManager;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
......@@ -29,14 +30,17 @@ public class SearchController {
@Resource
private UserHolder userHolder;
@Autowired
@Resource
private ThemeManager themeManager;
@Autowired
@Resource
private HomePageManager homePageManager;
@Resource
private TopicManager topicManager;
// 内容全文搜索
@ApiOperation("全文搜索主题")
@ApiOperation("帖子全文搜索")
@PostMapping(value = "/themeFullText")
@ResponseBody
public CommonResp<ThemeFullSearchResp> themeFullText(@RequestBody ThemeFullSearchReq req) {
......@@ -44,15 +48,17 @@ public class SearchController {
return CommonResp.success(resp);
}
// 用户+内容全文搜索
// 用户+内容全文+话题搜索
@ApiOperation("综合搜索")
@PostMapping(value = "/muLtipuleSearch")
@ResponseBody
public CommonResp<ThemeAndUserSearchResp> themeFullTextAndUserSearch(@RequestBody ThemeFullSearchReq req) {
ThemeFullSearchResp themeFullSearch = themeManager.themeFullSearch(req.keyword, req.page.pageNumber, req.page.pageSize, req.ident, userHolder.getUserId());
List<FollowQo> users = homePageManager.userNameSerach(req.keyword, 1, 3, req.ident, userHolder.getUserId());
List<TopicRankQo> topics = topicManager.getTopicRankList(req.getKeyword());
return CommonResp.success(ThemeAndUserSearchResp.builder().themes(themeFullSearch.getThemes()).users(users).build());
return CommonResp.success(ThemeAndUserSearchResp.builder().themes(themeFullSearch.getThemes()).users(users).topics(topics).build());
}
// 用户搜索
......
......@@ -3,6 +3,7 @@ package com.tanpu.community.controller;
import com.tanpu.common.api.CommonResp;
import com.tanpu.common.auth.AuthLogin;
import com.tanpu.common.auth.UserHolder;
import com.tanpu.community.api.beans.qo.DiscussionAeraQo;
import com.tanpu.community.api.beans.qo.TopicFollowQo;
import com.tanpu.community.api.beans.qo.TopicPageDetailQo;
import com.tanpu.community.api.beans.qo.TopicRankQo;
......@@ -67,10 +68,17 @@ public class TopicController {
@AuthLogin
@PostMapping(value = "/follow")
@ApiOperation("关注话题(讨论区)")
@ApiOperation("关注话题(讨论区),动作")
public CommonResp<Void> follow(@RequestBody FollowTopicReq req) {
topicManager.followTopic(req, userHolder.getUserId());
return CommonResp.success();
}
@GetMapping(value = "/inner/discussion")
@ApiOperation("讨论区,课程(基金)介绍用")
public CommonResp<DiscussionAeraQo> getForum() {
return CommonResp.success(topicManager.getForum());
}
}
......@@ -544,6 +544,17 @@ public class ThemeManager {
ThemeListResp resp = new ThemeListResp();
resp.themes = convertEntityToQo(themes, req.getUserId());
// 最新3条评论
// todo 测试性能
commentService.queryRecentComments(resp.themes);
// 讨论区添加是否管理员
if (ThemeListTypeEnum.TOPIC_LATEST.getCode().equals(req.getType())
|| ThemeListTypeEnum.TOPIC_HOT.getCode().equals(req.getType())) {
topicService.checkManager(req.getTopicId(),resp.themes);
}
// 保存缓存、记录已浏览
excludeIds.addAll(resp.themes.stream().map(ThemeQo::getThemeId).collect(Collectors.toList()));
redisCache.put("queryThemes_" + req.ident, excludeIds, 60 * 60 * 6);
......@@ -692,7 +703,7 @@ public class ThemeManager {
});
redisCache.put(StringUtils.joinWith("_", CACHE_FEIGN_USER_INFO, userId), user, 60);
}
commentService.queryRecentComments(themeQos);
return themeQos;
}
......
......@@ -3,6 +3,7 @@ package com.tanpu.community.manager;
import com.tanpu.common.api.CommonResp;
import com.tanpu.common.auth.UserHolder;
import com.tanpu.common.constant.ErrorCodeConstant;
import com.tanpu.community.api.beans.qo.DiscussionAeraQo;
import com.tanpu.community.api.beans.qo.TopicFollowQo;
import com.tanpu.community.api.beans.qo.TopicPageDetailQo;
import com.tanpu.community.api.beans.qo.TopicRankQo;
......@@ -17,6 +18,7 @@ import com.tanpu.community.service.RankService;
import com.tanpu.community.service.ThemeService;
import com.tanpu.community.service.TopicService;
import com.tanpu.community.util.PageUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
......@@ -48,8 +50,7 @@ public class TopicManager {
return rankService.getRankTopicListTop4();
}
// 话题搜索列表
// 话题列表
public Page<TopicRankQo> getAllTopicBriefInfo(TopicSearchReq req) {
// 全量排序,内存分页
List<TopicRankQo> topicList = rankService.getRankTopicList(req.getSearchKeyword());
......@@ -59,6 +60,18 @@ public class TopicManager {
return result;
}
// 关键字搜索话题(前2个)
public List<TopicRankQo> getTopicRankList(String keyword) {
// 全量排序,内存分页
List<TopicRankQo> topicList = rankService.getRankTopicList(keyword);
if (CollectionUtils.isEmpty(topicList)) return topicList;
// 只取前两条
if (topicList.size() > 2) topicList = topicList.subList(0, 1);
// 添加权限
topicService.batchCheckPermission(topicList, userHolder.getUserId());
return topicList;
}
/**
* 关注话题(讨论区)列表
*
......@@ -153,5 +166,9 @@ public class TopicManager {
}
return CommonResp.success();
}
public DiscussionAeraQo getForum() {
return null;
}
}
......@@ -6,20 +6,24 @@ import com.tanpu.biz.common.enums.community.CommentTypeEnum;
import com.tanpu.biz.common.enums.community.ReportStatusEnum;
import com.tanpu.common.exception.BizException;
import com.tanpu.common.uuid.UuidGenHelper;
import com.tanpu.community.api.beans.qo.ThemeQo;
import com.tanpu.community.api.beans.req.theme.ForwardThemeReq;
import com.tanpu.community.api.beans.vo.feign.fatools.UserInfoResp;
import com.tanpu.community.api.enums.DeleteTagEnum;
import com.tanpu.community.cache.RedisCache;
import com.tanpu.community.dao.entity.community.CommentEntity;
import com.tanpu.community.dao.entity.community.TimesCountEntity;
import com.tanpu.community.dao.mapper.community.CommentMapper;
import com.tanpu.community.util.ConvertUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
......@@ -32,11 +36,13 @@ public class CommentService {
@Resource
private CommentMapper commentMapper;
@Autowired
@Resource
private UuidGenHelper uuidGenHelper;
@Autowired
@Resource
private RedisCache redisCache;
@Resource
private FeignService feignService;
@Transactional
public void insertComment(CommentEntity commentEntity) {
......@@ -75,7 +81,7 @@ public class CommentService {
//统计主题集合的评论量
public Map<String, Integer> getCountMapByThemeIds(List<String> themeIds) {
if (CollectionUtils.isEmpty(themeIds)){
if (CollectionUtils.isEmpty(themeIds)) {
return new HashMap<>();
}
LambdaQueryWrapper<CommentEntity> wrapper = (new LambdaQueryWrapper<CommentEntity>()
......@@ -86,6 +92,12 @@ public class CommentService {
.collect(Collectors.toMap(TimesCountEntity::getId, TimesCountEntity::getTimes));
}
/**
* 获取单个帖子的所有评论
*
* @param themeId
* @return
*/
public List<CommentEntity> selectByThemeId(String themeId) {
return redisCache.getList(StringUtils.joinWith("_", CACHE_COMMENT_THEMEID, themeId),
60, () -> {
......@@ -99,7 +111,6 @@ public class CommentService {
}
public List<CommentEntity> queryCommentsByUserId(String userId, String lastId, Integer pageSize) {
LambdaQueryWrapper<CommentEntity> queryWrapper = new LambdaQueryWrapper<CommentEntity>()
.eq(CommentEntity::getAuthorId, userId)
......@@ -135,8 +146,8 @@ public class CommentService {
@Transactional
public void delete(String commentId, String userId) {
CommentEntity commentEntity = this.queryByIdIncludeDelete(commentId);
if (commentEntity==null || !commentEntity.getAuthorId().equals(userId)){
throw new BizException("删除评论与用户不匹配,commentId:"+commentId+",userId:"+userId);
if (commentEntity == null || !commentEntity.getAuthorId().equals(userId)) {
throw new BizException("删除评论与用户不匹配,commentId:" + commentId + ",userId:" + userId);
}
commentEntity.setDeleteTag(DeleteTagEnum.DELETED.getCode());
commentMapper.updateById(commentEntity);
......@@ -145,7 +156,7 @@ public class CommentService {
}
// 失效关联主题缓存
private void evictThemeCache(String themeId){
private void evictThemeCache(String themeId) {
// 评论内容
redisCache.evict(StringUtils.joinWith("_", CACHE_COMMENT_THEMEID, themeId));
// 主题内容
......@@ -156,12 +167,12 @@ public class CommentService {
public List<CommentEntity> queryAll() {
return commentMapper.selectList(new LambdaQueryWrapper<CommentEntity>()
.eq(CommentEntity::getDeleteTag,DeleteTagEnum.NOT_DELETED.getCode())
.eq(CommentEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode())
.orderByAsc(CommentEntity::getCreateTime));
}
public CommentEntity queryByCommentId(String commentId) {
return commentMapper.selectOne(new LambdaQueryWrapper<CommentEntity>().eq(CommentEntity::getCommentId,commentId));
return commentMapper.selectOne(new LambdaQueryWrapper<CommentEntity>().eq(CommentEntity::getCommentId, commentId));
}
public String forwardSyncComment(ForwardThemeReq req, String userId) {
......@@ -179,4 +190,25 @@ public class CommentService {
}
public void queryRecentComments(List<ThemeQo> themes) {
List<String> themeIds = themes.stream().map(ThemeQo::getThemeId).collect(Collectors.toList());
List<CommentEntity> commentEntities = commentMapper.selectList(new LambdaQueryWrapper<CommentEntity>()
.in(CommentEntity::getThemeId, themeIds)
.orderByDesc(CommentEntity::getCreateTime));
LinkedHashMap<String, List<CommentEntity>> collect = commentEntities.stream().collect(Collectors.groupingBy(CommentEntity::getThemeId, LinkedHashMap::new, Collectors.toList()));
// 查询用户信息
List<String> authorIds = new ArrayList<>(commentEntities.stream().map(CommentEntity::getAuthorId).collect(Collectors.toSet()));
List<UserInfoResp> queryUsersListNew = feignService.getUserList(authorIds);
Map<String, String> nameMap = queryUsersListNew.stream().collect(Collectors.toMap(UserInfoResp::getUserId, UserInfoResp::getNickName));
for (ThemeQo theme : themes) {
if (collect.containsKey(theme.getThemeId())) {
List<CommentEntity> comments = collect.get(theme.getThemeId());
theme.setRecentComments(ConvertUtil.comment2Simple(comments,nameMap));
}
}
}
}
......@@ -2,6 +2,7 @@ package com.tanpu.community.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tanpu.common.uuid.UuidGenHelper;
import com.tanpu.community.api.beans.qo.ThemeQo;
import com.tanpu.community.api.beans.qo.TopicAttachement;
import com.tanpu.community.api.beans.qo.TopicFollowQo;
import com.tanpu.community.api.beans.qo.TopicPageDetailQo;
......@@ -180,4 +181,17 @@ public class TopicService {
TopicFollowRelEntity topicFollowRelEntity = topicFollowRelMapper.queryOneByTopicIdAndUserId(topicId, userId);
return topicFollowRelEntity != null;
}
public void checkManager(String topicId, List<ThemeQo> themes) {
String managerId = getManagerId(topicId);
for (ThemeQo theme : themes) {
theme.setManager(theme.getAuthorId().equals(managerId));
}
}
public String getManagerId(String topicId) {
return "123";
}
}
......@@ -24,6 +24,7 @@ import com.tanpu.community.dao.entity.community.ThemeAttachmentEntity;
import com.tanpu.community.dao.entity.community.ThemeEntity;
import com.tanpu.community.dao.entity.community.TopicEntity;
import com.tanpu.community.dao.entity.community.VisitLogEntity;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
......@@ -124,9 +125,9 @@ public class ConvertUtil {
topicRankQo.setType(TopicStatusEnum.NEWEST.getCode());
}
// 根据是否专属设置默认权限
if (TopicSpecialPermissionEnum.FALSE.getCode().equals(topicEntity.getSpecialPermission())){
if (TopicSpecialPermissionEnum.FALSE.getCode().equals(topicEntity.getSpecialPermission())) {
topicRankQo.setHasPermission(true);
}else {
} else {
topicRankQo.setHasPermission(false);
}
topicRankQo.setMinutesTillNow((int) TimeUtils.calMinuteTillNow(topicEntity.getCreateTime()));
......@@ -160,7 +161,7 @@ public class ConvertUtil {
BeanUtils.copyProperties(entity, qo);
qo.setContent(OtherUtil.blockPhoneAndEmail(entity.getContent()));
qo.setUpdateTime(TimeUtils.getTimestampOfDateTime(entity.getUpdateTime()));
if (StringUtils.isBlank(entity.getReplyUserId())){
if (StringUtils.isBlank(entity.getReplyUserId())) {
qo.setReplyUserId(null);
}
return qo;
......@@ -360,4 +361,14 @@ public class ConvertUtil {
}
public static List<CommentSimpleQo> comment2Simple(List<CommentEntity> comments, Map<String, String> nameMap) {
if (CollectionUtils.isEmpty(comments)) return null;
return comments.stream().map(o -> {
CommentSimpleQo commentSimpleQo = new CommentSimpleQo();
BeanUtils.copyProperties(o, commentSimpleQo);
commentSimpleQo.setNickName(nameMap.getOrDefault(commentSimpleQo.getAuthorId(), "探普用户"));
return commentSimpleQo;
}).collect(Collectors.toList());
}
}
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