Commit 22030d18 authored by 刘基明's avatar 刘基明

关注话题

parent 855b9561
...@@ -44,7 +44,10 @@ public class TopicFollowQo { ...@@ -44,7 +44,10 @@ public class TopicFollowQo {
@ApiModelProperty(value = "更新帖子数量") @ApiModelProperty(value = "更新帖子数量")
private Integer updateCount; private Integer updateCount;
@ApiModelProperty(value = "发表时间-标准格式化") @ApiModelProperty(value = "最近一条讨论")
public String formatTime; public String lastTheme;
@ApiModelProperty(value = "最近一条讨论发表时间-格式化")
public String lastThemeTime;
} }
package com.tanpu.community.api.beans.req.topic;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class FollowTopicReq {
@ApiModelProperty(value = "关注对象Id")
private String topicId;
@ApiModelProperty(value = "关注类型,1:关注 2:取消关注")
private Integer type;
}
...@@ -2,14 +2,15 @@ package com.tanpu.community.controller; ...@@ -2,14 +2,15 @@ package com.tanpu.community.controller;
import com.tanpu.common.api.CommonResp; import com.tanpu.common.api.CommonResp;
import com.tanpu.common.auth.AuthLogin; import com.tanpu.common.auth.AuthLogin;
import com.tanpu.common.auth.UserHolder;
import com.tanpu.community.api.beans.qo.TopicFollowQo; import com.tanpu.community.api.beans.qo.TopicFollowQo;
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.FollowTopicReq;
import com.tanpu.community.api.beans.req.topic.TopicSearchReq; import com.tanpu.community.api.beans.req.topic.TopicSearchReq;
import com.tanpu.community.manager.TopicManager; import com.tanpu.community.manager.TopicManager;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
...@@ -18,6 +19,7 @@ import org.springframework.web.bind.annotation.RequestParam; ...@@ -18,6 +19,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List; import java.util.List;
@RestController @RestController
...@@ -26,15 +28,17 @@ import java.util.List; ...@@ -26,15 +28,17 @@ import java.util.List;
@ResponseBody @ResponseBody
public class TopicController { public class TopicController {
@Autowired @Resource
private TopicManager topicManager; private TopicManager topicManager;
@Resource
private UserHolder userHolder;
@AuthLogin @AuthLogin
@GetMapping(value = "/followList") @GetMapping(value = "/followList")
@ApiOperation("关注话题列表") @ApiOperation("关注话题列表")
public CommonResp<List<TopicFollowQo>> getFollowList(){ public CommonResp<List<TopicFollowQo>> getFollowList() {
return CommonResp.success(topicManager.getFollowTopicList()); return CommonResp.success(topicManager.getFollowTopicList());
} }
...@@ -42,22 +46,30 @@ public class TopicController { ...@@ -42,22 +46,30 @@ public class TopicController {
@PostMapping(value = "/list") @PostMapping(value = "/list")
@ApiOperation("热门话题,含搜索") @ApiOperation("热门话题,含搜索")
public CommonResp<Page<TopicRankQo>> getTopicList(@RequestBody TopicSearchReq req){ public CommonResp<Page<TopicRankQo>> getTopicList(@RequestBody TopicSearchReq req) {
return CommonResp.success(topicManager.getAllTopicBriefInfo(req)); return CommonResp.success(topicManager.getAllTopicBriefInfo(req));
} }
@GetMapping(value = "/detailPage") @GetMapping(value = "/detailPage")
@ApiOperation("话题详情页顶部") @ApiOperation("话题详情页顶部")
public CommonResp<TopicRankQo> getDetail(@RequestParam String topicId){ public CommonResp<TopicRankQo> getDetail(@RequestParam String topicId) {
return topicManager.getDetail(topicId); return topicManager.getDetail(topicId);
} }
@GetMapping(value = "/titleList") @GetMapping(value = "/titleList")
@ApiOperation("首页顶部话题标题列") @ApiOperation("首页顶部话题标题列")
public CommonResp<List<TopicRankQo>> getTop4Topic(){ public CommonResp<List<TopicRankQo>> getTop4Topic() {
return CommonResp.success(topicManager.getTop4TopicTitles()); return CommonResp.success(topicManager.getTop4TopicTitles());
} }
@AuthLogin
@PostMapping(value = "/follow")
@ApiOperation("首页顶部话题标题列")
public CommonResp<Void> follow(@RequestBody FollowTopicReq req) {
topicManager.follow(req, userHolder.getUserId());
return CommonResp.success();
}
} }
...@@ -23,7 +23,7 @@ public class CodeAutoGenerator { ...@@ -23,7 +23,7 @@ public class CodeAutoGenerator {
String mysqlPassword = "@imeng123"; String mysqlPassword = "@imeng123";
String jdbcUrl = "jdbc:mysql://rm-uf6r22t3d798q4kmkao.mysql.rds.aliyuncs.com:3306/tamp_community"; String jdbcUrl = "jdbc:mysql://rm-uf6r22t3d798q4kmkao.mysql.rds.aliyuncs.com:3306/tamp_community";
// String[] tables = new String[]{"theme"}; // String[] tables = new String[]{"theme"};
String[] tables = new String[]{"topic"}; String[] tables = new String[]{"topic_follow_rel"};
String basePackage = "com.tanpu.community"; String basePackage = "com.tanpu.community";
String mapperPackage = "dao.mapper.community"; String mapperPackage = "dao.mapper.community";
String entityPackage = "dao.entity.community"; String entityPackage = "dao.entity.community";
......
package com.tanpu.community.dao.entity.community;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 讨论区(主题)关注关系表
* </p>
*
* @author xudong
* @since 2022-02-17
*/
@TableName("topic_follow_rel")
@ApiModel(value="TopicFollowRelEntity对象", description="讨论区(主题)关注关系表")
@Builder
public class TopicFollowRelEntity implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "id")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "主题Id")
private String topicId;
@ApiModelProperty(value = "用户id")
private String userId;
@ApiModelProperty(value = "关注时间")
private LocalDateTime followTime;
@ApiModelProperty(value = "取消关注时间")
private LocalDateTime unfollowTime;
private LocalDateTime createTime;
private LocalDateTime updateTime;
private Integer deleteTag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTopicId() {
return topicId;
}
public void setTopicId(String topicId) {
this.topicId = topicId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public LocalDateTime getFollowTime() {
return followTime;
}
public void setFollowTime(LocalDateTime followTime) {
this.followTime = followTime;
}
public LocalDateTime getUnfollowTime() {
return unfollowTime;
}
public void setUnfollowTime(LocalDateTime unfollowTime) {
this.unfollowTime = unfollowTime;
}
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public LocalDateTime getUpdateTime() {
return updateTime;
}
public void setUpdateTime(LocalDateTime updateTime) {
this.updateTime = updateTime;
}
public Integer getDeleteTag() {
return deleteTag;
}
public void setDeleteTag(Integer deleteTag) {
this.deleteTag = deleteTag;
}
@Override
public String toString() {
return "TopicFollowRelEntity{" +
"id=" + id +
", topicId=" + topicId +
", userId=" + userId +
", followTime=" + followTime +
", unfollowTime=" + unfollowTime +
", createTime=" + createTime +
", updateTime=" + updateTime +
", deleteTag=" + deleteTag +
"}";
}
}
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.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants; 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.tanpu.community.dao.entity.community.TimesCountEntity; import com.tanpu.community.dao.entity.community.TimesCountEntity;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Select;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
/** /**
...@@ -22,4 +22,12 @@ public interface ThemeMapper extends BaseMapper<ThemeEntity> { ...@@ -22,4 +22,12 @@ public interface ThemeMapper extends BaseMapper<ThemeEntity> {
@Select("select former_theme_id as id, count(1) as times from theme ${ew.customSqlSegment}") @Select("select former_theme_id as id, count(1) as times from theme ${ew.customSqlSegment}")
List<TimesCountEntity> selectCountByThemeIds(@Param(Constants.WRAPPER) LambdaQueryWrapper wrapper); List<TimesCountEntity> selectCountByThemeIds(@Param(Constants.WRAPPER) LambdaQueryWrapper wrapper);
ThemeEntity queryOneByTopicIdOrderByUpdateTimeDesc(@Param("topicId")String topicId);
Integer countByTopicIdAndCreateTimeAfter(@Param("topicId")String topicId,@Param("minCreateTime")LocalDateTime minCreateTime);
} }
package com.tanpu.community.dao.mapper.community;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tanpu.community.dao.entity.community.TopicFollowRelEntity;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 讨论区(主题)关注关系表 Mapper 接口
* </p>
*
* @author xudong
* @since 2022-02-17
*/
public interface TopicFollowRelMapper extends BaseMapper<TopicFollowRelEntity> {
List<String> selectTopicIdByUserId(@Param("userId")String userId);
TopicFollowRelEntity queryOneByTopicIdAndUserId(@Param("topicId")String topicId,@Param("userId")String userId);
}
package com.tanpu.community.dao.mapper.community; package com.tanpu.community.dao.mapper.community;
import com.tanpu.community.dao.entity.community.TopicEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tanpu.community.dao.entity.community.TopicEntity;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Select;
import java.util.Collection;
import java.util.List; import java.util.List;
/** /**
...@@ -18,4 +18,10 @@ import java.util.List; ...@@ -18,4 +18,10 @@ import java.util.List;
public interface TopicMapper extends BaseMapper<TopicEntity> { public interface TopicMapper extends BaseMapper<TopicEntity> {
@Select("select * from topic where id>#{startId} and delete_tag=0 and is_conceal=0 order by id asc limit #{size}") @Select("select * from topic where id>#{startId} and delete_tag=0 and is_conceal=0 order by id asc limit #{size}")
List<TopicEntity> selectGtIdPageable(@Param("startId") Long startId, @Param("size") Integer size); List<TopicEntity> selectGtIdPageable(@Param("startId") Long startId, @Param("size") Integer size);
List<TopicEntity> selectAllByTopicIdIn(@Param("topicIdCollection")Collection<String> topicIdCollection);
} }
...@@ -32,4 +32,10 @@ public interface VisitLogMapper extends BaseMapper<VisitLogEntity> { ...@@ -32,4 +32,10 @@ public interface VisitLogMapper extends BaseMapper<VisitLogEntity> {
@Select("select ref_id from visit_log where visitor_id=#{visitorId} and date(create_time) between #{startDate} and #{endDate}") @Select("select ref_id from visit_log where visitor_id=#{visitorId} and date(create_time) between #{startDate} and #{endDate}")
List<String> selectRefIdByVisitorIdAndCreateBetween(@Param("visitorId") String visitorId, @Param("startDate") Date startDate, @Param("endDate") Date endDate); List<String> selectRefIdByVisitorIdAndCreateBetween(@Param("visitorId") String visitorId, @Param("startDate") Date startDate, @Param("endDate") Date endDate);
VisitLogEntity queryLastByVisitorIdAndRefId(@Param("visitorId")String visitorId, @Param("refId")String refId);
} }
...@@ -6,29 +6,42 @@ import com.tanpu.common.constant.ErrorCodeConstant; ...@@ -6,29 +6,42 @@ import com.tanpu.common.constant.ErrorCodeConstant;
import com.tanpu.community.api.beans.qo.TopicFollowQo; import com.tanpu.community.api.beans.qo.TopicFollowQo;
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.FollowTopicReq;
import com.tanpu.community.api.beans.req.topic.TopicSearchReq; import com.tanpu.community.api.beans.req.topic.TopicSearchReq;
import com.tanpu.community.api.enums.OperationTypeEnum;
import com.tanpu.community.api.enums.TopicSpecialPermissionEnum; import com.tanpu.community.api.enums.TopicSpecialPermissionEnum;
import com.tanpu.community.dao.entity.community.TopicEntity; import com.tanpu.community.dao.entity.community.TopicEntity;
import com.tanpu.community.dao.mapper.community.TopicFollowRelMapper;
import com.tanpu.community.service.RankService; import com.tanpu.community.service.RankService;
import com.tanpu.community.service.ThemeService;
import com.tanpu.community.service.TopicService; import com.tanpu.community.service.TopicService;
import com.tanpu.community.util.PageUtils; import com.tanpu.community.util.PageUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service @Service
public class TopicManager { public class TopicManager {
@Autowired @Resource
private TopicService topicService; private TopicService topicService;
@Autowired @Resource
private RankService rankService; private RankService rankService;
@Autowired @Resource
private UserHolder userHolder; private UserHolder userHolder;
@Resource
TopicFollowRelMapper topicFollowRelMapper;
@Resource
private ThemeService themeService;
// 首页-话题标签 // 首页-话题标签
public List<TopicRankQo> getTop4TopicTitles() { public List<TopicRankQo> getTop4TopicTitles() {
return rankService.getRankTopicListTop4(); return rankService.getRankTopicListTop4();
...@@ -42,18 +55,40 @@ public class TopicManager { ...@@ -42,18 +55,40 @@ public class TopicManager {
return PageUtils.page(req.getPage(), topicList); return PageUtils.page(req.getPage(), topicList);
} }
// 关注话题(讨论区)列表 /**
* 关注话题(讨论区)列表
*/
public List<TopicFollowQo> getFollowTopicList() { public List<TopicFollowQo> getFollowTopicList() {
String userId = userHolder.getUserId(); String userId = userHolder.getUserId();
// 全量排序,内存分页 // 查库
topicService.queryFollowTopic(userId); List<TopicFollowQo> topicFollowQos = topicService.queryFollowTopic(userId);
// 从缓存中获取浏览量
Map<String, TopicRankQo> topicMap = rankService.getRankTopicList(null).stream().collect(Collectors.toMap(TopicRankQo::getTopicId, o -> o, (a, b) -> a));
topicFollowQos.stream().forEach(o->{
TopicRankQo topicRankQo = topicMap.get(o.getTopicId());
BeanUtils.copyProperties(topicRankQo,o);
});
// 最新讨论
themeService.queryCommentForTopic(topicFollowQos, userId);
return null; // 排序
topicFollowQos.stream().sorted(Comparator.comparing(TopicFollowQo::getSpecialPermission, Comparator.reverseOrder()).
thenComparing(TopicFollowQo::getLastThemeTime, Comparator.nullsFirst(String::compareTo).reversed()))
.collect(Collectors.toList());
return topicFollowQos;
} }
// 话题详情页 /**
* 话题详情页
* @param topicId
* @return
*/
public CommonResp<TopicRankQo> getDetail(String topicId) { public CommonResp<TopicRankQo> getDetail(String topicId) {
...@@ -90,5 +125,13 @@ public class TopicManager { ...@@ -90,5 +125,13 @@ public class TopicManager {
} }
public void follow(FollowTopicReq req, String userId) {
if (OperationTypeEnum.CONFIRM.getCode().equals(req.getType())) {
topicService.addFollowTopic(req.getTopicId(), userId);
} else if (OperationTypeEnum.CANCEL.getCode().equals(req.getType())) {
topicService.deleteFollowTopic(req.getTopicId(), userId);
}
}
} }
...@@ -178,4 +178,5 @@ public class CommentService { ...@@ -178,4 +178,5 @@ public class CommentService {
} }
} }
...@@ -8,17 +8,21 @@ import com.tanpu.common.exception.BizException; ...@@ -8,17 +8,21 @@ import com.tanpu.common.exception.BizException;
import com.tanpu.common.redis.RedisHelper; import com.tanpu.common.redis.RedisHelper;
import com.tanpu.common.util.JsonUtil; import com.tanpu.common.util.JsonUtil;
import com.tanpu.common.uuid.UuidGenHelper; import com.tanpu.common.uuid.UuidGenHelper;
import com.tanpu.community.api.beans.qo.ThemeQo;
import com.tanpu.community.api.beans.qo.TopicFollowQo;
import com.tanpu.community.api.beans.req.comment.CreateCommentReq; import com.tanpu.community.api.beans.req.comment.CreateCommentReq;
import com.tanpu.community.api.beans.req.theme.ThemeContentReq; import com.tanpu.community.api.beans.req.theme.ThemeContentReq;
import com.tanpu.community.api.enums.DeleteTagEnum; import com.tanpu.community.api.enums.DeleteTagEnum;
import com.tanpu.community.api.enums.ThemeTypeEnum; import com.tanpu.community.api.enums.ThemeTypeEnum;
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.entity.community.TimesCountEntity;
import com.tanpu.community.dao.entity.community.VisitLogEntity;
import com.tanpu.community.dao.mapper.community.ThemeMapper; import com.tanpu.community.dao.mapper.community.ThemeMapper;
import com.tanpu.community.dao.mapper.community.VisitLogMapper;
import com.tanpu.community.util.ConvertUtil;
import com.tanpu.community.util.TimeUtils; import com.tanpu.community.util.TimeUtils;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -38,15 +42,17 @@ public class ThemeService { ...@@ -38,15 +42,17 @@ public class ThemeService {
@Resource @Resource
private ThemeMapper themeMapper; private ThemeMapper themeMapper;
@Autowired @Resource
private UuidGenHelper uuidGenHelper; private UuidGenHelper uuidGenHelper;
@Autowired @Resource
private RedisHelper redisHelper; private RedisHelper redisHelper;
@Resource
private VisitLogMapper visitLogMapper;
@Transactional @Transactional
public void insertTheme(ThemeEntity themeEntity) { public void insertTheme(ThemeEntity themeEntity) {
if (StringUtils.isBlank(themeEntity.getThemeId())){ if (StringUtils.isBlank(themeEntity.getThemeId())) {
themeEntity.setThemeId(uuidGenHelper.getUuidStr()); themeEntity.setThemeId(uuidGenHelper.getUuidStr());
} }
...@@ -147,8 +153,6 @@ public class ThemeService { ...@@ -147,8 +153,6 @@ public class ThemeService {
} }
/** /**
* 根据话题查询最新主题(可分页) * 根据话题查询最新主题(可分页)
* *
...@@ -181,13 +185,14 @@ public class ThemeService { ...@@ -181,13 +185,14 @@ public class ThemeService {
/** /**
* 根据作者查询主题分页列表 * 根据作者查询主题分页列表
*
* @param userIds * @param userIds
* @param pageStart * @param pageStart
* @param pageSize * @param pageSize
* @return * @return
*/ */
public List<ThemeEntity> queryByUserIdsCreateDesc(List<String> userIds, Integer pageStart, Integer pageSize) { public List<ThemeEntity> queryByUserIdsCreateDesc(List<String> userIds, Integer pageStart, Integer pageSize) {
if (CollectionUtils.isEmpty(userIds)){ if (CollectionUtils.isEmpty(userIds)) {
return Collections.emptyList(); return Collections.emptyList();
} }
LambdaQueryWrapper<ThemeEntity> queryWrapper = new LambdaQueryWrapper<ThemeEntity>() LambdaQueryWrapper<ThemeEntity> queryWrapper = new LambdaQueryWrapper<ThemeEntity>()
...@@ -209,11 +214,11 @@ public class ThemeService { ...@@ -209,11 +214,11 @@ public class ThemeService {
return themeMapper.selectCount(new LambdaQueryWrapper<ThemeEntity>() return themeMapper.selectCount(new LambdaQueryWrapper<ThemeEntity>()
.eq(ThemeEntity::getFormerThemeId, themeId) .eq(ThemeEntity::getFormerThemeId, themeId)
.eq(ThemeEntity::getAuthorId, userId) .eq(ThemeEntity::getAuthorId, userId)
.eq(ThemeEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED))>0; .eq(ThemeEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED)) > 0;
} }
public Set<String> getForwardUsers(List<String> themeIds) { public Set<String> getForwardUsers(List<String> themeIds) {
if (CollectionUtils.isEmpty(themeIds)){ if (CollectionUtils.isEmpty(themeIds)) {
return new HashSet<>(); return new HashSet<>();
} }
return themeMapper.selectList(new LambdaQueryWrapper<ThemeEntity>() return themeMapper.selectList(new LambdaQueryWrapper<ThemeEntity>()
...@@ -223,13 +228,12 @@ public class ThemeService { ...@@ -223,13 +228,12 @@ public class ThemeService {
} }
@Transactional @Transactional
public void deleteById(String themeId,String userId) { public void deleteById(String themeId, String userId) {
ThemeEntity themeEntity = themeMapper.selectOne(new LambdaQueryWrapper<ThemeEntity>() ThemeEntity themeEntity = themeMapper.selectOne(new LambdaQueryWrapper<ThemeEntity>()
.eq(ThemeEntity::getThemeId, themeId)); .eq(ThemeEntity::getThemeId, themeId));
if (themeEntity == null || !themeEntity.getAuthorId().equals(userId)) { if (themeEntity == null || !themeEntity.getAuthorId().equals(userId)) {
throw new BizException("主题与用户不匹配,id:" + themeId+",userId"+userId); throw new BizException("主题与用户不匹配,id:" + themeId + ",userId" + userId);
} }
themeEntity.setDeleteTag(DeleteTagEnum.DELETED.getCode()); themeEntity.setDeleteTag(DeleteTagEnum.DELETED.getCode());
themeMapper.updateById(themeEntity); themeMapper.updateById(themeEntity);
...@@ -257,7 +261,7 @@ public class ThemeService { ...@@ -257,7 +261,7 @@ public class ThemeService {
public void updateReportStatus(String themeId) { public void updateReportStatus(String themeId) {
ThemeEntity themeEntity = queryByThemeId(themeId); ThemeEntity themeEntity = queryByThemeId(themeId);
if (themeEntity == null) { if (themeEntity == null) {
throw new BizException("主题未找到,id:"+themeId); throw new BizException("主题未找到,id:" + themeId);
} }
themeEntity.setReportStatus(ReportStatusEnum.REPORTED.getCode()); themeEntity.setReportStatus(ReportStatusEnum.REPORTED.getCode());
themeMapper.updateById(themeEntity); themeMapper.updateById(themeEntity);
...@@ -265,12 +269,12 @@ public class ThemeService { ...@@ -265,12 +269,12 @@ public class ThemeService {
//统计主题集合的浏览量 //统计主题集合的浏览量
public Map<String, Integer> getForwardCountMap(List<String> themeIds) { public Map<String, Integer> getForwardCountMap(List<String> themeIds) {
if (CollectionUtils.isEmpty(themeIds)){ if (CollectionUtils.isEmpty(themeIds)) {
return new HashMap<String, Integer>(); return new HashMap<String, Integer>();
} }
LambdaQueryWrapper<ThemeEntity> wrapper = new LambdaQueryWrapper<ThemeEntity>() LambdaQueryWrapper<ThemeEntity> wrapper = new LambdaQueryWrapper<ThemeEntity>()
.eq(ThemeEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED) .eq(ThemeEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED)
.in(ThemeEntity::getFormerThemeId,themeIds) .in(ThemeEntity::getFormerThemeId, themeIds)
.groupBy(ThemeEntity::getFormerThemeId); .groupBy(ThemeEntity::getFormerThemeId);
return themeMapper.selectCountByThemeIds(wrapper).stream() return themeMapper.selectCountByThemeIds(wrapper).stream()
.collect(Collectors.toMap(TimesCountEntity::getId, TimesCountEntity::getTimes)); .collect(Collectors.toMap(TimesCountEntity::getId, TimesCountEntity::getTimes));
...@@ -279,7 +283,7 @@ public class ThemeService { ...@@ -279,7 +283,7 @@ public class ThemeService {
public List<ThemeEntity> queryAllForward() { public List<ThemeEntity> queryAllForward() {
return themeMapper.selectList(new LambdaQueryWrapper<ThemeEntity>() return themeMapper.selectList(new LambdaQueryWrapper<ThemeEntity>()
.eq(ThemeEntity::getThemeType, ThemeTypeEnum.FORWARD.getCode()) .eq(ThemeEntity::getThemeType, ThemeTypeEnum.FORWARD.getCode())
.eq(ThemeEntity::getDeleteTag,DeleteTagEnum.NOT_DELETED.getCode()) .eq(ThemeEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode())
.orderByAsc(ThemeEntity::getCreateTime)); .orderByAsc(ThemeEntity::getCreateTime));
} }
...@@ -297,4 +301,33 @@ public class ThemeService { ...@@ -297,4 +301,33 @@ public class ThemeService {
this.insertTheme(themeEntity); this.insertTheme(themeEntity);
return themeEntity.getThemeId(); return themeEntity.getThemeId();
} }
public void queryCommentForTopic(List<TopicFollowQo> topicQos, String userId) {
for (TopicFollowQo topic : topicQos) {
String topicId = topic.getTopicId();
// 最近的一条讨论
ThemeEntity themeEntity = themeMapper.queryOneByTopicIdOrderByUpdateTimeDesc(topicId);
if (themeEntity != null) {
ThemeQo themeQo = ConvertUtil.themeEntityToQo(themeEntity);
topic.setLastTheme(themeQo.getAuthorId() + themeQo.content.get(0).getValue());
topic.setLastThemeTime(TimeUtils.format(themeEntity.getUpdateTime()));
}
// 查询更新条数
VisitLogEntity visitLogEntity = visitLogMapper.queryLastByVisitorIdAndRefId(userId, topicId);
if (visitLogEntity != null) {
Integer updates = themeMapper.countByTopicIdAndCreateTimeAfter(topicId, visitLogEntity.getUpdateTime());
topic.setUpdateCount(updates);
} else {
topic.setUpdateCount(0);
}
}
}
} }
...@@ -2,16 +2,20 @@ package com.tanpu.community.service; ...@@ -2,16 +2,20 @@ package com.tanpu.community.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tanpu.common.uuid.UuidGenHelper; import com.tanpu.common.uuid.UuidGenHelper;
import com.tanpu.community.api.beans.qo.TopicRankQo; import com.tanpu.community.api.beans.qo.TopicFollowQo;
import com.tanpu.community.api.enums.DeleteTagEnum;
import com.tanpu.community.api.enums.StatusEnum; import com.tanpu.community.api.enums.StatusEnum;
import com.tanpu.community.dao.entity.community.TopicEntity; import com.tanpu.community.dao.entity.community.TopicEntity;
import com.tanpu.community.dao.entity.community.TopicFollowRelEntity;
import com.tanpu.community.dao.mapper.community.TopicFollowRelMapper;
import com.tanpu.community.dao.mapper.community.TopicMapper; import com.tanpu.community.dao.mapper.community.TopicMapper;
import com.tanpu.community.util.ConvertUtil;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
...@@ -22,10 +26,18 @@ import java.util.List; ...@@ -22,10 +26,18 @@ import java.util.List;
public class TopicService { public class TopicService {
@Resource @Resource
private TopicMapper topicMapper; TopicFollowRelMapper topicFollowRelMapper;
@Autowired @Resource
TopicMapper topicMapper;
@Resource
private UuidGenHelper uuidGenHelper; private UuidGenHelper uuidGenHelper;
@Resource
private ThemeService themeService;
@Resource
private VisitLogService visitLogService;
public List<TopicEntity> queryAll() { public List<TopicEntity> queryAll() {
List<TopicEntity> retList = new ArrayList<>(); List<TopicEntity> retList = new ArrayList<>();
...@@ -43,7 +55,6 @@ public class TopicService { ...@@ -43,7 +55,6 @@ public class TopicService {
} }
public TopicEntity queryOnlineTopicById(String topicId) { public TopicEntity queryOnlineTopicById(String topicId) {
return topicMapper.selectOne(new LambdaQueryWrapper<TopicEntity>() return topicMapper.selectOne(new LambdaQueryWrapper<TopicEntity>()
.eq(TopicEntity::getTopicId, topicId) .eq(TopicEntity::getTopicId, topicId)
...@@ -55,7 +66,7 @@ public class TopicService { ...@@ -55,7 +66,7 @@ public class TopicService {
public String queryTitleById(String topicId) { public String queryTitleById(String topicId) {
TopicEntity topicEntity = topicMapper.selectOne(new LambdaQueryWrapper<TopicEntity>() TopicEntity topicEntity = topicMapper.selectOne(new LambdaQueryWrapper<TopicEntity>()
.eq(TopicEntity::getTopicId, topicId)); .eq(TopicEntity::getTopicId, topicId));
return topicEntity!=null?topicEntity.getTopicTitle():null; return topicEntity != null ? topicEntity.getTopicTitle() : null;
} }
public List<TopicEntity> queryByIds(List<String> topicIds) { public List<TopicEntity> queryByIds(List<String> topicIds) {
...@@ -65,7 +76,49 @@ public class TopicService { ...@@ -65,7 +76,49 @@ public class TopicService {
return topicMapper.selectList(new LambdaQueryWrapper<TopicEntity>().in(TopicEntity::getTopicId, topicIds)); return topicMapper.selectList(new LambdaQueryWrapper<TopicEntity>().in(TopicEntity::getTopicId, topicIds));
} }
public List<TopicRankQo> queryFollowTopic(String userId) { public List<TopicFollowQo> queryFollowTopic(String userId) {
return null; // 用户的关注列表(包括专属)
List<String> followTopicIds = topicFollowRelMapper.selectTopicIdByUserId(userId);
if (CollectionUtils.isEmpty(followTopicIds)){
return Collections.emptyList();
}
List<TopicEntity> topicEntities = topicMapper.selectAllByTopicIdIn(followTopicIds);
List<TopicFollowQo> topicFollowQos = ConvertUtil.topicEntityToFollowQos(topicEntities);
return topicFollowQos;
}
public void followTopic(String topicId, String userId) {
}
public boolean addFollowTopic(String topicId, String userId) {
TopicFollowRelEntity searchResult = topicFollowRelMapper.queryOneByTopicIdAndUserId(topicId, userId);
if (searchResult == null) {
TopicFollowRelEntity entity = TopicFollowRelEntity.builder()
.topicId(topicId)
.userId(userId)
.followTime(LocalDateTime.now())
.build();
topicFollowRelMapper.insert(entity);
return true;
} else {
searchResult.setFollowTime(LocalDateTime.now());
searchResult.setDeleteTag(DeleteTagEnum.NOT_DELETED.getCode());
topicFollowRelMapper.updateById(searchResult);
return false;
}
}
public void deleteFollowTopic(String topicId, String userId) {
TopicFollowRelEntity searchResult = topicFollowRelMapper.queryOneByTopicIdAndUserId(topicId, userId);
if (searchResult != null){
searchResult.setUnfollowTime(LocalDateTime.now());
searchResult.setDeleteTag(DeleteTagEnum.DELETED.getCode());
topicFollowRelMapper.updateById(searchResult);
}
} }
} }
...@@ -138,4 +138,13 @@ public class VisitLogService { ...@@ -138,4 +138,13 @@ public class VisitLogService {
return visitLogMapper.selectCountByThemeIds(wrapper).stream() return visitLogMapper.selectCountByThemeIds(wrapper).stream()
.collect(Collectors.toMap(TimesCountEntity::getId, TimesCountEntity::getTimes)); .collect(Collectors.toMap(TimesCountEntity::getId, TimesCountEntity::getTimes));
} }
// 查询讨论区最近浏览
public Integer queryLastTopicVisit(String theme) {
return visitLogMapper.selectCount(new LambdaQueryWrapper<VisitLogEntity>()
.eq(VisitLogEntity::getRefId, theme)
.eq(VisitLogEntity::getRefType, PageEnum.COMM_VISIT_THEME.getId()));
}
} }
...@@ -51,7 +51,7 @@ public class ConvertUtil { ...@@ -51,7 +51,7 @@ public class ConvertUtil {
List<ThemeContentQo> themeContentQos = JsonUtil.toBean(themeEntity.getContent(), new TypeReference<List<ThemeContentQo>>() { List<ThemeContentQo> themeContentQos = JsonUtil.toBean(themeEntity.getContent(), new TypeReference<List<ThemeContentQo>>() {
}); });
// 屏蔽手机号和邮箱 // 屏蔽手机号和邮箱
themeContentQos.stream().filter(o->RelTypeEnum.TEXT.type.equals(o.getType())).forEach(o->o.setValue(OtherUtil.blockPhoneAndEmail(o.getValue()))); themeContentQos.stream().filter(o -> RelTypeEnum.TEXT.type.equals(o.getType())).forEach(o -> o.setValue(OtherUtil.blockPhoneAndEmail(o.getValue())));
themeQO.setContent(themeContentQos); themeQO.setContent(themeContentQos);
return themeQO; return themeQO;
...@@ -133,6 +133,19 @@ public class ConvertUtil { ...@@ -133,6 +133,19 @@ public class ConvertUtil {
return topicEntities.stream().map(ConvertUtil::topicEntityToHotQo).collect(Collectors.toList()); return topicEntities.stream().map(ConvertUtil::topicEntityToHotQo).collect(Collectors.toList());
} }
public static List<TopicFollowQo> topicEntityToFollowQos(List<TopicEntity> topicEntities) {
if (topicEntities == null) {
return Collections.emptyList();
}
return topicEntities.stream().map(ConvertUtil::topicEntityToFollowQo).collect(Collectors.toList());
}
private static TopicFollowQo topicEntityToFollowQo(TopicEntity topicEntity) {
TopicFollowQo topicFollowQo = new TopicFollowQo();
BeanUtils.copyProperties(topicEntity, topicFollowQo);
return topicFollowQo;
}
public static CommentQo commentEntity2Qo(CommentEntity entity) { public static CommentQo commentEntity2Qo(CommentEntity entity) {
CommentQo qo = new CommentQo(); CommentQo qo = new CommentQo();
......
...@@ -7,10 +7,16 @@ apollo.bootstrap.enabled: false ...@@ -7,10 +7,16 @@ apollo.bootstrap.enabled: false
# bootstrap: # bootstrap:
# namespaces: application.yml # namespaces: application.yml
springfox:
documentation:
swagger:
v2:
path: /api-docs
server: server:
port: 8080 port: 8080
servlet: servlet:
context-path: /community context-path: /community2
spring.datasource: spring.datasource:
community: community:
......
...@@ -3,6 +3,21 @@ ...@@ -3,6 +3,21 @@
<mapper namespace="com.tanpu.community.dao.mapper.community.ThemeMapper"> <mapper namespace="com.tanpu.community.dao.mapper.community.ThemeMapper">
<!-- 通用查询映射结果 --> <!-- 通用查询映射结果 -->
<sql id="Base_Column_List">
id,
theme_id,
title,
theme_type,
content,
author_id,
former_theme_id,
topic_id,
review_status,
report_status,
create_time,
update_time,
delete_tag
</sql>
<resultMap id="BaseResultMap" type="com.tanpu.community.dao.entity.community.ThemeEntity"> <resultMap id="BaseResultMap" type="com.tanpu.community.dao.entity.community.ThemeEntity">
<id column="id" property="id" /> <id column="id" property="id" />
<result column="theme_id" property="themeId" /> <result column="theme_id" property="themeId" />
...@@ -19,4 +34,18 @@ ...@@ -19,4 +34,18 @@
<result column="delete_tag" property="deleteTag" /> <result column="delete_tag" property="deleteTag" />
</resultMap> </resultMap>
<!--auto generated by MybatisCodeHelper on 2022-02-17-->
<select id="queryOneByTopicIdOrderByUpdateTimeDesc" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from theme
where topic_id=#{topicId} order by update_time desc limit 1
</select>
<!--auto generated by MybatisCodeHelper on 2022-02-17-->
<select id="countByTopicIdAndCreateTimeAfter" resultType="java.lang.Integer">
select count(1)
from theme
where topic_id=#{topicId} and create_time <![CDATA[>]]> #{minCreateTime}
</select>
</mapper> </mapper>
...@@ -3,6 +3,21 @@ ...@@ -3,6 +3,21 @@
<mapper namespace="com.tanpu.community.dao.mapper.community.TopicMapper"> <mapper namespace="com.tanpu.community.dao.mapper.community.TopicMapper">
<!-- 通用查询映射结果 --> <!-- 通用查询映射结果 -->
<sql id="Base_Column_List">
id,
topic_id,
topic_title,
topic_desc,
cover_img,
special_permission,
sync_corp_wechat,
is_top,
is_conceal,
view_cnt_adjust,
create_time,
update_time,
delete_tag
</sql>
<resultMap id="BaseResultMap" type="com.tanpu.community.dao.entity.community.TopicEntity"> <resultMap id="BaseResultMap" type="com.tanpu.community.dao.entity.community.TopicEntity">
<id column="id" property="id" /> <id column="id" property="id" />
<result column="topic_id" property="topicId" /> <result column="topic_id" property="topicId" />
...@@ -19,4 +34,16 @@ ...@@ -19,4 +34,16 @@
<result column="delete_tag" property="deleteTag" /> <result column="delete_tag" property="deleteTag" />
</resultMap> </resultMap>
<!--auto generated by MybatisCodeHelper on 2022-02-17-->
<select id="selectAllByTopicIdIn" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from topic
where topic_id in
<foreach item="item" index="index" collection="topicIdCollection"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
</mapper> </mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tanpu.community.dao.mapper.community.TopicFollowRelMapper">
<!-- 通用查询映射结果 -->
<sql id="Base_Column_List">
id,
topic_id,
user_id,
follow_time,
unfollow_time,
create_time,
update_time,
delete_tag
</sql>
<resultMap id="BaseResultMap" type="com.tanpu.community.dao.entity.community.TopicFollowRelEntity">
<id column="id" property="id" />
<result column="topic_id" property="topicId" />
<result column="user_id" property="userId" />
<result column="follow_time" property="followTime" />
<result column="unfollow_time" property="unfollowTime" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
<result column="delete_tag" property="deleteTag" />
</resultMap>
<!--auto generated by MybatisCodeHelper on 2022-02-17-->
<select id="selectTopicIdByUserId" resultType="java.lang.String">
select topic_id
from topic_follow_rel
where user_id=#{userId}
and delete_tag = 0
</select>
<!--auto generated by MybatisCodeHelper on 2022-02-17-->
<select id="queryOneByTopicIdAndUserId" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from topic_follow_rel
where topic_id=#{topicId} and user_id=#{userId}
</select>
</mapper>
...@@ -3,6 +3,18 @@ ...@@ -3,6 +3,18 @@
<mapper namespace="com.tanpu.community.dao.mapper.community.VisitLogMapper"> <mapper namespace="com.tanpu.community.dao.mapper.community.VisitLogMapper">
<!-- 通用查询映射结果 --> <!-- 通用查询映射结果 -->
<sql id="Base_Column_List">
id,
ident,
visitor_id,
author_id,
ref_id,
ref_type,
duration,
create_time,
update_time,
delete_tag
</sql>
<resultMap id="BaseResultMap" type="com.tanpu.community.dao.entity.community.VisitLogEntity"> <resultMap id="BaseResultMap" type="com.tanpu.community.dao.entity.community.VisitLogEntity">
<id column="id" property="id" /> <id column="id" property="id" />
<result column="ident" property="ident" /> <result column="ident" property="ident" />
...@@ -16,4 +28,12 @@ ...@@ -16,4 +28,12 @@
<result column="delete_tag" property="deleteTag" /> <result column="delete_tag" property="deleteTag" />
</resultMap> </resultMap>
<!--auto generated by MybatisCodeHelper on 2022-02-17-->
<select id="queryLastByVisitorIdAndRefId" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from visit_log
where visitor_id=#{visitorId} and ref_id=#{refId}
order by update_time limit 1
</select>
</mapper> </mapper>
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