[fix]修改视频点赞逻辑

This commit is contained in:
王庆祥 2025-09-29 19:04:13 +08:00
parent 1cee8788f2
commit ec715206ef
18 changed files with 264 additions and 124 deletions

View File

@ -27,7 +27,7 @@ public class AppProductController {
@Operation(summary = "查询商品信息列表") @Operation(summary = "查询商品信息列表")
@PostMapping("page") @PostMapping("page")
public R<IPage<ProductVO>> page(@RequestBody ProductBo query, Page<Product> page) { public R<IPage<ProductVO>> page(@RequestBody ProductBo query, Page<Product> page) {
IPage<ProductVO> resultPage = service.getProduct(page, query); IPage<ProductVO> resultPage = service.getProduct(query.getPage(), query);
return R.ok(resultPage); return R.ok(resultPage);
} }

View File

@ -41,7 +41,7 @@ public class AppSearchController {
try { try {
LoginUser loginUser = LoginHelper.getLoginUser(); LoginUser loginUser = LoginHelper.getLoginUser();
if (loginUser == null) { if (loginUser == null) {
throw new ServiceException("用户未登录"); return R.notLogin();
} }
searchBO.setUserId(String.valueOf(loginUser.getUserId())); searchBO.setUserId(String.valueOf(loginUser.getUserId()));
} catch (Exception e) { } catch (Exception e) {

View File

@ -2,7 +2,7 @@
spring.boot.admin.client: spring.boot.admin.client:
# 增加客户端开关 # 增加客户端开关
enabled: false enabled: false
url: http://192.168.1.65:9090/admin url: http://82.168.1.65:9090/admin
instance: instance:
service-host-type: IP service-host-type: IP
metadata: metadata:
@ -98,9 +98,9 @@ spring:
spring.data: spring.data:
redis: redis:
# 地址 # 地址
host: 192.168.1.65 host: 82.156.121.2
# 端口默认为6379 # 端口默认为6379
port: 16379 port: 26379
# 数据库索引 # 数据库索引
database: 0 database: 0
# 密码(如没有密码请注释掉) # 密码(如没有密码请注释掉)
@ -136,7 +136,7 @@ redisson:
--- # RocketMQ 配置 --- # RocketMQ 配置
rocketmq: rocketmq:
# RocketMQ 服务器地址 # RocketMQ 服务器地址
name-server: 192.168.1.65:9876 name-server: 82.156.121.2:9876
# 生产者配置 # 生产者配置
producer: producer:
# 生产者组名 # 生产者组名

View File

@ -57,5 +57,25 @@ public interface GlobalConstants {
* 热点视频 redis key * 热点视频 redis key
*/ */
String HOT_VLOG_TAG = "HOT"; String HOT_VLOG_TAG = "HOT";
/**
* 我喜欢的视频 redis key
*/
String GLOBAL_VLOG_LIKED= "global:vlog:member:";
String GLOBAL_VLOG_MY_LIKED_LIST= "global:vlog:myliked:list";
/**
* 我喜欢的视频数量 redis key
*/
String GLOBAL_VLOG_MY_LIKED_COUNT = "global:vlog:myliked:count:";
/**
* 视频被喜欢的数量 redis key
*/
String GLOBAL_VLOG_LIKED_COUNT = "global:vlog:myvlogliked:count:";
String GLOBAL_VLOG_ALL_LIKED_COUNT="global:vlog:myallliked:count:";
String GLOBAL_MEMBER_FANS_COUNT="global:member:myfans:count:";
} }

View File

@ -171,6 +171,19 @@ public class RedisCache
} }
} }
/**
* 删除key
*
* @param key
* @param dataMap
*/
public <T> void removeMapValue(final String key, final Map<String, T> dataMap)
{
if (dataMap != null) {
redisTemplate.opsForHash().delete(key, dataMap.keySet().toArray());
}
}
/** /**
* 获得缓存的Map * 获得缓存的Map
* *

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wzj.soopin.content.domain.bo.AuditVlogBO; import com.wzj.soopin.content.domain.bo.AuditVlogBO;
import com.wzj.soopin.content.domain.bo.VlogBO; import com.wzj.soopin.content.domain.bo.VlogBO;
import com.wzj.soopin.content.domain.vo.IndexVlogVO; import com.wzj.soopin.content.domain.vo.IndexVlogVO;
import com.wzj.soopin.content.service.IMyLikeVlogService;
import com.wzj.soopin.content.service.IVlogPullService; import com.wzj.soopin.content.service.IVlogPullService;
import com.wzj.soopin.content.service.IVlogPushService; import com.wzj.soopin.content.service.IVlogPushService;
import com.wzj.soopin.content.service.VlogService; import com.wzj.soopin.content.service.VlogService;
@ -34,6 +35,7 @@ public class VlogController extends BaseInfoProperties {
public final RedisOperator redis; public final RedisOperator redis;
private final IVlogPushService vlogPushService; private final IVlogPushService vlogPushService;
private final IVlogPullService vlogPullService; private final IVlogPullService vlogPullService;
private final IMyLikeVlogService myLikeVlogService;
@Operation(summary = "查询列表") @Operation(summary = "查询列表")
@PostMapping("/page") @PostMapping("/page")
@ -162,7 +164,7 @@ public class VlogController extends BaseInfoProperties {
@Operation(summary = "查询视频被点赞数量") @Operation(summary = "查询视频被点赞数量")
@PostMapping("/totalLikedCounts") @PostMapping("/totalLikedCounts")
public R<Integer> totalLikedCounts(@RequestParam String vlogId) { public R<Integer> totalLikedCounts(@RequestParam String vlogId) {
return R.ok(vlogService.getVlogBeLikedCounts(vlogId)); return R.ok(myLikeVlogService.getVLogLikeCount(vlogId));
} }
@Operation(summary = "推送视频") @Operation(summary = "推送视频")

View File

@ -10,7 +10,6 @@ import lombok.EqualsAndHashCode;
import org.dromara.common.core.domain.BaseBO; import org.dromara.common.core.domain.BaseBO;
import org.dromara.common.core.domain.model.BaseAudit; import org.dromara.common.core.domain.model.BaseAudit;
@TableName("cont_my_liked_vlog")
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class MyLikedVlogBO extends BaseBO<MyLikedVlog> { public class MyLikedVlogBO extends BaseBO<MyLikedVlog> {
@ -20,7 +19,7 @@ public class MyLikedVlogBO extends BaseBO<MyLikedVlog> {
/** /**
* 用户id * 用户id
*/ */
private String userId; private String memberId;
/** /**
* 喜欢的短视频id * 喜欢的短视频id
@ -31,7 +30,7 @@ public class MyLikedVlogBO extends BaseBO<MyLikedVlog> {
@Override @Override
public LambdaQueryWrapper<MyLikedVlog> toWrapper() { public LambdaQueryWrapper<MyLikedVlog> toWrapper() {
return super.toWrapper().eq(userId!=null,MyLikedVlog::getUserId,userId) return super.toWrapper().eq(memberId!=null,MyLikedVlog::getMemberId,memberId)
.eq(vlogId!=null,MyLikedVlog::getVlogId,vlogId); .eq(vlogId!=null,MyLikedVlog::getVlogId,vlogId);
} }
} }

View File

@ -20,7 +20,7 @@ public class MyLikedVlog extends BaseAudit {
/** /**
* 用户id * 用户id
*/ */
private String userId; private Long memberId;
/** /**
* 喜欢的短视频id * 喜欢的短视频id
@ -31,4 +31,5 @@ public class MyLikedVlog extends BaseAudit {
} }

View File

@ -0,0 +1,23 @@
package com.wzj.soopin.content.enums;
public enum CommentStatusEnum {
NORMAL(0, "正常"),
DELETE(1, "删除"),
DISABLE(2, "禁用");
private final Integer value;
private final String info;
CommentStatusEnum(Integer value, String info) {
this.value = value;
this.info = info;
}
public Integer getValue() {
return value;
}
public String getInfo() {
return info;
}
}

View File

@ -172,4 +172,6 @@ public interface VlogMapper extends BaseMapper<Vlog> {
IPage<String> getVlogForUser(Page<IndexVlogVO> page, @Param("memberId") Long memberId); IPage<String> getVlogForUser(Page<IndexVlogVO> page, @Param("memberId") Long memberId);
int readVlog(@Param("memberId") Long memberId, @Param("vlogId") String vlogId); int readVlog(@Param("memberId") Long memberId, @Param("vlogId") String vlogId);
List<IndexVlogVO> selectUserLikeVlogList(@Param("memberId") Long memberId);
} }

View File

@ -75,4 +75,9 @@ public interface CommentService {
* 发布评论 * 发布评论
*/ */
void publishComment(CommentBO bo); void publishComment(CommentBO bo);
/**
* 获取评论数量
*/
Integer getCommentCount(String vlogId);
} }

