Commit 9f1f1469 authored by 张辰's avatar 张辰

Merge branch 'dev' into 'master'

Dev

See merge request !8
parents 8f5c23ee cd3bac90
...@@ -23,4 +23,11 @@ public final class CommunityConstant { ...@@ -23,4 +23,11 @@ public final class CommunityConstant {
//图片压缩比例:50% //图片压缩比例:50%
public static final String OSS_RESIZE_RATIO = "?x-oss-process=image/resize,p_50"; public static final String OSS_RESIZE_RATIO = "?x-oss-process=image/resize,p_50";
public static final String THEME_PREFIX ="NEW_THEME_";
public static final String OLD_FILE_UPLOAD_URL ="http://tp-fatools-svc/fatools/h5/rest/common/uploadSingleFile";
} }
...@@ -24,11 +24,13 @@ public class CreateThemeReq { ...@@ -24,11 +24,13 @@ public class CreateThemeReq {
private List<ThemeContentReq> content; private List<ThemeContentReq> content;
@ApiModelProperty(value = "所属的话题id") @ApiModelProperty(value = "所属的话题id")
private String topicId=""; private String topicId = "";
@ApiModelProperty(value = "修改,则传入正在编辑的ThemeId") @ApiModelProperty(value = "修改,则传入正在编辑的ThemeId")
private String editThemeId=""; private String editThemeId = "";
@ApiModelProperty("是否同步到社区 0为不同步 1为同步 不传也为同步")
private Integer syncToNewComm = 0;
} }
package com.tanpu.community.api.beans.req.theme;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 专栏同步到圈子
*/
@Data
public class SynchroThemeReq {
@NotNull(message = "类型不能为空")
@ApiModelProperty(value = "类型 1:讨论无标题 2:长文有标题")
private Integer themeType;
@ApiModelProperty(value = "专栏id")
private String themeId = "";
@NotEmpty(message = "内容不能为空")
@ApiModelProperty(value = "文本内容")
private List<ThemeContentReq> content;
public String userId = "";
}
package com.tanpu.community.api.beans.vo.feign.newsfeed;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class NewsFeedResReq {
/**
* 关联类型
*/
@ApiModelProperty("关联类型 产品:88 直播:3 短视频:6 图片:122")
private Integer relType;
/**
* 关联id
*/
@ApiModelProperty("关联id")
private String relId;
/**
* 产品类型 rel_type等于产品生效
*/
private Integer productType;
/**
* 备注说明
*/
private String remark;
}
package com.tanpu.community.api.beans.vo.feign.newsfeed;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* 发布动态
*
* @author hudingguo
*/
@ApiModel("发布动态")
@Data
public class NewsFeedSave4NewCommReq {
@ApiModelProperty("专栏id")
private String newsFeedId;
@ApiModelProperty("专栏内容内容")
private String content;
@ApiModelProperty("关联多个内容")
private List<NewsFeedResReq> newsFeedResList;
@ApiModelProperty("用户id")
public String userId = "";
}
...@@ -3,6 +3,7 @@ package com.tanpu.community.config; ...@@ -3,6 +3,7 @@ package com.tanpu.community.config;
import feign.Logger; import feign.Logger;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/** /**
* @description: * @description:
...@@ -16,4 +17,9 @@ public class FeignConfiguration { ...@@ -16,4 +17,9 @@ public class FeignConfiguration {
//这里记录所有,根据实际情况选择合适的日志level //这里记录所有,根据实际情况选择合适的日志level
return Logger.Level.FULL; return Logger.Level.FULL;
} }
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
} }
...@@ -113,4 +113,13 @@ public class ThemeController { ...@@ -113,4 +113,13 @@ public class ThemeController {
return CommonResp.success(themeManager.getFollowUpdateCount(userId)); return CommonResp.success(themeManager.getFollowUpdateCount(userId));
} }
@ApiOperation("专栏同步主题")
@PostMapping(value = "/convertFromNewsFeed")
@ResponseBody
public CommonResp<Void> convertFromNewsFeed(@Validated @RequestBody SynchroThemeReq req) {
themeManager.convertFromNewsFeed(req);
return CommonResp.success();
}
} }
package com.tanpu.community.feign.community;
import com.tanpu.common.api.CommonResp;
import com.tanpu.community.api.beans.vo.feign.newsfeed.NewsFeedSave4NewCommReq;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class FeignBackClientForCommunity implements FallbackFactory<FeignClientForCommunity> {
@Override
public FeignClientForCommunity create(Throwable throwable) {
return new FeignClientForCommunity() {
@Override
public CommonResp saveNewsFeed4NewComm(NewsFeedSave4NewCommReq req) {
log.error("请求信息", throwable);
log.error("FeignBackClientForCommunity.saveNewsFeed4NewComm-同步专栏频ids:{}", req.getNewsFeedId());
return null;
}
};
}
}
package com.tanpu.community.feign.community;
import com.tanpu.common.api.CommonResp;
import com.tanpu.community.api.beans.vo.feign.newsfeed.NewsFeedSave4NewCommReq;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
@FeignClient(value = "service-community", contextId = "community", fallbackFactory = FeignBackClientForCommunity.class, url = "http://tp-tamp-community-svc", path = "/community")
// @FeignClient(value = "service-community", contextId = "community", fallbackFactory = FeignBackClientForCommunity.class, url = "http://127.0.0.1:8202/community")
public interface FeignClientForCommunity {
@ApiOperation("发布专栏 圈子用feign")
@PostMapping("/newsFeed/save4NewComm")
CommonResp saveNewsFeed4NewComm(NewsFeedSave4NewCommReq req);
}
package com.tanpu.community.manager; package com.tanpu.community.manager;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.tanpu.biz.common.enums.RelTypeEnum; import com.tanpu.biz.common.enums.RelTypeEnum;
...@@ -9,6 +10,7 @@ import com.tanpu.common.api.CommonResp; ...@@ -9,6 +10,7 @@ import com.tanpu.common.api.CommonResp;
import com.tanpu.common.constant.ErrorCodeConstant; import com.tanpu.common.constant.ErrorCodeConstant;
import com.tanpu.common.exception.BizException; import com.tanpu.common.exception.BizException;
import com.tanpu.common.util.JsonUtil; import com.tanpu.common.util.JsonUtil;
import com.tanpu.community.api.CommunityConstant;
import com.tanpu.community.api.beans.qo.ESThemeQo; import com.tanpu.community.api.beans.qo.ESThemeQo;
import com.tanpu.community.api.beans.qo.FormerThemeQo; import com.tanpu.community.api.beans.qo.FormerThemeQo;
import com.tanpu.community.api.beans.qo.ThemeContentQo; import com.tanpu.community.api.beans.qo.ThemeContentQo;
...@@ -19,19 +21,28 @@ import com.tanpu.community.api.beans.req.theme.CreateThemeReq; ...@@ -19,19 +21,28 @@ import com.tanpu.community.api.beans.req.theme.CreateThemeReq;
import com.tanpu.community.api.beans.req.theme.ForwardThemeReq; import com.tanpu.community.api.beans.req.theme.ForwardThemeReq;
import com.tanpu.community.api.beans.req.theme.LikeThemeReq; import com.tanpu.community.api.beans.req.theme.LikeThemeReq;
import com.tanpu.community.api.beans.req.theme.ReportThemeReq; import com.tanpu.community.api.beans.req.theme.ReportThemeReq;
import com.tanpu.community.api.beans.req.theme.SynchroThemeReq;
import com.tanpu.community.api.beans.req.theme.ThemeContentReq; import com.tanpu.community.api.beans.req.theme.ThemeContentReq;
import com.tanpu.community.api.beans.req.theme.ThemeListReq; import com.tanpu.community.api.beans.req.theme.ThemeListReq;
import com.tanpu.community.api.beans.resp.CreateThemeResp; import com.tanpu.community.api.beans.resp.CreateThemeResp;
import com.tanpu.community.api.beans.resp.ThemeFullSearchResp; import com.tanpu.community.api.beans.resp.ThemeFullSearchResp;
import com.tanpu.community.api.beans.resp.ThemeListResp; import com.tanpu.community.api.beans.resp.ThemeListResp;
import com.tanpu.community.api.beans.vo.ImagesDTO;
import com.tanpu.community.api.beans.vo.feign.fatools.UserInfoResp; import com.tanpu.community.api.beans.vo.feign.fatools.UserInfoResp;
import com.tanpu.community.api.enums.*; import com.tanpu.community.api.beans.vo.feign.newsfeed.NewsFeedResReq;
import com.tanpu.community.api.beans.vo.feign.newsfeed.NewsFeedSave4NewCommReq;
import com.tanpu.community.api.enums.BlockTypeEnum;
import com.tanpu.community.api.enums.DeleteTagEnum;
import com.tanpu.community.api.enums.OperationTypeEnum;
import com.tanpu.community.api.enums.ThemeListTypeEnum;
import com.tanpu.community.api.enums.ThemeTypeEnum;
import com.tanpu.community.cache.RedisCache; import com.tanpu.community.cache.RedisCache;
import com.tanpu.community.dao.entity.community.BlackListEntity; import com.tanpu.community.dao.entity.community.BlackListEntity;
import com.tanpu.community.dao.entity.community.CollectionEntity; import com.tanpu.community.dao.entity.community.CollectionEntity;
import com.tanpu.community.dao.entity.community.CommentEntity; import com.tanpu.community.dao.entity.community.CommentEntity;
import com.tanpu.community.dao.entity.community.ThemeAttachmentEntity; import com.tanpu.community.dao.entity.community.ThemeAttachmentEntity;
import com.tanpu.community.dao.entity.community.ThemeEntity; import com.tanpu.community.dao.entity.community.ThemeEntity;
import com.tanpu.community.feign.community.FeignClientForCommunity;
import com.tanpu.community.feign.fatools.FeignClientForFatools; import com.tanpu.community.feign.fatools.FeignClientForFatools;
import com.tanpu.community.service.*; import com.tanpu.community.service.*;
import com.tanpu.community.service.base.ESService; import com.tanpu.community.service.base.ESService;
...@@ -43,22 +54,31 @@ import com.tanpu.community.util.TimeUtils; ...@@ -43,22 +54,31 @@ import com.tanpu.community.util.TimeUtils;
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.io.FileUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.lang3.exception.ExceptionUtils;
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.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import javax.annotation.PostConstruct;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList; import java.io.File;
import java.util.Arrays; import java.io.IOException;
import java.util.Collections; import java.time.LocalDateTime;
import java.util.Comparator; import java.util.*;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static com.tanpu.community.api.constants.RedisKeyConstant.*; import static com.tanpu.community.api.constants.RedisKeyConstant.*;
...@@ -66,6 +86,10 @@ import static com.tanpu.community.api.constants.RedisKeyConstant.*; ...@@ -66,6 +86,10 @@ import static com.tanpu.community.api.constants.RedisKeyConstant.*;
@Slf4j @Slf4j
@Service @Service
public class ThemeManager { public class ThemeManager {
@Value("${tmpfile.dir:/data/tmp/}")
private String tmpDir;
@Resource @Resource
private ThemeService themeService; private ThemeService themeService;
...@@ -108,6 +132,22 @@ public class ThemeManager { ...@@ -108,6 +132,22 @@ public class ThemeManager {
@Autowired @Autowired
private RecommendService recommendService; private RecommendService recommendService;
@Resource
private RestTemplate restTemplate;
@PostConstruct
public void init() throws IOException {
File f = new File(tmpDir);
log.info("create directory {}", tmpDir);
if (!f.exists()) {
FileUtils.forceMkdir(f);
}
}
// 专栏
@Autowired
private FeignClientForCommunity feignClientForCommunity;
public ThemeFullSearchResp themeFullSearch(String keyword, Integer pageNo, Integer pageSize, String ident, String userId) { public ThemeFullSearchResp themeFullSearch(String keyword, Integer pageNo, Integer pageSize, String ident, String userId) {
List<String> excludeIds; List<String> excludeIds;
if (pageNo > 1) { if (pageNo > 1) {
...@@ -158,11 +198,11 @@ public class ThemeManager { ...@@ -158,11 +198,11 @@ public class ThemeManager {
*/ */
@Transactional @Transactional
public CreateThemeResp publishTheme(CreateThemeReq req, String userId) { public CreateThemeResp publishTheme(CreateThemeReq req, String userId) {
if (CollectionUtils.isEmpty(req.getContent())) {
throw new BizException("正文内容不能为空"); // 校验参数
}
//校验参数
checkAttachment(req.getContent()); checkAttachment(req.getContent());
// 转播权限校验
liveRelayCheck(userId, req.getContent());
// 保存主题表 // 保存主题表
ThemeEntity themeEntity = new ThemeEntity(); ThemeEntity themeEntity = new ThemeEntity();
...@@ -176,6 +216,11 @@ public class ThemeManager { ...@@ -176,6 +216,11 @@ public class ThemeManager {
if (StringUtils.isBlank(req.getEditThemeId())) { if (StringUtils.isBlank(req.getEditThemeId())) {
// 新建 // 新建
themeService.insertTheme(themeEntity); themeService.insertTheme(themeEntity);
// 同步到专栏
if (1 == req.getSyncToNewComm()) {
synchronizeToNewsFeed(req, themeEntity.getThemeId(), userId);
}
} else { } else {
// 修改 // 修改
themeService.update(themeEntity, req.getEditThemeId()); themeService.update(themeEntity, req.getEditThemeId());
...@@ -201,12 +246,111 @@ public class ThemeManager { ...@@ -201,12 +246,111 @@ public class ThemeManager {
return CreateThemeResp.builder().themeId(themeEntity.getThemeId()).build(); return CreateThemeResp.builder().themeId(themeEntity.getThemeId()).build();
} }
private void synchronizeToNewsFeed(CreateThemeReq req, String themeId, String userId) {
if (!ThemeTypeEnum.DISCUSSION.getCode().equals(req.getThemeType())) {
// 只有讨论类型才能同步专栏
throw new BizException("长文类型无法同步专栏");
}
NewsFeedSave4NewCommReq newsFeedReq = new NewsFeedSave4NewCommReq();
newsFeedReq.setNewsFeedId(themeId);
newsFeedReq.setUserId(userId);
ArrayList<NewsFeedResReq> feedList = new ArrayList<>();
for (ThemeContentReq themeContentReq : req.getContent()) {
// 文字内容添加到content
if (RelTypeEnum.TEXT.type.equals(themeContentReq.getType())) {
newsFeedReq.setContent(themeContentReq.getValue());
} else if (RelTypeEnum.MULTIPLE_IMAGE.type.equals(themeContentReq.getType())) {
List<ImagesDTO> imgList = themeContentReq.getImgList();
imgList.forEach(img -> {
feedList.add(convertImg(img, userId));
});
} else {
//其他类型的附件
feedList.add(NewsFeedResReq.builder().relType(Integer.parseInt(themeContentReq.getType()))
.relId(themeContentReq.getValue())
.productType(themeContentReq.getProductType())
.remark(themeContentReq.getRemark())
.build());
}
}
newsFeedReq.setNewsFeedResList(feedList);
CommonResp response = feignClientForCommunity.saveNewsFeed4NewComm(newsFeedReq);
if (response.isNotSuccess() || !ObjectUtils.anyNotNull(response.getData())) {
throw new BizException("同步圈子调用失败");
}
}
private NewsFeedResReq convertImg(ImagesDTO img, String userId) {
String imgUrl = img.getRemark();
String[] arr = StringUtils.split(imgUrl, ".");
String suffix = arr[arr.length - 1];
String fileName = tmpDir + imgUrl.substring(imgUrl.lastIndexOf('/') + 1);
ResponseEntity<byte[]> resp = restTemplate.getForEntity(img.getRemark(), byte[].class);
byte[] rst = resp.getBody();
File f = new File(fileName);
try {
FileUtils.writeByteArrayToFile(f, rst);
// 调用对方接口
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.set("uid", userId);
MultiValueMap<String, Object> params = new LinkedMultiValueMap<String, Object>();
HashMap<String, Object> item = new HashMap<>();
item.put("filetype", suffix);
item.put("refid", img.getRelId());
item.put("mode", 0);
item.put("userId", userId);
FileSystemResource br = new FileSystemResource(f);
params.add("file", br);
params.add("item", item);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String, Object>>(params, headers);
// tp-community-svc
ResponseEntity<String> response = restTemplate.exchange(CommunityConstant.OLD_FILE_UPLOAD_URL, HttpMethod.POST, requestEntity, String.class);
log.info("new-community uploadThemePic returns {}", JSON.toJSONString(response));
if (StringUtils.isBlank(response.getBody())) {
throw new RuntimeException("response body is blank");
}
CommonResp<LinkedHashMap<String, String>> responseBody = JsonUtil.toBean(response.getBody(), CommonResp.class);
if (!responseBody.isSuccess()) {
throw new RuntimeException("reponse is not success");
}
HashMap<String, String> data = responseBody.getData();
return NewsFeedResReq.builder().relId(data.get("fileId"))
.relType(Integer.parseInt(RelTypeEnum.IMAGE_FILE.type))
.remark(data.get("fileurl")).build();
} catch (Exception e) {
log.error("error in handleSyncImg for imgUrl: {}", img.getRemark(), e);
throw new RuntimeException(e);
} finally {
try {
FileUtils.forceDelete(f);
} catch (Exception e) {
// do nothing
}
}
}
/** /**
* 参数校验 * 参数校验
* *
* @param themeAttachments * @param themeAttachments
*/ */
private void checkAttachment(List<ThemeContentReq> themeAttachments) { private void checkAttachment(List<ThemeContentReq> themeAttachments) {
if (CollectionUtils.isEmpty(themeAttachments)) {
throw new BizException("正文内容不能为空");
}
for (ThemeContentReq content : themeAttachments) { for (ThemeContentReq content : themeAttachments) {
if (content.getType() == null) { if (content.getType() == null) {
throw new IllegalArgumentException("主题内容ThemeContentReq缺少类型"); throw new IllegalArgumentException("主题内容ThemeContentReq缺少类型");
...@@ -260,15 +404,19 @@ public class ThemeManager { ...@@ -260,15 +404,19 @@ public class ThemeManager {
*/ */
// 查询主题列表:推荐/关注/热门/最新 // 查询主题列表:推荐/关注/热门/最新
public ThemeListResp queryList(ThemeListReq req, String userId) { public ThemeListResp queryList(ThemeListReq req, String userId) {
List<String> excludeIds; List<String> excludeIds = new ArrayList<>();
LocalDateTime firstThemeTime = LocalDateTime.now();
if (req.page.pageNumber > 1) { if (req.page.pageNumber > 1) {
String l = redisCache.get("queryThemes_" + req.ident); String l = redisCache.get("queryThemes_" + req.ident);
excludeIds = StringUtils.isBlank(l) ? new ArrayList<>() : JsonUtil.toBean(l, new TypeReference<List<String>>() { if (!StringUtils.isBlank(l)) {
excludeIds = JsonUtil.toBean(l, new TypeReference<List<String>>() {
}); });
} else { firstThemeTime = themeService.queryByThemeIdIgnoreDelete(excludeIds.get(0)).getCreateTime();
excludeIds = new ArrayList<>();
} }
}
Integer pageStart = (req.page.pageNumber - 1) * req.page.pageSize; Integer pageStart = (req.page.pageNumber - 1) * req.page.pageSize;
Integer pageSize = req.page.pageSize; Integer pageSize = req.page.pageSize;
...@@ -279,11 +427,16 @@ public class ThemeManager { ...@@ -279,11 +427,16 @@ public class ThemeManager {
// 需要筛掉用户访问过详情的 & 最近出现在列表页过的. // 需要筛掉用户访问过详情的 & 最近出现在列表页过的.
List<String> visitedIds = visitLogService.queryUserRecentVisited(userId); List<String> visitedIds = visitLogService.queryUserRecentVisited(userId);
List<String> excludes = ListUtils.union(excludeIds, visitedIds); List<String> excludes = ListUtils.union(excludeIds, visitedIds);
List<String> recmdIds = recommendService.getRecommendThemes(pageStart, pageSize, userId, excludes); List<String> recmdIds = recommendService.getRecommendThemes(pageStart, pageSize, userId, excludes, firstThemeTime);
themes = themeService.queryByThemeIds(recmdIds); // 加载第一页时,为防止首页显示空列表,从推荐池中再捞出已看过帖子
if (req.page.pageNumber <= 3 && recmdIds.size() < pageSize) {
List<String> reSearchIds=ListUtils.union(excludeIds, recmdIds);
recmdIds.addAll(recommendService.getRecommendThemes(pageStart, pageSize, userId, reSearchIds, firstThemeTime));
}
//排序并去重 themes = themeService.queryByThemeIds(recmdIds);
// 排序并去重
themes = RankUtils.sortThemeEntityByIds(themes, recmdIds).stream().limit(pageSize).collect(Collectors.toList()); themes = RankUtils.sortThemeEntityByIds(themes, recmdIds).stream().limit(pageSize).collect(Collectors.toList());
...@@ -547,6 +700,39 @@ public class ThemeManager { ...@@ -547,6 +700,39 @@ public class ThemeManager {
this.evictThemeCache(themeId); this.evictThemeCache(themeId);
} }
// 从专栏同步
public void convertFromNewsFeed(SynchroThemeReq req2) {
String userId = req2.getUserId();
CreateThemeReq req = new CreateThemeReq();
BeanUtils.copyProperties(req2, req);
req.setTopicId("");
req.setTitle("");
// 校验参数
checkAttachment(req.getContent());
// 转播权限校验
liveRelayCheck(userId, req.getContent());
// 保存主题表
ThemeEntity themeEntity = new ThemeEntity();
BeanUtils.copyProperties(req, themeEntity);
themeEntity.setAuthorId(userId);
themeEntity.setContent(JsonUtil.toJson(req.getContent()));
themeEntity.setThemeId(CommunityConstant.THEME_PREFIX + req2.getThemeId());
themeService.insertTheme(themeEntity);
// 保存附件表
List<ThemeAttachmentEntity> themeAttachments = ConvertUtil.themeReqToAttachmentList(req, themeEntity.getThemeId());
themeAttachmentService.insertList(themeAttachments);
try {
esService.insertOrUpdateTheme(ConvertUtil.convert(themeEntity));
} catch (Exception e) {
log.error("error in save theme to ES. themeId:{}, error:{}", themeEntity.getThemeId(), ExceptionUtils.getStackTrace(e));
}
}
/** /**
* 腾讯云-内容检测 * 腾讯云-内容检测
...@@ -698,4 +884,5 @@ public class ThemeManager { ...@@ -698,4 +884,5 @@ public class ThemeManager {
redisCache.evict(StringUtils.joinWith("_", CACHE_THEME_ID, themeId)); redisCache.evict(StringUtils.joinWith("_", CACHE_THEME_ID, themeId));
} }
} }
...@@ -135,7 +135,7 @@ public class RankService { ...@@ -135,7 +135,7 @@ public class RankService {
//排序 //排序
hotestThemes = map.entrySet().stream() hotestThemes = map.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.map(e -> e.getKey()).collect(Collectors.toList()); .map(Map.Entry::getKey).collect(Collectors.toList());
//落库 //落库
rankLogService.logThemeRank(hotestThemes, start, TimeUtils.calMillisTillNow(start)); rankLogService.logThemeRank(hotestThemes, start, TimeUtils.calMillisTillNow(start));
} }
......
...@@ -6,12 +6,15 @@ import com.tanpu.community.api.beans.resp.PythonResponse; ...@@ -6,12 +6,15 @@ 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.BizUtils;
import com.tanpu.community.util.ConvertUtil; import com.tanpu.community.util.ConvertUtil;
import com.tanpu.community.util.TimeUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
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;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -40,27 +43,33 @@ public class RecommendService { ...@@ -40,27 +43,33 @@ public class RecommendService {
private ThemeService themeService; private ThemeService themeService;
@Resource
private RestTemplate restTemplate;
// 最新 // 最新
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<>();
public List<String> getRecommendThemes(Integer pageStart, Integer pageSize, String userId, List<String> excludeIds) { public List<String> getRecommendThemes(Integer pageStart, Integer pageSize, String userId, List<String> excludeIds, LocalDateTime timeAfter) {
// 最热话题,筛掉用户发表的 & 最近看过的 & excludeIds // 最热话题,筛掉用户发表的 & 最近看过的 & excludeIds
List<String> hotThemeIds = rankService.getHotestThemes().stream() List<String> hotThemeIds = rankService.getHotestThemes().stream()
.filter(theme -> { .filter(theme -> {
return !excludeIds.contains(theme.getThemeId()) && !userId.equals(theme.getAuthorId()); // 暂时不过滤用户自己发的 !userId.equals(theme.getAuthorId());
return !excludeIds.contains(theme.getThemeId());
}) })
.map(ThemeAnalysDO::getThemeId).collect(Collectors.toList()); .map(ThemeAnalysDO::getThemeId).collect(Collectors.toList());
hotThemeIds = BizUtils.subList(hotThemeIds, pageStart, pageSize); hotThemeIds = BizUtils.subList(hotThemeIds, 0, pageSize);
//最新话题,筛掉用户发表的 & 最近看过的 & excludeIds //最新话题,筛掉用户发表的 & 最近看过的 & excludeIds && 上次查询后发帖的
long margin = TimeUtils.calMinuteTillNow(timeAfter);
List<String> newThemeIds = getNewestThemes().stream() List<String> newThemeIds = getNewestThemes().stream()
.filter(theme -> { .filter(theme -> {
return !excludeIds.contains(theme.getThemeId()) && !userId.equals(theme.getAuthorId()); // 暂时不过滤用户自己发的 !userId.equals(theme.getAuthorId());
return !excludeIds.contains(theme.getThemeId()) && theme.getMinutesTillNow() > margin;
}) })
.map(ThemeAnalysDO::getThemeId).collect(Collectors.toList()); .map(ThemeAnalysDO::getThemeId).collect(Collectors.toList());
newThemeIds = BizUtils.subList(newThemeIds, pageStart, pageSize); newThemeIds = BizUtils.subList(newThemeIds, 0, pageSize);
//推荐话题 //推荐话题
List<String> recThemeIds = getPythonRecommendList(userId).stream() List<String> recThemeIds = getPythonRecommendList(userId).stream()
...@@ -101,7 +110,6 @@ public class RecommendService { ...@@ -101,7 +110,6 @@ public class RecommendService {
if (!"true".equals(enablePython)) { if (!"true".equals(enablePython)) {
return Collections.emptyList(); return Collections.emptyList();
} }
RestTemplate restTemplate = new RestTemplate();
HashMap<String, String> param = new HashMap<>(); HashMap<String, String> param = new HashMap<>();
param.put("user_id", userId); param.put("user_id", userId);
try { try {
......
...@@ -40,7 +40,10 @@ public class ThemeService { ...@@ -40,7 +40,10 @@ public class ThemeService {
@Transactional @Transactional
public void insertTheme(ThemeEntity themeEntity) { public void insertTheme(ThemeEntity themeEntity) {
if (StringUtils.isBlank(themeEntity.getThemeId())){
themeEntity.setThemeId(uuidGenHelper.getUuidStr()); themeEntity.setThemeId(uuidGenHelper.getUuidStr());
}
themeMapper.insert(themeEntity); themeMapper.insert(themeEntity);
} }
......
...@@ -4,7 +4,14 @@ import com.fasterxml.jackson.core.type.TypeReference; ...@@ -4,7 +4,14 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.tanpu.biz.common.enums.RelTypeEnum; import com.tanpu.biz.common.enums.RelTypeEnum;
import com.tanpu.biz.common.enums.community.TopicStatusEnum; import com.tanpu.biz.common.enums.community.TopicStatusEnum;
import com.tanpu.common.util.JsonUtil; import com.tanpu.common.util.JsonUtil;
import com.tanpu.community.api.beans.qo.*; import com.tanpu.community.api.beans.qo.CommentQo;
import com.tanpu.community.api.beans.qo.ESThemeQo;
import com.tanpu.community.api.beans.qo.FollowQo;
import com.tanpu.community.api.beans.qo.FormerThemeQo;
import com.tanpu.community.api.beans.qo.ThemeAnalysDO;
import com.tanpu.community.api.beans.qo.ThemeContentQo;
import com.tanpu.community.api.beans.qo.ThemeQo;
import com.tanpu.community.api.beans.qo.TopicRankQo;
import com.tanpu.community.api.beans.req.theme.CreateThemeReq; import com.tanpu.community.api.beans.req.theme.CreateThemeReq;
import com.tanpu.community.api.beans.req.theme.ThemeContentReq; import com.tanpu.community.api.beans.req.theme.ThemeContentReq;
import com.tanpu.community.api.beans.resp.FileUploadResp; import com.tanpu.community.api.beans.resp.FileUploadResp;
...@@ -12,7 +19,12 @@ import com.tanpu.community.api.beans.vo.ImagesDTO; ...@@ -12,7 +19,12 @@ import com.tanpu.community.api.beans.vo.ImagesDTO;
import com.tanpu.community.api.beans.vo.KafkaDurationUptMsg; import com.tanpu.community.api.beans.vo.KafkaDurationUptMsg;
import com.tanpu.community.api.beans.vo.feign.fatools.UserInfoResp; import com.tanpu.community.api.beans.vo.feign.fatools.UserInfoResp;
import com.tanpu.community.api.enums.DeleteTagEnum; import com.tanpu.community.api.enums.DeleteTagEnum;
import com.tanpu.community.dao.entity.community.*; import com.tanpu.community.dao.entity.community.CommentEntity;
import com.tanpu.community.dao.entity.community.FileRecordEntity;
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.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
......
...@@ -44,24 +44,36 @@ public class TimeUtils { ...@@ -44,24 +44,36 @@ public class TimeUtils {
//计算迄今分钟 //计算迄今分钟
public static long calMinuteTillNow(LocalDateTime start) { public static long calMinuteTillNow(LocalDateTime start) {
if (start==null){
return 0L;
}
Duration between = Duration.between(start, LocalDateTime.now()); Duration between = Duration.between(start, LocalDateTime.now());
return between.toMinutes(); return between.toMinutes();
} }
//计算迄今毫秒数 //计算迄今毫秒数
public static long calMillisTillNow(LocalDateTime start) { public static long calMillisTillNow(LocalDateTime start) {
if (start==null){
return 0L;
}
Duration between = Duration.between(start, LocalDateTime.now()); Duration between = Duration.between(start, LocalDateTime.now());
return between.toMillis(); return between.toMillis();
} }
//计算迄今天数 //计算迄今天数
public static long calDaysTillNow(LocalDateTime start) { public static long calDaysTillNow(LocalDateTime start) {
if (start==null){
return 0L;
}
Duration between = Duration.between(start, LocalDateTime.now()); Duration between = Duration.between(start, LocalDateTime.now());
return between.toDays(); return between.toDays();
} }
//计算迄今小时数 //计算迄今小时数
public static long calHoursTillNow(LocalDateTime start) { public static long calHoursTillNow(LocalDateTime start) {
if (start==null){
return 0L;
}
Duration between = Duration.between(start, LocalDateTime.now()); Duration between = Duration.between(start, LocalDateTime.now());
return between.toHours(); return between.toHours();
} }
......
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