Commit 3d002630 authored by 吴泽佳's avatar 吴泽佳
parents a44cf3e9 f7dcb998
...@@ -50,7 +50,7 @@ public class ThemeAnalysDO { ...@@ -50,7 +50,7 @@ public class ThemeAnalysDO {
private Double userWeight = 0.0; private Double userWeight = 0.0;
public Double getScore() { public Double calcScore() {
//质量=帖子质量+用户质量 //质量=帖子质量+用户质量
double w = (double) (viewCount * 0.1 + forwardCount * 3 + commentCount * 2 + likeCount * 1 + collectCount * 3) + userWeight; double w = (double) (viewCount * 0.1 + forwardCount * 3 + commentCount * 2 + likeCount * 1 + collectCount * 3) + userWeight;
double i = 1;//初试权重 double i = 1;//初试权重
......
...@@ -4,6 +4,8 @@ import io.swagger.annotations.ApiModel; ...@@ -4,6 +4,8 @@ import io.swagger.annotations.ApiModel;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotEmpty;
@Data @Data
@Builder @Builder
@ApiModel(value = "分页") @ApiModel(value = "分页")
...@@ -15,8 +17,10 @@ public class Pageable { ...@@ -15,8 +17,10 @@ public class Pageable {
public static final Integer DEFAULT_PAGE_NUMBER = 0; public static final Integer DEFAULT_PAGE_NUMBER = 0;
@NotEmpty(message = "分页Number不能为空")
public Integer pageNumber = DEFAULT_PAGE_NUMBER; public Integer pageNumber = DEFAULT_PAGE_NUMBER;
@NotEmpty(message = "分页pageSize不能为空")
public Integer pageSize = DEFAULT_PAGE_SIZE; public Integer pageSize = DEFAULT_PAGE_SIZE;
public Pageable() { public Pageable() {
......
package com.tanpu.community.api.beans.req.theme; package com.tanpu.community.api.beans.req.theme;
import com.tanpu.community.api.beans.req.page.Pageable;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.util.List;
@Data @Data
public class ThemeListReq { public class ThemeListReq {
...@@ -12,20 +14,16 @@ public class ThemeListReq { ...@@ -12,20 +14,16 @@ public class ThemeListReq {
@NotNull(message = "主题类型不能为空") @NotNull(message = "主题类型不能为空")
@ApiModelProperty(value = "类型,1:推荐 2:关注 3:话题-热门 4:话题-最新") @ApiModelProperty(value = "类型,1:推荐 2:关注 3:话题-热门 4:话题-最新")
private Integer type; public Integer type;
@ApiModelProperty(value = "话题Id") @ApiModelProperty(value = "话题Id")
private String topicId; public String topicId;
@ApiModelProperty(value = "当前浏览的最后一个themeId,可以为空") @ApiModelProperty(value = "当前浏览的最后一个themeId,可以为空")
private String lastId=""; public String lastId="";
@NotNull(message = "PageSize不能为空")
@ApiModelProperty(value = "页面大小")
private Integer pageSize;
@NotNull(message = "分页")
public Pageable page;
public List<String> excludeIds;
} }
package com.tanpu.community.api.beans.resp;
import com.tanpu.community.api.beans.qo.ThemeQo;
import lombok.Data;
import java.util.List;
@Data
public class ThemeListResp {
public List<ThemeQo> themes;
public List<String> excludeIds;
}
package com.tanpu.community.config; package com.tanpu.community.config;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.auth.UsernamePasswordCredentials;
...@@ -17,6 +18,7 @@ import org.springframework.context.annotation.Bean; ...@@ -17,6 +18,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Slf4j
@Data @Data
@Component @Component
@ConfigurationProperties(prefix = "es") @ConfigurationProperties(prefix = "es")
...@@ -33,12 +35,14 @@ public class ESConfig { ...@@ -33,12 +35,14 @@ public class ESConfig {
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, userPasswd)); credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, userPasswd));
RestHighLevelClient restHighLevelClient = new RestHighLevelClient( RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
RestClient.builder(new HttpHost(host, port)).setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() { RestClient.builder(new HttpHost(host, port, "http")).setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override @Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider); return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
} }
})); }));
log.info("es client created. addr: {}:{}, userName: {}", host, port, userName);
return restHighLevelClient; return restHighLevelClient;
} }
} }
...@@ -22,7 +22,6 @@ public class MetricsController { ...@@ -22,7 +22,6 @@ public class MetricsController {
@ApiOperation("浏览话题") @ApiOperation("浏览话题")
@GetMapping("/view/topic") @GetMapping("/view/topic")
public CommonResp pageViewTopic(@RequestParam String topicId){ public CommonResp pageViewTopic(@RequestParam String topicId){
visitSummaryManager.addTopicPageView(topicId);
return CommonResp.success(); return CommonResp.success();
} }
...@@ -30,7 +29,6 @@ public class MetricsController { ...@@ -30,7 +29,6 @@ public class MetricsController {
@ApiOperation("浏览主题") @ApiOperation("浏览主题")
@GetMapping("/view/theme") @GetMapping("/view/theme")
public CommonResp pageViewTheme(@RequestParam String themeId){ public CommonResp pageViewTheme(@RequestParam String themeId){
visitSummaryManager.addFollowThemeView(themeId);
return CommonResp.success(); return CommonResp.success();
} }
...@@ -38,7 +36,6 @@ public class MetricsController { ...@@ -38,7 +36,6 @@ public class MetricsController {
@ApiOperation("浏览关注主题") @ApiOperation("浏览关注主题")
@GetMapping("/view/follow") @GetMapping("/view/follow")
public CommonResp pageViewTheme(){ public CommonResp pageViewTheme(){
visitSummaryManager.addFollowThemeView();
return CommonResp.success(); return CommonResp.success();
} }
......
...@@ -7,6 +7,7 @@ import com.tanpu.common.auth.UserHolder; ...@@ -7,6 +7,7 @@ import com.tanpu.common.auth.UserHolder;
import com.tanpu.community.api.beans.qo.ThemeQo; import com.tanpu.community.api.beans.qo.ThemeQo;
import com.tanpu.community.api.beans.req.theme.*; import com.tanpu.community.api.beans.req.theme.*;
import com.tanpu.community.api.beans.resp.CreateThemeResp; import com.tanpu.community.api.beans.resp.CreateThemeResp;
import com.tanpu.community.api.beans.resp.ThemeListResp;
import com.tanpu.community.cache.RedisCache; import com.tanpu.community.cache.RedisCache;
import com.tanpu.community.manager.ThemeManager; import com.tanpu.community.manager.ThemeManager;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
...@@ -43,9 +44,9 @@ public class ThemeController { ...@@ -43,9 +44,9 @@ public class ThemeController {
@ApiOperation("主题列表-推荐/关注/热门/最新") @ApiOperation("主题列表-推荐/关注/热门/最新")
@PostMapping(value = "/list") @PostMapping(value = "/list")
@ResponseBody @ResponseBody
public CommonResp<List<ThemeQo>> selectInterestList(@Validated @RequestBody ThemeListReq req) { public CommonResp<ThemeListResp> selectInterestList(@Validated @RequestBody ThemeListReq req) {
String userId = userHolder.getUserId(); String userId = userHolder.getUserId();
List<ThemeQo> result = themeManager.queryThemes(req, userId); ThemeListResp result = themeManager.queryThemes(req, userId);
return CommonResp.success(result); return CommonResp.success(result);
} }
......
package com.tanpu.community.dao.entity.community;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class TimesCountEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "次数")
private Integer times;
@ApiModelProperty(value = "目标id")
private String id;
}
package com.tanpu.community.dao.mapper.community; package com.tanpu.community.dao.mapper.community;
import com.tanpu.community.dao.entity.community.CollectionEntity; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.tanpu.community.dao.entity.community.CollectionEntity;
import com.tanpu.community.dao.entity.community.TimesCountEntity;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/** /**
* <p> * <p>
...@@ -13,4 +20,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; ...@@ -13,4 +20,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
*/ */
public interface CollectionMapper extends BaseMapper<CollectionEntity> { public interface CollectionMapper extends BaseMapper<CollectionEntity> {
@Select("select target_id as id, count(1) as times from collection ${ew.customSqlSegment}")
List<TimesCountEntity> selectCountByTargetIds(@Param(Constants.WRAPPER) LambdaQueryWrapper wrapper);
} }
package com.tanpu.community.dao.mapper.community; package com.tanpu.community.dao.mapper.community;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.tanpu.community.dao.entity.community.CommentEntity; import com.tanpu.community.dao.entity.community.CommentEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tanpu.community.dao.entity.community.TimesCountEntity;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/** /**
* <p> * <p>
...@@ -13,4 +20,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; ...@@ -13,4 +20,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
*/ */
public interface CommentMapper extends BaseMapper<CommentEntity> { public interface CommentMapper extends BaseMapper<CommentEntity> {
@Select("select theme_id as id, count(1) as times from comment ${ew.customSqlSegment}")
List<TimesCountEntity> selectCountByThemeIds(@Param(Constants.WRAPPER) LambdaQueryWrapper wrapper);
} }
package com.tanpu.community.dao.mapper.community; package com.tanpu.community.dao.mapper.community;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.tanpu.community.dao.entity.community.ThemeEntity; import com.tanpu.community.dao.entity.community.ThemeEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tanpu.community.dao.entity.community.TimesCountEntity;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/** /**
* <p> * <p>
...@@ -13,4 +20,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; ...@@ -13,4 +20,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
*/ */
public interface ThemeMapper extends BaseMapper<ThemeEntity> { public interface ThemeMapper extends BaseMapper<ThemeEntity> {
@Select("select former_theme_id as id, count(1) as times from theme ${ew.customSqlSegment}")
List<TimesCountEntity> selectCountByThemeIds(@Param(Constants.WRAPPER) LambdaQueryWrapper wrapper);
} }
package com.tanpu.community.dao.mapper.community; package com.tanpu.community.dao.mapper.community;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.tanpu.community.dao.entity.community.TimesCountEntity;
import com.tanpu.community.dao.entity.community.VisitSummaryEntity; import com.tanpu.community.dao.entity.community.VisitSummaryEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
...@@ -25,4 +28,7 @@ public interface VisitSummaryMapper extends BaseMapper<VisitSummaryEntity> { ...@@ -25,4 +28,7 @@ public interface VisitSummaryMapper extends BaseMapper<VisitSummaryEntity> {
@Select("select ref_id from visit_summary where visitor_id=#{visitorId} and ref_id in (#{refIds})") @Select("select ref_id from visit_summary where visitor_id=#{visitorId} and ref_id in (#{refIds})")
List<String> selectRefIdByUserId(@Param("visitorId") String visitorId, @Param("refIds") String refIds); List<String> selectRefIdByUserId(@Param("visitorId") String visitorId, @Param("refIds") String refIds);
@Select("select ref_id as id, count(1) as times from visit_summary ${ew.customSqlSegment}")
List<TimesCountEntity> selectCountByThemeIds(@Param(Constants.WRAPPER)LambdaQueryWrapper wrapper);
} }
...@@ -109,7 +109,7 @@ public class CommentManager { ...@@ -109,7 +109,7 @@ public class CommentManager {
//点赞评论/取消点赞 //点赞评论/取消点赞
public void likeComment(LikeCommentReq req, String userId) { public void likeComment(LikeCommentReq req, String userId) {
if (OperationTypeEnum.CONFIRM.getCode().equals(req.getType())) { if (OperationTypeEnum.CONFIRM.getCode().equals(req.getType())) {
collectionService.addIfNotExist(req.getCommentId(), userId, CollectionTypeEnum.LIKE_COMMENT); collectionService.saveOrUpdate(req.getCommentId(), userId, CollectionTypeEnum.LIKE_COMMENT);
} else if (OperationTypeEnum.CANCEL.getCode().equals(req.getType())) { } else if (OperationTypeEnum.CANCEL.getCode().equals(req.getType())) {
collectionService.delete(req.getCommentId(), userId, CollectionTypeEnum.LIKE_COMMENT); collectionService.delete(req.getCommentId(), userId, CollectionTypeEnum.LIKE_COMMENT);
} }
......
package com.tanpu.community.manager; package com.tanpu.community.manager;
import com.tanpu.common.auth.UserHolder; import com.tanpu.common.auth.UserHolder;
import com.tanpu.common.exception.BizException;
import com.tanpu.community.api.beans.qo.TopicRankQo; import com.tanpu.community.api.beans.qo.TopicRankQo;
import com.tanpu.community.api.beans.req.page.Page; import com.tanpu.community.api.beans.req.page.Page;
import com.tanpu.community.api.beans.req.topic.TopicSearchReq; import com.tanpu.community.api.beans.req.topic.TopicSearchReq;
import com.tanpu.community.api.enums.VisitTypeEnum; import com.tanpu.community.api.enums.VisitTypeEnum;
import com.tanpu.community.service.*; import com.tanpu.community.service.RankService;
import com.tanpu.community.service.TopicService;
import com.tanpu.community.service.VisitSummaryService;
import com.tanpu.community.util.PageUtils; import com.tanpu.community.util.PageUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -28,14 +29,6 @@ public class TopicManager { ...@@ -28,14 +29,6 @@ public class TopicManager {
@Resource @Resource
private UserHolder userHolder; private UserHolder userHolder;
// 新增话题
public void insertTopic(String topicTitle, String userId) {
if (topicService.queryByTitile(topicTitle) == null) {
throw new BizException("话题名称已存在:" + topicTitle);
}
topicService.addTopic(topicTitle, userId);
}
// 首页-话题标签 // 首页-话题标签
public List<TopicRankQo> getTop4TopicTitles() { public List<TopicRankQo> getTop4TopicTitles() {
...@@ -52,7 +45,7 @@ public class TopicManager { ...@@ -52,7 +45,7 @@ public class TopicManager {
// 话题详情页 // 话题详情页
public TopicRankQo getDetail(String topicId) { public TopicRankQo getDetail(String topicId) {
//话题详情 //TODO 临时埋点,接入新埋点后删除
visitSummaryService.addPageView(userHolder.getUserId(), topicId, VisitTypeEnum.TOPIC_PAGE_VIEW); visitSummaryService.addPageView(userHolder.getUserId(), topicId, VisitTypeEnum.TOPIC_PAGE_VIEW);
return rankService.getTopicDetail(topicId); return rankService.getTopicDetail(topicId);
} }
......
package com.tanpu.community.manager; package com.tanpu.community.manager;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.tanpu.common.auth.UserHolder;
import com.tanpu.community.api.beans.vo.KafkaDurationUptMsg; import com.tanpu.community.api.beans.vo.KafkaDurationUptMsg;
import com.tanpu.community.api.enums.VisitTypeEnum;
import com.tanpu.community.dao.entity.community.VisitSummaryEntity; import com.tanpu.community.dao.entity.community.VisitSummaryEntity;
import com.tanpu.community.service.VisitSummaryService; import com.tanpu.community.service.VisitSummaryService;
import com.tanpu.community.util.ConvertUtil; import com.tanpu.community.util.ConvertUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.common.recycler.Recycler;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener; import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Slf4j @Slf4j
@Service @Service
public class VisitSummaryManager { public class VisitSummaryManager {
...@@ -28,31 +23,13 @@ public class VisitSummaryManager { ...@@ -28,31 +23,13 @@ public class VisitSummaryManager {
@Autowired @Autowired
private VisitSummaryService visitSummaryService; private VisitSummaryService visitSummaryService;
@Autowired
private UserHolder userHolder;
@KafkaListener(topics = kafakTopic) @KafkaListener(topics = kafakTopic)
public void updateVisitSummary(String message) { public void updateVisitSummary(String message) {
log.info("receive kafka msg: {}", message);
KafkaDurationUptMsg msg = JSON.parseObject(message, KafkaDurationUptMsg.class); KafkaDurationUptMsg msg = JSON.parseObject(message, KafkaDurationUptMsg.class);
// ident在每次进入新页面 & 回退 的时候都会随机生成一个,所以用ident做唯一key即可。 // ident在每次进入新页面 & 回退 的时候都会随机生成一个,所以用ident做唯一key即可。
VisitSummaryEntity vs = ConvertUtil.convertFromKafka(msg); VisitSummaryEntity vs = ConvertUtil.convertFromKafka(msg);
visitSummaryService.insertOrUpdateDur(vs); visitSummaryService.insertOrUpdateDur(vs);
} }
public void addTopicPageView(String topicId) {
String userId = userHolder.getUserId();
visitSummaryService.addPageView(userId, topicId, VisitTypeEnum.TOPIC_PAGE_VIEW);
}
public void addFollowThemeView(String themeId) {
String userId = userHolder.getUserId();
visitSummaryService.addPageView(userId, themeId, VisitTypeEnum.THEME_PAGE_VIEW);
}
public void addFollowThemeView() {
String userId = userHolder.getUserId();
visitSummaryService.addPageView(userId, userId, VisitTypeEnum.FOLLOW_THEME_VIEW);
}
} }
...@@ -16,6 +16,7 @@ import com.tanpu.community.api.beans.vo.feign.product.FundInfoBaseResp; ...@@ -16,6 +16,7 @@ import com.tanpu.community.api.beans.vo.feign.product.FundInfoBaseResp;
import com.tanpu.community.api.beans.vo.feign.product.ProductInfoVO; import com.tanpu.community.api.beans.vo.feign.product.ProductInfoVO;
import com.tanpu.community.api.beans.vo.feign.zhibo.ZhiboListResp; import com.tanpu.community.api.beans.vo.feign.zhibo.ZhiboListResp;
import com.tanpu.community.api.enums.RelTypeEnum; import com.tanpu.community.api.enums.RelTypeEnum;
import com.tanpu.community.api.enums.UserLevelEnum;
import com.tanpu.community.dao.entity.community.FileRecordEntity; import com.tanpu.community.dao.entity.community.FileRecordEntity;
import com.tanpu.community.dao.entity.community.TopicEntity; import com.tanpu.community.dao.entity.community.TopicEntity;
import com.tanpu.community.feign.course.FeignClientForCourse; import com.tanpu.community.feign.course.FeignClientForCourse;
...@@ -392,6 +393,17 @@ public class BatchFeignCallService { ...@@ -392,6 +393,17 @@ public class BatchFeignCallService {
themeQo.setUserInvestorType(userInfo.getUserInvestorType()); themeQo.setUserInvestorType(userInfo.getUserInvestorType());
themeQo.setBelongUserOrgId(userInfo.getBelongUserOrgId()); themeQo.setBelongUserOrgId(userInfo.getBelongUserOrgId());
themeQo.setBelongUserOrgName(userInfo.getBelongUserOrgName()); themeQo.setBelongUserOrgName(userInfo.getBelongUserOrgName());
//工作室相关
themeQo.setWorkshopName(userInfo.getWorkshopName());
themeQo.setWorkshopStatus(userInfo.getWorkshopStatus());
themeQo.setWorkshopIntroduction(userInfo.getWorkshopIntroduction());
//首席投顾
if (UserLevelEnum.USER_CHIEF_FINANCIAL_ADVISER.getCode() == userInfo.getLevelGrade()
&& userInfo.getUserInfoNewChief() != null) {
themeQo.setNickName(userInfo.getUserInfoNewChief().getUserName());
themeQo.setUserImg(userInfo.getUserInfoNewChief().getHeadImageUrl());
themeQo.setUserIntroduction(userInfo.getUserInfoNewChief().getPersonalProfile());
}
} }
if (themeQo.getContent() == null) { if (themeQo.getContent() == null) {
continue; continue;
......
...@@ -4,13 +4,17 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; ...@@ -4,13 +4,17 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tanpu.community.api.enums.CollectionTypeEnum; import com.tanpu.community.api.enums.CollectionTypeEnum;
import com.tanpu.community.api.enums.DeleteTagEnum; import com.tanpu.community.api.enums.DeleteTagEnum;
import com.tanpu.community.dao.entity.community.CollectionEntity; import com.tanpu.community.dao.entity.community.CollectionEntity;
import com.tanpu.community.dao.entity.community.TimesCountEntity;
import com.tanpu.community.dao.mapper.community.CollectionMapper; import com.tanpu.community.dao.mapper.community.CollectionMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -22,7 +26,7 @@ public class CollectionService { ...@@ -22,7 +26,7 @@ public class CollectionService {
// 若不存在则新增,若存在则修改deleteTag // 若不存在则新增,若存在则修改deleteTag
@Transactional @Transactional
public void addIfNotExist(String themeId, String userId, CollectionTypeEnum type) { public void saveOrUpdate(String themeId, String userId, CollectionTypeEnum type) {
// 判断记录是否存在,无论是否删除 // 判断记录是否存在,无论是否删除
CollectionEntity queryCollection = getTargetCollection(themeId, userId, type); CollectionEntity queryCollection = getTargetCollection(themeId, userId, type);
if (queryCollection != null) { if (queryCollection != null) {
...@@ -64,7 +68,7 @@ public class CollectionService { ...@@ -64,7 +68,7 @@ public class CollectionService {
// 根据用户id和行为type获取target_id列表 // 根据用户id和行为type获取target_id列表
public Set<String> getListByUser(String userId, CollectionTypeEnum type) { public Set<String> getListByUser(String userId, CollectionTypeEnum type) {
return collectionMapper.selectList(new LambdaQueryWrapper<CollectionEntity>() return collectionMapper.selectList(new LambdaQueryWrapper<CollectionEntity>()
.eq(CollectionEntity::getUserId,userId) .eq(CollectionEntity::getUserId, userId)
.eq(CollectionEntity::getCollectionType, type.getCode()) .eq(CollectionEntity::getCollectionType, type.getCode())
.eq(CollectionEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode())) .eq(CollectionEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode()))
.stream().map(CollectionEntity::getTargetId).collect(Collectors.toSet()); .stream().map(CollectionEntity::getTargetId).collect(Collectors.toSet());
...@@ -79,6 +83,18 @@ public class CollectionService { ...@@ -79,6 +83,18 @@ public class CollectionService {
.eq(CollectionEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode()))); .eq(CollectionEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode())));
} }
// 统计多个对象(主题、评论)的数量(点赞、收藏)
public Map<String, Integer> getCountMapByType(List<String> targetIds, CollectionTypeEnum type) {
if (CollectionUtils.isEmpty(targetIds)){
return new HashMap<>();
}
LambdaQueryWrapper<CollectionEntity> queryWrapper = new LambdaQueryWrapper<CollectionEntity>().eq(CollectionEntity::getCollectionType, 1)
.in(CollectionEntity::getTargetId, targetIds).groupBy(CollectionEntity::getTargetId);
return collectionMapper.selectCountByTargetIds(queryWrapper).stream()
.collect(Collectors.toMap(TimesCountEntity::getId, TimesCountEntity::getTimes));
}
// 统计多个对象(主题、评论)的数量(点赞、收藏) // 统计多个对象(主题、评论)的数量(点赞、收藏)
public Integer getCountByTypeAndIds(List<String> targetIds, CollectionTypeEnum type) { public Integer getCountByTypeAndIds(List<String> targetIds, CollectionTypeEnum type) {
return collectionMapper.selectCount((new LambdaQueryWrapper<CollectionEntity>() return collectionMapper.selectCount((new LambdaQueryWrapper<CollectionEntity>()
...@@ -86,6 +102,7 @@ public class CollectionService { ...@@ -86,6 +102,7 @@ public class CollectionService {
.eq(CollectionEntity::getCollectionType, type.getCode())) .eq(CollectionEntity::getCollectionType, type.getCode()))
.eq(CollectionEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode())); .eq(CollectionEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode()));
} }
//逻辑删除,修改delete_tag //逻辑删除,修改delete_tag
@Transactional @Transactional
public void delete(String themeId, String userId, CollectionTypeEnum type) { public void delete(String themeId, String userId, CollectionTypeEnum type) {
......
...@@ -9,6 +9,7 @@ import com.tanpu.community.api.enums.DeleteTagEnum; ...@@ -9,6 +9,7 @@ import com.tanpu.community.api.enums.DeleteTagEnum;
import com.tanpu.community.api.enums.ReportStatusEnum; import com.tanpu.community.api.enums.ReportStatusEnum;
import com.tanpu.community.cache.RedisCache; import com.tanpu.community.cache.RedisCache;
import com.tanpu.community.dao.entity.community.CommentEntity; 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.dao.mapper.community.CommentMapper;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
...@@ -17,12 +18,12 @@ import org.springframework.stereotype.Service; ...@@ -17,12 +18,12 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static com.tanpu.community.api.constants.RedisKeyConstant.CACHE_COMMENT_THEMEID; import static com.tanpu.community.api.constants.RedisKeyConstant.*;
import static com.tanpu.community.api.constants.RedisKeyConstant.CAHCE_COMMENT_ID;
@Service @Service
public class CommentService { public class CommentService {
...@@ -42,6 +43,7 @@ public class CommentService { ...@@ -42,6 +43,7 @@ public class CommentService {
commentMapper.insert(commentEntity); commentMapper.insert(commentEntity);
//失效缓存 //失效缓存
redisCache.evict(StringUtils.joinWith("_", CACHE_COMMENT_THEMEID, commentEntity.getThemeId())); redisCache.evict(StringUtils.joinWith("_", CACHE_COMMENT_THEMEID, commentEntity.getThemeId()));
redisCache.evict(StringUtils.joinWith("_", CACHE_THEME_ID, commentEntity.getThemeId()));
} }
...@@ -51,47 +53,49 @@ public class CommentService { ...@@ -51,47 +53,49 @@ public class CommentService {
} }
//统计主题集合的评论量 //统计主题集合的评论量
public Integer getCommentCountByThemeIds(List<String> themeIds) { public Integer getTotalCountByThemeIds(List<String> themeIds) {
if (CollectionUtils.isEmpty(themeIds)){ if (CollectionUtils.isEmpty(themeIds)) {
return 0; return 0;
} }
return commentMapper.selectList((new LambdaQueryWrapper<CommentEntity>() return commentMapper.selectList((new LambdaQueryWrapper<CommentEntity>()
.in(CommentEntity::getThemeId, themeIds))) .in(CommentEntity::getThemeId, themeIds)))
.size(); .size();
} }
//统计主题集合的评论量 //统计主题集合的评论量
public Integer getCommentCountByThemeId(String themeId) { public Integer getCommentCountByThemeId(String themeId) {
return commentMapper.selectList((new LambdaQueryWrapper<CommentEntity>() return commentMapper.selectList((new LambdaQueryWrapper<CommentEntity>()
.eq(CommentEntity::getThemeId, themeId))) .eq(CommentEntity::getThemeId, themeId)))
.size(); .size();
} }
public Set<String> getCommentUserCount(List<String> themeIds) {
return commentMapper.selectList((new LambdaQueryWrapper<CommentEntity>() //统计主题集合的评论量
.in(CommentEntity::getThemeId, themeIds))) public Map<String, Integer> getCountMapByThemeIds(List<String> themeIds) {
.stream().map(CommentEntity::getAuthorId).collect(Collectors.toSet()); if (CollectionUtils.isEmpty(themeIds)){
return new HashMap<>();
}
LambdaQueryWrapper<CommentEntity> wrapper = (new LambdaQueryWrapper<CommentEntity>()
.in(CommentEntity::getThemeId, themeIds))
.eq(CommentEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED)
.groupBy(CommentEntity::getThemeId);
return commentMapper.selectCountByThemeIds(wrapper).stream()
.collect(Collectors.toMap(TimesCountEntity::getId, TimesCountEntity::getTimes));
} }
public List<CommentEntity> selectByThemeId(String themeId) { public List<CommentEntity> selectByThemeId(String themeId) {
return redisCache.getList(StringUtils.joinWith("_", CACHE_COMMENT_THEMEID, themeId), return redisCache.getList(StringUtils.joinWith("_", CACHE_COMMENT_THEMEID, themeId),
60, () -> { 60, () -> {
LambdaQueryWrapper<CommentEntity> queryWrapper = new LambdaQueryWrapper<CommentEntity>() LambdaQueryWrapper<CommentEntity> queryWrapper = new LambdaQueryWrapper<CommentEntity>()
.eq(CommentEntity::getThemeId, themeId) .eq(CommentEntity::getThemeId, themeId)
.eq(CommentEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode()) .eq(CommentEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode())
.orderByDesc(CommentEntity::getCreateTime); .orderByDesc(CommentEntity::getCreateTime);
return commentMapper.selectList(queryWrapper); return commentMapper.selectList(queryWrapper);
}, new TypeReference<List<CommentEntity>>() {}); }, new TypeReference<List<CommentEntity>>() {
});
} }
public List<CommentEntity> queryCommentsByUserId(String userId) {
return commentMapper.selectList(new LambdaQueryWrapper<CommentEntity>()
.eq(CommentEntity::getAuthorId,userId)
.eq(CommentEntity::getCommentType, CommentTypeEnum.THEME.getCode())
.eq(CommentEntity::getDeleteTag,DeleteTagEnum.NOT_DELETED.getCode()));
}
public List<CommentEntity> queryCommentsByUserId(String userId, String lastId, Integer pageSize) { public List<CommentEntity> queryCommentsByUserId(String userId, String lastId, Integer pageSize) {
LambdaQueryWrapper<CommentEntity> queryWrapper = new LambdaQueryWrapper<CommentEntity>() LambdaQueryWrapper<CommentEntity> queryWrapper = new LambdaQueryWrapper<CommentEntity>()
...@@ -101,20 +105,20 @@ public class CommentService { ...@@ -101,20 +105,20 @@ public class CommentService {
.orderByDesc(CommentEntity::getCreateTime); .orderByDesc(CommentEntity::getCreateTime);
if (StringUtils.isNotEmpty(lastId)) { if (StringUtils.isNotEmpty(lastId)) {
CommentEntity commentEntity = commentMapper.selectOne(new LambdaQueryWrapper<CommentEntity>() CommentEntity commentEntity = commentMapper.selectOne(new LambdaQueryWrapper<CommentEntity>()
.eq(CommentEntity::getCommentId,lastId)); .eq(CommentEntity::getCommentId, lastId));
if (commentEntity==null) throw new BizException("评论未找到,id:"+lastId); if (commentEntity == null) throw new BizException("评论未找到,id:" + lastId);
queryWrapper.lt(CommentEntity::getUpdateTime, commentEntity.getCreateTime()); queryWrapper.lt(CommentEntity::getUpdateTime, commentEntity.getCreateTime());
} }
if (pageSize!=null){ if (pageSize != null) {
queryWrapper.last("limit "+pageSize); queryWrapper.last("limit " + pageSize);
} }
return commentMapper.selectList(queryWrapper); return commentMapper.selectList(queryWrapper);
} }
public void updateReportStatus(String commentId) { public void updateReportStatus(String commentId) {
CommentEntity commentEntity = queryByCommentId(commentId); CommentEntity commentEntity = queryByCommentId(commentId);
if (commentEntity==null){ if (commentEntity == null) {
throw new BizException("评论未找到,id:"+commentId); throw new BizException("评论未找到,id:" + commentId);
} }
commentEntity.setReportStatus(ReportStatusEnum.REPORTED.getCode()); commentEntity.setReportStatus(ReportStatusEnum.REPORTED.getCode());
commentMapper.updateById(commentEntity); commentMapper.updateById(commentEntity);
......
package com.tanpu.community.service;
import com.tanpu.common.api.CommonResp;
import com.tanpu.common.exception.BizException;
import com.tanpu.community.api.beans.vo.feign.fatools.UserInfoNew;
import com.tanpu.community.feign.fatools.FeignClientForFatools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class FeignService {
@Autowired
private FeignClientForFatools fatools;
public UserInfoNew getUserInfoById(String userId) {
CommonResp<UserInfoNew> userInfoNewCommonResp = fatools.queryUsersListNew(userId);
if (userInfoNewCommonResp.isNotSuccess()) {
throw new BizException("内部接口调用失败");
}
return userInfoNewCommonResp.getData();
}
}
...@@ -4,8 +4,10 @@ import com.tanpu.common.util.JsonUtil; ...@@ -4,8 +4,10 @@ import com.tanpu.common.util.JsonUtil;
import com.tanpu.community.api.beans.qo.ThemeAnalysDO; import com.tanpu.community.api.beans.qo.ThemeAnalysDO;
import com.tanpu.community.api.beans.resp.PythonResponse; import com.tanpu.community.api.beans.resp.PythonResponse;
import com.tanpu.community.dao.entity.community.ThemeEntity; import com.tanpu.community.dao.entity.community.ThemeEntity;
import com.tanpu.community.util.BizUtils;
import com.tanpu.community.util.ConvertUtil; import com.tanpu.community.util.ConvertUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
...@@ -42,56 +44,40 @@ public class RecommendService { ...@@ -42,56 +44,40 @@ public class RecommendService {
@Autowired @Autowired
private VisitSummaryService visitSummaryService; private VisitSummaryService visitSummaryService;
//最新 // 最新
private List<ThemeAnalysDO> recentThemeList = new ArrayList<>(); private List<ThemeAnalysDO> recentThemeList = new ArrayList<>();
//推荐 // 推荐
private Map<String, List<String>> recommondList = new HashMap<>(); private Map<String, List<String>> recommondList = new HashMap<>();
//
private Map<String, Set<String>> returnedIdsMap = new HashMap<>();
public List<String> getRecommendThemes(String lastId, Integer pageSize, String userId) { public List<String> getRecommendThemes(Integer pageStart, Integer pageSize, String userId) {
//最热话题,剔除当前用户的主题 //最热话题,剔除当前用户的主题
List<String> hotThemeIds = rankService.getRankThemeList().stream() // todo pageNo , pageSize
.filter(o -> !userId.equals(o.getAuthorId())) List<String> hotThemeIds = rankService.getHotestThemes().stream()
.map(ThemeAnalysDO::getThemeId) .map(ThemeAnalysDO::getThemeId)
.collect(Collectors.toList()); .collect(Collectors.toList());
//最新话题,剔除当前用户的主题 //最新话题,剔除当前用户的主题
List<String> newThemeIds = this.getRecentThemeList().stream() List<String> newThemeIds = getNewestThemes().stream()
.filter(o -> !userId.equals(o.getAuthorId()))
.map(ThemeAnalysDO::getThemeId) .map(ThemeAnalysDO::getThemeId)
.collect(Collectors.toList()); .collect(Collectors.toList());
//推荐话题 //推荐话题
List<String> recThemeIds = getPythonRecommendList(userId); List<String> recThemeIds = getPythonRecommendList(userId);
//混合 List<String> result = mergeRecommend(hotThemeIds, newThemeIds, recThemeIds);
Set<String> returnedIds = (StringUtils.isEmpty(lastId)) || !returnedIdsMap.containsKey(userId)
|| returnedIdsMap.get(userId) == null ?
new HashSet<>() : returnedIdsMap.get(userId);
List<String> result = new ArrayList<>();
getResultList(hotThemeIds, 0, newThemeIds, 0, recThemeIds, 0, returnedIds, result, pageSize, userId);
result = result.stream().limit(pageSize).collect(Collectors.toList()); result = result.stream().limit(pageSize).collect(Collectors.toList());
//记录已返回主题id
if (StringUtils.isEmpty(lastId)) {
returnedIdsMap.put(userId, new HashSet<>(result));
} else {
HashSet<String> newSet = new HashSet<>();
newSet.addAll(returnedIdsMap.get(userId));
newSet.addAll(result);
returnedIdsMap.put(userId, newSet);
}
return result; return result;
} }
public List<ThemeAnalysDO> getRecentThemeList() { // 获取最新话题
public List<ThemeAnalysDO> getNewestThemes() {
if (recentThemeList.size() == 0) { if (recentThemeList.size() == 0) {
refreshNewestThemes(); refreshNewestThemes();
} }
return recentThemeList; return recentThemeList;
} }
//从数据库查询最新主题 // 从数据库查询最新主题
public void refreshNewestThemes() { public void refreshNewestThemes() {
List<ThemeEntity> themeEntities = themeService.queryLatestThemes(100); List<ThemeEntity> themeEntities = themeService.queryLatestThemes(100);
this.recentThemeList = ConvertUtil.themeEntityToAnalysDOs(themeEntities); this.recentThemeList = ConvertUtil.themeEntityToAnalysDOs(themeEntities);
...@@ -106,8 +92,7 @@ public class RecommendService { ...@@ -106,8 +92,7 @@ public class RecommendService {
} }
} }
//HTTP查询python推荐主题 python返回最多50个
//HTTP查询python推荐主题
public List<String> refreshPythonRecommendList(String userId) { public List<String> refreshPythonRecommendList(String userId) {
if (!"true".equals(enablePython)) { if (!"true".equals(enablePython)) {
return Collections.emptyList(); return Collections.emptyList();
...@@ -128,53 +113,72 @@ public class RecommendService { ...@@ -128,53 +113,72 @@ public class RecommendService {
} }
//逐个插入 // 合并,去重
private void getResultList(List<String> hotThemeIds, Integer hotTag, List<String> newThemeIds, Integer newTag, List<String> recThemeIds, Integer recTag, Set<String> returnedIds, List<String> result, Integer pageSize, String userId) { private List<String> mergeList(List<String> hotThemeIds, List<String> newThemeIds, List<String> recThemeIds, Set<String> set) {
if (hotThemeIds.size() <= hotTag && newThemeIds.size() <= newTag && recThemeIds.size() <= recTag) { ArrayList<String> result = new ArrayList<>();
//所有列表已循环结束,返回 // 3个集合的指针
return; Integer hotIdx = 0;
} Integer newIdx = 0;
Integer recIdx = 0;
while (result.size() < pageSize * 1.5) { while (hotThemeIds.size() > hotIdx || newThemeIds.size() > newIdx || recThemeIds.size() > recIdx) {
int hotTimes = hotRatio; int hotTimes = hotRatio;
int newTimes = newRatio; int newTimes = newRatio;
int recTimes = pythonRatio; int recTimes = pythonRatio;
String id; String id;
while (hotTimes > 0 && hotThemeIds.size() > hotTag) { while (hotTimes > 0 && hotThemeIds.size() > hotIdx) {
id = hotThemeIds.get(hotTag); id = hotThemeIds.get(hotIdx);
if (!returnedIds.contains(id)) { if (!set.contains(id)){
result.add(id); result.add(id);
returnedIds.add(id); set.add(id);
} }
hotTag++;
hotIdx++;
hotTimes--; hotTimes--;
} }
while (newTimes > 0 && newThemeIds.size() > newTag) { while (newTimes > 0 && newThemeIds.size() > newIdx) {
id = newThemeIds.get(newTag); id = newThemeIds.get(newIdx);
if (!returnedIds.contains(id)) { if (!set.contains(id)){
result.add(id); result.add(id);
returnedIds.add(id); set.add(id);
} }
newTag++;
newIdx++;
newTimes--; newTimes--;
} }
while (recTimes > 0 && recThemeIds.size() > recTag) { while (recTimes > 0 && recThemeIds.size() > recIdx) {
id = recThemeIds.get(recTag); id = recThemeIds.get(recIdx);
if (!returnedIds.contains(id)) { if (!set.contains(id)){
result.add(id); result.add(id);
returnedIds.add(id); set.add(id);
} }
recTag++;
recIdx++;
recTimes--; recTimes--;
} }
} }
//去重已看过(查看正文) return result;
result = visitSummaryService.filterUserNotVisited(userId, result); }
// 按照 6,3,1的比例
private List<String> mergeRecommend(List<String> hotIds, List<String> newestIds, List<String> recmdIds) {
List<String> retList = new ArrayList<>();
int round = 0;
while (true) {
int hotStart = round * 6;
int newestStart = round * 3;
int recmdStart = round;
if (hotStart >= hotIds.size() && newestStart >= newestIds.size() && recmdStart >= recmdIds.size()) {
break;
}
retList.addAll(BizUtils.subList(hotIds, hotStart, hotStart + 6));
retList.addAll(BizUtils.subList(newestIds, newestStart, newestStart + 3));
retList.addAll(BizUtils.subList(recmdIds, recmdStart, recmdStart + 1));
if (result.size() < pageSize) { round++;
getResultList(hotThemeIds, hotTag, newThemeIds, newTag, recThemeIds, recTag, returnedIds, result, pageSize, userId);
} }
return retList;
} }
......
...@@ -25,7 +25,5 @@ public class ReportLogService { ...@@ -25,7 +25,5 @@ public class ReportLogService {
.reportTime(LocalDateTime.now()) .reportTime(LocalDateTime.now())
.build(); .build();
reportLogMapper.insert(entity); reportLogMapper.insert(entity);
} }
} }
...@@ -8,6 +8,7 @@ import com.tanpu.common.uuid.UuidGenHelper; ...@@ -8,6 +8,7 @@ import com.tanpu.common.uuid.UuidGenHelper;
import com.tanpu.community.api.enums.DeleteTagEnum; import com.tanpu.community.api.enums.DeleteTagEnum;
import com.tanpu.community.api.enums.ReportStatusEnum; import com.tanpu.community.api.enums.ReportStatusEnum;
import com.tanpu.community.dao.entity.community.ThemeEntity; import com.tanpu.community.dao.entity.community.ThemeEntity;
import com.tanpu.community.dao.entity.community.TimesCountEntity;
import com.tanpu.community.dao.mapper.community.ThemeMapper; import com.tanpu.community.dao.mapper.community.ThemeMapper;
import com.tanpu.community.util.TimeUtils; import com.tanpu.community.util.TimeUtils;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
...@@ -19,8 +20,9 @@ import org.springframework.transaction.annotation.Transactional; ...@@ -19,8 +20,9 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
...@@ -46,7 +48,7 @@ public class ThemeService { ...@@ -46,7 +48,7 @@ public class ThemeService {
themeMapper.update(themeEntity, new LambdaUpdateWrapper<ThemeEntity>().eq(ThemeEntity::getThemeId, themeId)); themeMapper.update(themeEntity, new LambdaUpdateWrapper<ThemeEntity>().eq(ThemeEntity::getThemeId, themeId));
} }
//n天内所有主题 //n天内发表的所有主题
public List<ThemeEntity> queryRecentdays(Integer days) { public List<ThemeEntity> queryRecentdays(Integer days) {
LambdaQueryWrapper<ThemeEntity> queryWrapper = new LambdaQueryWrapper<ThemeEntity>() LambdaQueryWrapper<ThemeEntity> queryWrapper = new LambdaQueryWrapper<ThemeEntity>()
.eq(ThemeEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode()) .eq(ThemeEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode())
...@@ -197,29 +199,19 @@ public class ThemeService { ...@@ -197,29 +199,19 @@ public class ThemeService {
} }
/** /**
* 根据话题查询最新主题(可分页) * 根据话题查询最新主题(可分页)
* *
* @param topidId 话题Id * @param topidId 话题Id
* @param lastId 查询此主题Id之前的主题
* @param pageSize 查询数量 * @param pageSize 查询数量
* @return * @return
*/ */
public List<ThemeEntity> queryByTopic(String topidId, String lastId, Integer pageSize) { public List<ThemeEntity> queryNewestByTopic(String topidId, Integer pageNo, Integer pageSize) {
LambdaQueryWrapper<ThemeEntity> queryWrapper = new LambdaQueryWrapper<ThemeEntity>() LambdaQueryWrapper<ThemeEntity> queryWrapper = new LambdaQueryWrapper<ThemeEntity>()
.eq(ThemeEntity::getTopicId, topidId); .eq(ThemeEntity::getTopicId, topidId)
if (StringUtils.isNotEmpty(lastId)) { .last("limit " + pageNo + ", " + pageSize)
ThemeEntity lastEntity = queryByThemeId(lastId); .orderByDesc(ThemeEntity::getCreateTime)
if (lastEntity == null) throw new BizException("主题未找到,id:" + lastId); .eq(ThemeEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode());
queryWrapper.lt(ThemeEntity::getUpdateTime, lastEntity.getCreateTime());
}
if (pageSize != null) {
queryWrapper.last("limit " + pageSize);
}
queryWrapper.orderByDesc(ThemeEntity::getCreateTime);
queryWrapper.eq(ThemeEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode());
return themeMapper.selectList(queryWrapper); return themeMapper.selectList(queryWrapper);
} }
...@@ -234,64 +226,26 @@ public class ThemeService { ...@@ -234,64 +226,26 @@ public class ThemeService {
return themeMapper.selectList(queryWrapper).stream().map(ThemeEntity::getThemeId).collect(Collectors.toList()); return themeMapper.selectList(queryWrapper).stream().map(ThemeEntity::getThemeId).collect(Collectors.toList());
} }
/** /**
* 根据作者查询主题列表(可分页) * 根据作者查询主题分页列表
*
* @param userIds * @param userIds
* @param lastId * @param pageStart
* @param pageSize * @param pageSize
* @return * @return
*/ */
public List<ThemeEntity> queryByUserIds(List<String> userIds, String lastId, Integer pageSize) { public List<ThemeEntity> queryByUserIds(List<String> userIds, Integer pageStart, Integer pageSize) {
LambdaQueryWrapper<ThemeEntity> queryWrapper = new LambdaQueryWrapper<ThemeEntity>() if (CollectionUtils.isEmpty(userIds)){
.in(ThemeEntity::getAuthorId, userIds);
if (StringUtils.isNotEmpty(lastId)) {
ThemeEntity lastEntity = queryByThemeId(lastId);
if (lastEntity == null) throw new BizException("主题未找到,id:" + lastId);
queryWrapper.lt(ThemeEntity::getUpdateTime, lastEntity.getCreateTime());
}
queryWrapper.last("limit " + pageSize);
queryWrapper.orderByDesc(ThemeEntity::getCreateTime);
queryWrapper.eq(ThemeEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode());
return themeMapper.selectList(queryWrapper);
}
/**
* 根据关键字搜索
*
* @param keyword
* @param lastId
* @param pageSize
* @return
*/
public List<ThemeEntity> search(String keyword, String lastId, Integer pageSize) {
if (StringUtils.isEmpty(keyword)) {
return Collections.emptyList(); return Collections.emptyList();
} }
LambdaQueryWrapper<ThemeEntity> queryWrapper = new LambdaQueryWrapper<ThemeEntity>() LambdaQueryWrapper<ThemeEntity> queryWrapper = new LambdaQueryWrapper<ThemeEntity>()
.like(ThemeEntity::getTitle, keyword); .in(ThemeEntity::getAuthorId, userIds)
if (StringUtils.isNotEmpty(lastId)) { .last("limit " + pageStart + ", " + pageSize)
ThemeEntity lastEntity = queryByThemeId(lastId); .orderByDesc(ThemeEntity::getCreateTime)
if (lastEntity == null) throw new BizException("主题未找到,id:" + lastId); .eq(ThemeEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode());
queryWrapper.lt(ThemeEntity::getUpdateTime, lastEntity.getCreateTime());
}
queryWrapper.last("limit " + pageSize);
queryWrapper.orderByDesc(ThemeEntity::getCreateTime);
queryWrapper.eq(ThemeEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode());
return themeMapper.selectList(queryWrapper); return themeMapper.selectList(queryWrapper);
} }
//查询对应话题的发表用户集合
public Set<String> getPostUserCount(List<String> themeIds) {
return themeMapper.selectBatchIds(themeIds).stream()
.map(ThemeEntity::getAuthorId)
.collect(Collectors.toSet());
}
public Integer getForwardCountById(String themeId) { public Integer getForwardCountById(String themeId) {
return themeMapper.selectCount(new LambdaQueryWrapper<ThemeEntity>() return themeMapper.selectCount(new LambdaQueryWrapper<ThemeEntity>()
.eq(ThemeEntity::getFormerThemeId, themeId) .eq(ThemeEntity::getFormerThemeId, themeId)
...@@ -345,4 +299,18 @@ public class ThemeService { ...@@ -345,4 +299,18 @@ public class ThemeService {
themeEntity.setReportStatus(ReportStatusEnum.REPORTED.getCode()); themeEntity.setReportStatus(ReportStatusEnum.REPORTED.getCode());
themeMapper.updateById(themeEntity); themeMapper.updateById(themeEntity);
} }
//统计主题集合的浏览量
public Map<String, Integer> getForwardCountMap(List<String> themeIds) {
if (CollectionUtils.isEmpty(themeIds)){
return new HashMap<String, Integer>();
}
LambdaQueryWrapper<ThemeEntity> wrapper = new LambdaQueryWrapper<ThemeEntity>()
.eq(ThemeEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED)
.in(ThemeEntity::getFormerThemeId,themeIds)
.groupBy(ThemeEntity::getFormerThemeId);
return themeMapper.selectCountByThemeIds(wrapper).stream()
.collect(Collectors.toMap(TimesCountEntity::getId, TimesCountEntity::getTimes));
}
} }
package com.tanpu.community.service; package com.tanpu.community.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.tanpu.community.api.enums.DeleteTagEnum;
import com.tanpu.community.api.enums.VisitTypeEnum; import com.tanpu.community.api.enums.VisitTypeEnum;
import com.tanpu.community.dao.entity.community.TimesCountEntity;
import com.tanpu.community.dao.entity.community.VisitSummaryEntity; import com.tanpu.community.dao.entity.community.VisitSummaryEntity;
import com.tanpu.community.dao.mapper.community.VisitSummaryMapper; import com.tanpu.community.dao.mapper.community.VisitSummaryMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils; import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Slf4j @Slf4j
...@@ -24,6 +26,7 @@ public class VisitSummaryService { ...@@ -24,6 +26,7 @@ public class VisitSummaryService {
@Resource @Resource
private VisitSummaryMapper visitSummaryMapper; private VisitSummaryMapper visitSummaryMapper;
// 从refIds中去掉用户已经访问过的
public List<String> filterUserNotVisited(String userId, List<String> refIds) { public List<String> filterUserNotVisited(String userId, List<String> refIds) {
if (refIds.isEmpty()) { if (refIds.isEmpty()) {
return refIds; return refIds;
...@@ -34,6 +37,14 @@ public class VisitSummaryService { ...@@ -34,6 +37,14 @@ public class VisitSummaryService {
.stream().map(VisitSummaryEntity::getRefId).distinct().collect(Collectors.toList()); .stream().map(VisitSummaryEntity::getRefId).distinct().collect(Collectors.toList());
return ListUtils.subtract(refIds, visited); return ListUtils.subtract(refIds, visited);
} }
public List<String> queryUserVisited(String userId) {
List<String> visited = visitSummaryMapper.selectList(new LambdaQueryWrapper<VisitSummaryEntity>()
.eq(VisitSummaryEntity::getVisitorId, userId))
.stream().map(VisitSummaryEntity::getRefId).distinct().collect(Collectors.toList());
return visited;
}
@Transactional @Transactional
public void insertOrUpdateDur(VisitSummaryEntity vs) { public void insertOrUpdateDur(VisitSummaryEntity vs) {
...@@ -45,6 +56,7 @@ public class VisitSummaryService { ...@@ -45,6 +56,7 @@ public class VisitSummaryService {
} }
@Transactional @Transactional
//TODO 临时埋点,接入新埋点后删除
public void addPageView(String userId, String targetId, VisitTypeEnum type) { public void addPageView(String userId, String targetId, VisitTypeEnum type) {
visitSummaryMapper.insert(VisitSummaryEntity.builder() visitSummaryMapper.insert(VisitSummaryEntity.builder()
.visitorId(userId) .visitorId(userId)
...@@ -89,4 +101,18 @@ public class VisitSummaryService { ...@@ -89,4 +101,18 @@ public class VisitSummaryService {
return visitSummaryEntities.get(0).getCreateTime(); return visitSummaryEntities.get(0).getCreateTime();
} }
} }
//统计主题集合的浏览量
public Map<String, Integer> getCountMapByTargetIds(List<String> refIds, VisitTypeEnum type) {
if (CollectionUtils.isEmpty(refIds)){
return new HashMap<>();
}
LambdaQueryWrapper<VisitSummaryEntity> wrapper = (new LambdaQueryWrapper<VisitSummaryEntity>()
.in(VisitSummaryEntity::getRefId,refIds))
.eq(VisitSummaryEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED)
.eq(VisitSummaryEntity::getRefType,type.getCode())
.groupBy(VisitSummaryEntity::getRefId);
return visitSummaryMapper.selectCountByThemeIds(wrapper).stream()
.collect(Collectors.toMap(TimesCountEntity::getId, TimesCountEntity::getTimes));
}
} }
...@@ -22,6 +22,7 @@ import org.elasticsearch.rest.RestStatus; ...@@ -22,6 +22,7 @@ import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.elasticsearch.client.*; import org.elasticsearch.client.*;
...@@ -35,14 +36,16 @@ import java.util.Map; ...@@ -35,14 +36,16 @@ import java.util.Map;
@Service @Service
public class ESHelper { public class ESHelper {
@Value("${es.index}")
private String esIndex;
@Autowired @Autowired
private RestHighLevelClient client; private RestHighLevelClient client;
public void insert(String type, String id, String json) {
public void insert(String index, String type, String id, String json) {
try { try {
IndexRequest req = new IndexRequest(index); IndexRequest req = new IndexRequest(esIndex);
if (StringUtils.isNotBlank(id)) { if (StringUtils.isNotBlank(id)) {
req.id(type + "_" + id); req.id(type + "_" + id);
} }
...@@ -55,9 +58,9 @@ public class ESHelper { ...@@ -55,9 +58,9 @@ public class ESHelper {
} }
} }
public void insert(String index, String type, String id, Map<String, Object> data) { public void insert(String type, String id, Map<String, Object> data) {
try { try {
IndexRequest req = new IndexRequest(index); IndexRequest req = new IndexRequest(esIndex);
if (StringUtils.isNotBlank(id)) { if (StringUtils.isNotBlank(id)) {
req.id(type + "_" + id); req.id(type + "_" + id);
} }
...@@ -70,9 +73,9 @@ public class ESHelper { ...@@ -70,9 +73,9 @@ public class ESHelper {
} }
} }
public SearchHit[] selectLike(String index, SearchSourceBuilder builder) { public SearchHit[] selectLike(SearchSourceBuilder builder) {
try { try {
SearchRequest req = new SearchRequest(index); SearchRequest req = new SearchRequest(esIndex);
req.source(builder); req.source(builder);
SearchResponse resp = client.search(req, RequestOptions.DEFAULT); SearchResponse resp = client.search(req, RequestOptions.DEFAULT);
validStatus(resp.status(), RestStatus.OK); validStatus(resp.status(), RestStatus.OK);
...@@ -149,7 +152,7 @@ public class ESHelper { ...@@ -149,7 +152,7 @@ public class ESHelper {
search.query(boolQb).from(0).size(50); search.query(boolQb).from(0).size(50);
SearchHit[] hits = helper.selectLike("theme", search); SearchHit[] hits = helper.selectLike(search);
System.out.println(hits.length); System.out.println(hits.length);
for (SearchHit hit : hits) { for (SearchHit hit : hits) {
System.out.println(hit.toString()); System.out.println(hit.toString());
......
...@@ -16,6 +16,7 @@ import org.elasticsearch.search.builder.SearchSourceBuilder; ...@@ -16,6 +16,7 @@ import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder; import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Arrays; import java.util.Arrays;
...@@ -29,8 +30,6 @@ public class ESService { ...@@ -29,8 +30,6 @@ public class ESService {
@Autowired @Autowired
private ESHelper helper; private ESHelper helper;
private static final String INDEX_THEME = "theme";
public void insertOrUpdateThemes(List<ESThemeQo> qos) { public void insertOrUpdateThemes(List<ESThemeQo> qos) {
for (ESThemeQo qo : qos) { for (ESThemeQo qo : qos) {
insertOrUpdateTheme(qo); insertOrUpdateTheme(qo);
...@@ -38,7 +37,7 @@ public class ESService { ...@@ -38,7 +37,7 @@ public class ESService {
} }
// 只要设置了_id,则直接覆盖 // 只要设置了_id,则直接覆盖
public void insertOrUpdateTheme(ESThemeQo qo) { public void insertOrUpdateTheme(ESThemeQo qo) {
helper.insert(INDEX_THEME, String.valueOf(qo.themeType), qo.themeId, JSON.toJSONString(qo)); helper.insert(String.valueOf(qo.themeType), qo.themeId, JSON.toJSONString(qo));
} }
public List<ESThemeQo> queryThemeIdByContentAndTitle(String keyword, int from, int size) { public List<ESThemeQo> queryThemeIdByContentAndTitle(String keyword, int from, int size) {
...@@ -55,7 +54,7 @@ public class ESService { ...@@ -55,7 +54,7 @@ public class ESService {
search.query(boolQb).fetchSource(includes, excludes).sort("createTime", SortOrder.DESC).from(from).size(size); 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); search.query(boolQb).sort("createTime", SortOrder.DESC).from(from).size(size);
SearchHit[] hits = helper.selectLike(INDEX_THEME, search); SearchHit[] hits = helper.selectLike(search);
return Arrays.stream(hits).map(h -> { return Arrays.stream(hits).map(h -> {
return JsonUtil.toBean(h.getSourceAsString(), ESThemeQo.class); return JsonUtil.toBean(h.getSourceAsString(), ESThemeQo.class);
}).collect(Collectors.toList()); }).collect(Collectors.toList());
......
package com.tanpu.community.util;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
public class BizUtils {
public static <T> List<T> subList(List<T> list, int start, int size) {
if (list.isEmpty() || start >= list.size() || start < 0) {
return new ArrayList<>();
}
int realEnd = Math.min(start + size, list.size());
return list.subList(start, realEnd);
}
}
apollo.bootstrap.enabled: false apollo.bootstrap.enabled: true
#app.id: tanpu-community #app.id: tanpu-community
#apollo: #apollo:
...@@ -97,6 +97,7 @@ es: ...@@ -97,6 +97,7 @@ es:
port: 9200 port: 9200
userName: 1 userName: 1
userPasswd: 2 userPasswd: 2
index: dev
tencent: tencent:
cloud: cloud:
......
apollo.bootstrap.enabled: true
#app.id: tanpu-community
#apollo:
# meta: http://dev-apollo.tamp-innner.com:8080
# cacheDir: ./apollocache/
# bootstrap:
# namespaces: application.yml
server:
port: 8060
servlet:
context-path: /community
spring.datasource:
community:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://rm-uf6r22t3d798q4kmk.mysql.rds.aliyuncs.com:3306/tamp_community?useUnicode=true&characterEncoding=utf-8&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
username: tamp_admin
password: '@imeng123'
maxActive: 2
minIdle: 2
initialSize: 2
user:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://rm-uf6r22t3d798q4kmk.mysql.rds.aliyuncs.com:3306/tamp_user?useUnicode=true&characterEncoding=utf-8&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
password: '@imeng123'
maxActive: 2
minIdle: 2
initialSize: 2
jydb:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://rm-uf6r22t3d798q4kmk.mysql.rds.aliyuncs.com:3306/tamp_jydb?useUnicode=true&characterEncoding=utf-8&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
username: tamp_admin
password: '@imeng123'
maxActive: 2
minIdle: 2
initialSize: 2
fund:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://rm-uf6r22t3d798q4kmk.mysql.rds.aliyuncs.com:3306/tamp_fund?useUnicode=true&characterEncoding=utf-8&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
username: tamp_admin
password: '@imeng123'
maxActive: 2
minIdle: 2
initialSize: 2
spring.redis:
host: 118.190.63.109
port: 56379
password: qimeng123
timeout: 2000
max-active: 5
max-wait: 5
max-idle: 5
jedis:
pool:
max-active: 3
max-idle: 3
min-idle: 3
spring.kafka:
bootstrap-servers: 118.190.63.109:9092
consumer:
group-id: tp_group_new_community
auto-offset-reset: latest
fetch-min-size: 64
fetch-max-wait: 500
max-poll-records: 500
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
producer:
acks: 1
batch-size: 10000
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
spring:
sleuth:
enabled: false
zipkin:
enabled: false
aliyun:
oss:
endpoint: http://oss-cn-shanghai.aliyuncs.com
accessId: LTAIAKEzVydP0Q9P
accessSK: 59V9ke9txaIFzWxHFKTb1eoOOpmKpJ
bucketName: tamp-sit
es:
host: 42.194.224.208
port: 9200
userName: 1
userPasswd: 2
tencent:
cloud:
secretId: AKIDTjjV2IhK4ZKBm8z5g14vPedNSJuFnTIq
secretKey: PaVBZfeQwDVXKr7TZOzM6c9VZNwGJGyA
region: ap-shanghai
recommend:
ratio: #主题推荐比例(热门、最新、机器学习)
hot: 3
new: 2
python: 1
python:
enable: false
url: http://172.168.0.164:9000/api/get_recommend?user_id=2431614397151511
\ No newline at end of file
...@@ -15,4 +15,11 @@ ...@@ -15,4 +15,11 @@
<result column="delete_tag" property="deleteTag" /> <result column="delete_tag" property="deleteTag" />
</resultMap> </resultMap>
<resultMap id="CountResultMap" type="com.tanpu.community.dao.entity.community.TimesCountEntity">
<id column="id" property="id" />
<result column="collection_type" property="collectionType" />
<result column="target_id" property="targetId" />
<result column="times" property="times" />
</resultMap>
</mapper> </mapper>
This diff is collapsed.
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