View File

@ -0,0 +1,41 @@
package com.wzj.soopin.content.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.wzj.soopin.content.domain.po.MyLikedVlog;
public interface IMyLikeVlogService extends IService<MyLikedVlog> {
/**
* 喜欢短视频
* @param vlogId 短视频id
* @return 是否喜欢成功
*/
boolean like(String vlogId,Long memberId);
/**
* 取消喜欢短视频
* @param vlogId 短视频id
* @return 是否取消喜欢成功
*/
boolean unLike(String vlogId,Long memberId);
/**
* 获取短视频被喜欢的数量
* @param vlogId 短视频id
* @return 被喜欢的数量
*/
Integer getVLogLikeCount(String vlogId);
/**
* 获取用户的所有点赞
* @param memberId 用户id
* @return 喜欢的短视频数量
*/
Integer getMyVlogLikeCount(Long memberId);
boolean doILikeVlog(String vlogId,Long memberId);
}

View File

@ -54,10 +54,6 @@ public interface VlogService extends IService<Vlog> {
*/ */
public void userUnLikeVlog(String userId, String vlogId); public void userUnLikeVlog(String userId, String vlogId);
/**
* 获得用户点赞视频的总数
*/
public Integer getVlogBeLikedCounts(String vlogId);
/** /**
* 查询用户点赞过的短视频 * 查询用户点赞过的短视频

View File

@ -3,6 +3,7 @@ package com.wzj.soopin.content.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wzj.soopin.content.enums.CommentStatusEnum;
import org.dromara.common.core.constant.BaseInfoProperties; import org.dromara.common.core.constant.BaseInfoProperties;
import com.wzj.soopin.content.domain.bo.CommentBO; import com.wzj.soopin.content.domain.bo.CommentBO;
import com.wzj.soopin.content.domain.po.Comment; import com.wzj.soopin.content.domain.po.Comment;
@ -28,6 +29,7 @@ import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.redis.redis.RedisCache; import org.dromara.common.redis.redis.RedisCache;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -442,4 +444,11 @@ public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> impl
mqMessage.setData(params); mqMessage.setData(params);
return mqMessage; return mqMessage;
} }
@Override
public Integer getCommentCount(String vlogId) {
return baseMapper.selectCount(new LambdaQueryWrapper<Comment>().eq(Comment::getVlogId, vlogId)
.eq(Comment::getStatus, CommentStatusEnum.NORMAL.getValue())).intValue();
}
} }

View File

@ -0,0 +1,63 @@
package com.wzj.soopin.content.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wzj.soopin.content.domain.po.MyLikedVlog;
import com.wzj.soopin.content.mapper.MyLikedVlogMapper;
import com.wzj.soopin.content.service.IMyLikeVlogService;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.redis.utils.RedisUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class MyLikeVlogServiceImpl extends ServiceImpl<MyLikedVlogMapper, MyLikedVlog> implements IMyLikeVlogService {
@Override
@Cacheable(cacheNames = GlobalConstants.GLOBAL_VLOG_LIKED, key = "#vlogId + '_' + #memberId")
public boolean like(String vlogId, Long memberId) {
MyLikedVlog myLikedVlog = new MyLikedVlog();
myLikedVlog.setMemberId(memberId);
myLikedVlog.setVlogId(vlogId.toString());
return this.save(myLikedVlog);
}
@Override
@CacheEvict(cacheNames = GlobalConstants.GLOBAL_VLOG_LIKED, key = "#vlogId + '_' + #memberId")
public boolean unLike(String vlogId, Long memberId) {
return this.remove(new LambdaQueryWrapper<MyLikedVlog>()
.eq(MyLikedVlog::getMemberId, memberId.toString())
.eq(MyLikedVlog::getVlogId, vlogId.toString()));
}
@Cacheable(cacheNames = GlobalConstants.GLOBAL_VLOG_MY_LIKED_LIST, key = "#memberId")
public List<Long> myLikeVlog(Long memberId) {
return this.baseMapper.selectList(new LambdaQueryWrapper<MyLikedVlog>()
.eq(MyLikedVlog::getMemberId, memberId.toString()))
.stream().map(MyLikedVlog::getVlogId).map(Long::valueOf).collect(Collectors.toList());
}
@Cacheable(cacheNames = GlobalConstants.GLOBAL_VLOG_LIKED_COUNT, key = "#vlogId")
public Integer getVLogLikeCount(String vlogId) {
return this.baseMapper.selectCount(new LambdaQueryWrapper<MyLikedVlog>()
.eq(MyLikedVlog::getVlogId, vlogId.toString())).intValue();
}
@Cacheable(cacheNames = GlobalConstants.GLOBAL_VLOG_ALL_LIKED_COUNT, key = "#memberId")
public Integer getMyVlogLikeCount(Long memberId) {
return this.baseMapper.selectCount(new LambdaQueryWrapper<MyLikedVlog>()
.eq(MyLikedVlog::getMemberId, memberId.toString())).intValue();
}
public boolean doILikeVlog(String vlogId, Long memberId) {
Boolean doILike = RedisUtils.getCacheMapValue(GlobalConstants.GLOBAL_VLOG_LIKED, vlogId + "_" + memberId);
return doILike != null && doILike;
}
}

View File

@ -13,7 +13,6 @@ import com.wzj.soopin.content.domain.bo.AuditVlogBO;
import com.wzj.soopin.content.domain.bo.MyListBO; import com.wzj.soopin.content.domain.bo.MyListBO;
import com.wzj.soopin.content.domain.bo.SearchBO; import com.wzj.soopin.content.domain.bo.SearchBO;
import com.wzj.soopin.content.domain.bo.VlogBO; import com.wzj.soopin.content.domain.bo.VlogBO;
import com.wzj.soopin.content.domain.po.MyLikedVlog;
import com.wzj.soopin.content.domain.po.Vlog; import com.wzj.soopin.content.domain.po.Vlog;
import com.wzj.soopin.content.domain.vo.IndexVlogVO; import com.wzj.soopin.content.domain.vo.IndexVlogVO;
import com.wzj.soopin.content.enums.VlogStatusEnum; import com.wzj.soopin.content.enums.VlogStatusEnum;
@ -22,6 +21,8 @@ import com.wzj.soopin.content.mapper.CommentMapper;
import com.wzj.soopin.content.mapper.MyLikedVlogMapper; import com.wzj.soopin.content.mapper.MyLikedVlogMapper;
import com.wzj.soopin.content.mapper.VlogMapper; import com.wzj.soopin.content.mapper.VlogMapper;
import com.wzj.soopin.content.mapper.VlogMapperCustom; import com.wzj.soopin.content.mapper.VlogMapperCustom;
import com.wzj.soopin.content.service.CommentService;
import com.wzj.soopin.content.service.IMyLikeVlogService;
import com.wzj.soopin.content.service.MsgService; import com.wzj.soopin.content.service.MsgService;
import com.wzj.soopin.content.service.VlogService; import com.wzj.soopin.content.service.VlogService;
import com.wzj.soopin.content.utils.RedisOperator; import com.wzj.soopin.content.utils.RedisOperator;
@ -44,10 +45,9 @@ import org.dromara.common.mq.enums.MQMessageType;
import org.dromara.common.mq.enums.MessageActionEnum; import org.dromara.common.mq.enums.MessageActionEnum;
import org.dromara.common.mq.utils.MqUtil; import org.dromara.common.mq.utils.MqUtil;
import org.dromara.common.redis.redis.RedisCache; import org.dromara.common.redis.redis.RedisCache;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -57,7 +57,8 @@ import java.time.ZoneOffset;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.dromara.common.core.constant.BaseInfoProperties.*; import static org.dromara.common.core.constant.BaseInfoProperties.REDIS_USER_BLOCK;
import static org.dromara.common.core.constant.BaseInfoProperties.REDIS_VIDEO_BLOCK;
@Slf4j @Slf4j
@Service @Service
@ -66,19 +67,19 @@ public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements Vl
private final VlogMapper vlogMapper; private final VlogMapper vlogMapper;
private final VlogMapperCustom vlogMapperCustom; private final VlogMapperCustom vlogMapperCustom;
private final MyLikedVlogMapper myLikedVlogMapper; private final IMyLikeVlogService myLikeVlogService;
private final IFansService fansService; private final IFansService fansService;
private final MsgService msgService; private final MsgService msgService;
private final Sid sid; private final Sid sid;
private final CommentMapper commentMapper; private final CommentMapper commentMapper;
private final MemberMapper memberMapper; private final MemberMapper memberMapper;
private final RedisCache cache;
private final RedisCache redisCache; private final RedisCache redisCache;
private final VlogConvert vlogConvert; private final VlogConvert vlogConvert;
@Autowired private final IMemberService memberService;
private IMemberService memberService; private final RedisOperator redis;
@Autowired private final CommentService commentService;
private RedisOperator redis;
private final MyLikedVlogMapper myLikedVlogMapper;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
@ -94,25 +95,6 @@ public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements Vl
if (vlog == null) return; if (vlog == null) return;
String uploaderId = vlog.getMemberId(); String uploaderId = vlog.getMemberId();
// 2. 选择模板假设你有模板ID实际可配置到常量或数据库
Long templateId = (status == 1) ? 1938491493736902658L : 1938491899007332353L; // 1001=审核通过模板1002=驳回模板
// SysMessageTemplateVo template = templateService.selectTemplateById(templateId);
// if (template == null) return;
//
// // 3. 参数替换
// String content = template.getTemplateContent()
// .replace("${videoTitle}", vlog.getTitle() == null ? "" : vlog.getTitle())
// .replace("${reason}", reason == null ? "" : reason);
//
// // 4. 构造消息对象
// SysMessageBo messageBo = new SysMessageBo();
// messageBo.setTitle(template.getTitle());
// messageBo.setContent(content);
// messageBo.setSenderId(1L); // 系统管理员
// // 可根据需要设置更多字段
//
// // 5. 发送消息
// sysMessageService.sendMessageToUser(messageBo, Long.valueOf(uploaderId));
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@ -161,26 +143,7 @@ public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements Vl
MqUtil.sendMessage(RocketMQConfig.VLOG_UPLOAD_TOPIC+":"+"upload", message); MqUtil.sendMessage(RocketMQConfig.VLOG_UPLOAD_TOPIC+":"+"upload", message);
} }
@Override @Override
public Integer getVlogBeLikedCounts(String vlogId) {
Double count = cache.zSetScore(REDIS_VLOG_BE_LIKED_COUNTS, vlogId);
return count == null ? 0 : count.intValue();
}
private Integer getVlogComment(String vlogId) {
Double count = cache.zSetScore(REDIS_VLOG_COMMENT_COUNTS, vlogId);
return count == null ? 0 : count.intValue();
}
private boolean doILikeVlog(String myId, String vlogId) {
String doILike = cache.getCacheObject(REDIS_USER_LIKE_VLOG + ":" + myId + ":" + vlogId);
return StringUtils.isNotBlank(doILike) && doILike.equalsIgnoreCase("1");
}
@Override
@Cacheable(cacheNames = GlobalConstants.VLOG_KEY, key = "#vlogId")
public IndexVlogVO getVlogDetailById(String vlogId) { public IndexVlogVO getVlogDetailById(String vlogId) {
Vlog vlog = vlogMapper.selectById(vlogId); Vlog vlog = vlogMapper.selectById(vlogId);
if (vlog == null) { if (vlog == null) {
@ -192,14 +155,14 @@ public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements Vl
LoginUser loginUser = LoginHelper.getLoginUser(); LoginUser loginUser = LoginHelper.getLoginUser();
if (loginUser != null) { if (loginUser != null) {
vo.setDoIFollowVloger(fansService.queryDoIFollowVloger(loginUser.getUserId() + "", vlog.getMemberId())); vo.setDoIFollowVloger(fansService.queryDoIFollowVloger(loginUser.getUserId() + "", vlog.getMemberId()));
vo.setDoILikeThisVlog(doILikeVlog(loginUser.getUserId() + "", vlogId)); vo.setDoILikeThisVlog(myLikeVlogService.doILikeVlog(vlogId,loginUser.getUserId() ));
} }
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage()); log.error(e.getMessage());
} }
vo.setLikeCounts(getVlogBeLikedCounts(vlogId)); vo.setLikeCounts(myLikeVlogService.getVLogLikeCount(vlogId));
vo.setCommentsCounts(getVlogComment(vlogId)); vo.setCommentsCounts(commentService.getCommentCount(vlogId));
// 补充作者信息头像/昵称 // 补充作者信息头像/昵称
Member author = memberMapper.selectById(vlog.getMemberId()); Member author = memberMapper.selectById(vlog.getMemberId());
@ -213,14 +176,12 @@ public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements Vl
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
@CacheEvict(value = GlobalConstants.VLOG_KEY, key = "#vlogId")
public void changeToPrivateOrPublic(String vlogId, Integer yesOrNo) { public void changeToPrivateOrPublic(String vlogId, Integer yesOrNo) {
vlogMapper.updateById(Vlog.builder().id(vlogId).isPrivate(yesOrNo).build()); vlogMapper.updateById(Vlog.builder().id(vlogId).isPrivate(yesOrNo).build());
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
@CacheEvict(value = GlobalConstants.VLOG_KEY, key = "#bo.vlogId")
public void changeVlogStatus(AuditVlogBO bo) { public void changeVlogStatus(AuditVlogBO bo) {
vlogMapper.updateById(Vlog.builder().id(bo.getVlogId()).status(bo.getStatus()).reason(bo.getReason()).build()); vlogMapper.updateById(Vlog.builder().id(bo.getVlogId()).status(bo.getStatus()).reason(bo.getReason()).build());
} }
@ -255,10 +216,10 @@ public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements Vl
} }
if (StringUtils.isNotBlank(uid)) { if (StringUtils.isNotBlank(uid)) {
vo.setDoIFollowVloger(fansService.queryDoIFollowVloger(uid, vlog.getMemberId())); vo.setDoIFollowVloger(fansService.queryDoIFollowVloger(uid, vlog.getMemberId()));
vo.setDoILikeThisVlog(doILikeVlog(uid, vlog.getId())); vo.setDoILikeThisVlog(myLikeVlogService.doILikeVlog( vlog.getId(),Long.valueOf(uid)));
} }
vo.setLikeCounts(getVlogBeLikedCounts(vlog.getId())); vo.setLikeCounts(myLikeVlogService.getVLogLikeCount(vlog.getId()));
vo.setCommentsCounts(getVlogComment(vlog.getId())); vo.setCommentsCounts(commentService.getCommentCount(vlog.getId()));
// 补充用户信息头像/昵称 // 补充用户信息头像/昵称
Member author = memberMapper.selectById(vlog.getMemberId()); Member author = memberMapper.selectById(vlog.getMemberId());
@ -280,33 +241,19 @@ public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements Vl
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
@CacheEvict(value = GlobalConstants.VLOG_KEY, key = "#vlogId")
public void userLikeVlog(String userId, String vlogId) { public void userLikeVlog(String userId, String vlogId) {
//获取vlog //获取vlog
Vlog vlog = this.getVlog(vlogId); Vlog vlog = this.getVlog(vlogId);
if (vlog == null) { if (vlog == null) {
throw new ServiceException("视频不存在"); throw new ServiceException("视频不存在");
} }
// 我点赞的视频关联关系保存到数据库 //先检查是否已经点过赞了
if (myLikeVlogService.doILikeVlog(vlogId,Long.valueOf(userId))) {
String rid = sid.nextShort(); throw new ServiceException("您已经点过赞了");
MyLikedVlog likedVlog = new MyLikedVlog();
likedVlog.setId(rid);
likedVlog.setVlogId(vlogId);
likedVlog.setUserId(userId);
myLikedVlogMapper.insert(likedVlog);
// 点赞后视频和视频发布者的获赞都会 +1
cache.zSetIncrement(REDIS_VLOGER_BE_LIKED_COUNTS, vlog.getMemberId(), 1);
cache.zSetIncrement(REDIS_VLOG_BE_LIKED_COUNTS, vlogId, 1);
// 我点赞的视频需要在redis中保存关联关系
cache.setCacheObject(REDIS_USER_LIKE_VLOG + ":" + userId + ":" + vlogId, "1");
Double count = cache.zSetScore(REDIS_VLOG_BE_LIKED_COUNTS, vlogId);
if (count > 0) {
//更新数据库的点赞数
this.flushCounts(vlogId, count.intValue());
} }
// 我点赞的视频关联关系保存到数据库
myLikeVlogService.like( vlogId,Long.valueOf(userId));
clearMemberVlogCache(vlogId,userId);
//发送消息 //发送消息
MqUtil.sendIMMessage(buildMessage(vlog)); MqUtil.sendIMMessage(buildMessage(vlog));
} }
@ -344,7 +291,6 @@ public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements Vl
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
@CacheEvict(value = GlobalConstants.VLOG_KEY, key = "#vlogId")
public void userUnLikeVlog(String userId, String vlogId) { public void userUnLikeVlog(String userId, String vlogId) {
//获取vlog //获取vlog
@ -354,23 +300,15 @@ public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements Vl
} }
// 我取消点赞的视频关联关系删除 // 我取消点赞的视频关联关系删除
LambdaQueryWrapper<MyLikedVlog> queryWrapper = new LambdaQueryWrapper<>(); myLikeVlogService.unLike(vlogId,Long.valueOf(userId));
queryWrapper.eq(MyLikedVlog::getUserId, userId); clearMemberVlogCache(vlogId,userId);
queryWrapper.eq(MyLikedVlog::getVlogId, vlogId);
myLikedVlogMapper.delete(queryWrapper);
cache.zSetDecrement(REDIS_VLOGER_BE_LIKED_COUNTS, vlog.getMemberId(), 1);
cache.zSetDecrement(REDIS_VLOG_BE_LIKED_COUNTS, vlogId, 1);
cache.deleteObject(REDIS_USER_LIKE_VLOG + ":" + userId + ":" + vlogId);
Double count = cache.zSetScore(REDIS_VLOG_BE_LIKED_COUNTS, vlogId);
if (count > 0) {
//更新数据库的点赞数
this.flushCounts(vlogId, count.intValue());
}
} }
private void clearMemberVlogCache(String vlogId,String userId) {
RedisUtils.delCacheMapValue(GlobalConstants.GLOBAL_VLOG_MY_LIKED_LIST, userId);
RedisUtils.delCacheMapValue(GlobalConstants.GLOBAL_VLOG_LIKED_COUNT, vlogId);
RedisUtils.delCacheMapValue(GlobalConstants.GLOBAL_VLOG_ALL_LIKED_COUNT, userId);
}
@Override @Override
public Page<IndexVlogVO> getMyLikedVlogList(Page page) { public Page<IndexVlogVO> getMyLikedVlogList(Page page) {
@ -441,16 +379,7 @@ public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements Vl
// 这里不再统计避免重复计算 // 这里不再统计避免重复计算
// 获取粉丝数量优先 Redis无则 MySQL // 获取粉丝数量优先 Redis无则 MySQL
String fansCountsStr = cache.getCacheObject(REDIS_MY_FANS_COUNTS + ":" + vlog.getMemberId()); Long fansCounts = fansService.countFansByVloggerId(Long.valueOf(vlog.getMemberId()));
Integer fansCounts = 0;
if (StringUtils.isNotBlank(fansCountsStr)) {
fansCounts = Integer.valueOf(fansCountsStr);
} else {
// fansCounts = fansService.countFansByVlogerId(vlog.getVlogerId());
// if (fansCounts != null) {
// redis.set(REDIS_MY_FANS_COUNTS + ":" + vlog.getVlogerId(), String.valueOf(fansCounts));
// }
}
result.put("fansCounts", fansCounts); result.put("fansCounts", fansCounts);
} else { } else {
result.put("vlogId", null); result.put("vlogId", null);
@ -481,7 +410,7 @@ public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements Vl
result.put("comments", comments); result.put("comments", comments);
// 从Redis获取点赞数 // 从Redis获取点赞数
int likeCounts = getVlogBeLikedCounts(vlog.getId()); Integer likeCounts = myLikeVlogService.getVLogLikeCount(vlog.getId());
result.put("likeCounts", likeCounts); result.put("likeCounts", likeCounts);
result.put("vlogId", vlog.getId()); result.put("vlogId", vlog.getId());
@ -648,10 +577,10 @@ public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements Vl
vlogList.parallelStream().forEach(vlog -> { vlogList.parallelStream().forEach(vlog -> {
if (user != null) { if (user != null) {
vlog.setDoIFollowVloger(fansService.queryDoIFollowVloger(user.getUserId() + "", vlog.getMemberId())); vlog.setDoIFollowVloger(fansService.queryDoIFollowVloger(user.getUserId() + "", vlog.getMemberId()));
vlog.setDoILikeThisVlog(doILikeVlog(user.getUserId() + "", vlog.getId())); vlog.setDoILikeThisVlog(myLikeVlogService.doILikeVlog( vlog.getId(),user.getUserId()));
} }
vlog.setLikeCounts(getVlogBeLikedCounts(vlog.getId())); vlog.setLikeCounts(myLikeVlogService.getVLogLikeCount(vlog.getId()));
vlog.setCommentsCounts(getVlogComment(vlog.getId())); vlog.setCommentsCounts(commentService.getCommentCount(vlog.getId()));
}); });
} }
@ -723,10 +652,10 @@ public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements Vl
IndexVlogVO vo = MapstructUtils.convert(v, IndexVlogVO.class); IndexVlogVO vo = MapstructUtils.convert(v, IndexVlogVO.class);
if (StringUtils.isNotBlank(userId)) { if (StringUtils.isNotBlank(userId)) {
vo.setDoIFollowVloger(fansService.queryDoIFollowVloger(userId, v.getMemberId())); vo.setDoIFollowVloger(fansService.queryDoIFollowVloger(userId, v.getMemberId()));
vo.setDoILikeThisVlog(doILikeVlog(userId, v.getId())); vo.setDoILikeThisVlog(myLikeVlogService.doILikeVlog(v.getId(),Long.valueOf(userId)));
} }
vo.setLikeCounts(getVlogBeLikedCounts(v.getId())); vo.setLikeCounts(myLikeVlogService.getVLogLikeCount(v.getId()));
vo.setCommentsCounts(getVlogComment(v.getId())); vo.setCommentsCounts(commentService.getCommentCount(v.getId()));
MemberVO m = memberService.getMemberInfo(vo.getMemberId()); MemberVO m = memberService.getMemberInfo(vo.getMemberId());
if (m != null) { if (m != null) {
vo.setAvatar(m.getAvatar()); vo.setAvatar(m.getAvatar());

View File

@ -304,5 +304,36 @@
<update id="readVlog"> <update id="readVlog">
insert into cms_vlog_member (vlog_id, member_id,status) values (#{vlogId}, #{memberId},1) insert into cms_vlog_member (vlog_id, member_id,status) values (#{vlogId}, #{memberId},1)
</update> </update>
<select id="selectUserLikeVlogList" resultType="com.wzj.soopin.content.domain.vo.IndexVlogVO">
SELECT
v.id as vlogId,
v.member_id as memberId,
v.title as title,
v.title as content,
v.url as url,
v.cover as cover,
v.width as width,
v.height as height,
v.like_counts as likeCounts,
v.comments_counts as commentsCounts,
v.is_private as isPrivate,
v.city_code as cityCode,
v.reason as reason,
v.status as status,
v.file_id as fileId,
v.first_frame_img as firstFrameImg,
v.id as Id,
m.avatar as avatar,
m.nickname as nickname
FROM
cont_vlog v
LEFT JOIN
ums_member m ON v.member_id = m.id
WHERE
v.member_id = #{memberId}
ORDER BY
v.create_time DESC
</select>
</mapper> </mapper>

View File

@ -26,6 +26,7 @@ import org.dromara.common.mq.utils.MqUtil;
import org.dromara.common.redis.redis.RedisCache; import org.dromara.common.redis.redis.RedisCache;
import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.redis.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -47,6 +48,7 @@ public class FansServiceImpl extends ServiceImpl<FansMapper, Fans> implements IF
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
@CacheEvict(value = GlobalConstants.GLOBAL_MEMBER_FANS_COUNT, key = "#vloggerId")
public boolean doFollow(Long myId, Long vloggerId) { public boolean doFollow(Long myId, Long vloggerId) {
// 幂等性校验已存在则不再插入 // 幂等性校验已存在则不再插入
@ -110,6 +112,7 @@ public class FansServiceImpl extends ServiceImpl<FansMapper, Fans> implements IF
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
@CacheEvict(value = GlobalConstants.GLOBAL_MEMBER_FANS_COUNT, key = "#vloggerId")
public boolean doCancel(Long myId, Long vloggerId) { public boolean doCancel(Long myId, Long vloggerId) {
// 判断我们是否朋友关系如果是则需要取消双方的关系 // 判断我们是否朋友关系如果是则需要取消双方的关系
Fans fan = queryFansRelationship(myId, vloggerId); Fans fan = queryFansRelationship(myId, vloggerId);
@ -184,12 +187,15 @@ public class FansServiceImpl extends ServiceImpl<FansMapper, Fans> implements IF
} }
@Override @Override
@Cacheable(value = GlobalConstants.GLOBAL_MEMBER_FANS_COUNT, key = "#vloggerId")
public Long countFansByVloggerId(Long vloggerId) { public Long countFansByVloggerId(Long vloggerId) {
return baseMapper.selectCount(new LambdaQueryWrapper<Fans>().eq(Fans::getVloggerId, vloggerId)); return baseMapper.selectCount(new LambdaQueryWrapper<Fans>().eq(Fans::getVloggerId, vloggerId));
} }
// 拉黑前只删除我关注对方的关系 // 拉黑前只删除我关注对方的关系
@Override @Override
@CacheEvict(value = GlobalConstants.GLOBAL_MEMBER_FANS_COUNT, key = "#vloggerId")
public void removeFansRelationship(Long myId, Long vloggerId) { public void removeFansRelationship(Long myId, Long vloggerId) {
Fans fan = queryFansRelationship(myId, vloggerId); Fans fan = queryFansRelationship(myId, vloggerId);
if (fan != null) { if (fan != null) {