package org.dromara.app; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fasterxml.jackson.databind.ObjectMapper; import com.wzj.soopin.content.domain.bo.*; import com.wzj.soopin.content.domain.po.MyLikedVlog; import com.wzj.soopin.content.domain.po.Vlog; import com.wzj.soopin.content.domain.vo.IndexVlogVO; import com.wzj.soopin.content.service.VlogService; import com.wzj.soopin.content.service.VlogUploadService; import com.wzj.soopin.content.utils.PagedGridResult; import com.wzj.soopin.content.utils.QcCloud; import com.wzj.soopin.content.utils.RedisOperator; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.mq.domain.MQMessage; import org.dromara.common.mq.enums.MQMessageType; import org.dromara.common.mq.enums.MessageActionEnum; import org.dromara.common.mq.utils.MqUtil; import org.dromara.common.satoken.utils.LoginHelper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static com.wzj.soopin.content.domain.base.BaseInfoProperties.*; @Slf4j @Api(tags = "VlogController 短视频相关业务功能的接口") @RequestMapping("/app/vlog") @RestController public class AppVlogController { @Autowired private VlogService vlogService; @Autowired private QcCloud qcCloud; @Autowired private VlogUploadService vlogUploadService; @Autowired public RedisOperator redis; @Tag(name = "首页视频列表") @PostMapping("/indexList") public R> indexList(@RequestBody IndexListBO bo, @RequestBody Page page) { try{ LoginUser loginUser = LoginHelper.getLoginUser(); if (loginUser == null) { throw new ServiceException("用户未登录"); } bo.setUserId(String.valueOf(loginUser.getUserId())); }catch (Exception e){ log.error("用户没登陆", e); } Page pages = vlogService.getIndexVlogList(bo, page); return R.ok(pages); } @GetMapping("/detail/{vlogId}") public R detail( @PathVariable String vlogId) { return R.ok(vlogService.getVlogDetailById(vlogId)); } @Tag(name = "我的私密视频列表") @PostMapping("/myPrivateList") public R> myPrivateList(@RequestBody MyListBO bo, @RequestBody Page page) { LoginUser loginUser = LoginHelper.getLoginUser(); if (loginUser == null) { throw new ServiceException("用户未登录"); } bo.setUserId(String.valueOf(loginUser.getUserId())); Page pages = vlogService.queryMyVlogList(bo, page); return R.ok(pages); } @Tag(name = "我点赞的视频列表") @PostMapping("/myLikedList") public R> myLikedList(@RequestBody MyLikedVlogBO bo, @RequestBody Page page) { Page pages = vlogService.getMyLikedVlogList(page); return R.ok(pages); } @Tag(name = "我关注的人的视频列表") @PostMapping("/followList") public R> followList(@RequestBody SimpleListBO bo, @RequestBody Page page) { LoginUser loginUser = LoginHelper.getLoginUser(); if (loginUser == null) { throw new ServiceException("用户未登录"); } bo.setMyId(String.valueOf(loginUser.getUserId())); Page pages = vlogService.getMyFollowVlogList( page); return R.ok(pages); } @Tag(name = "好友视频列表") @PostMapping("/friendList") public R> friendList(@RequestBody SimpleListBO bo, @RequestBody Page page) { LoginUser loginUser = LoginHelper.getLoginUser(); if (loginUser == null) { throw new ServiceException("用户未登录"); } bo.setMyId(String.valueOf(loginUser.getUserId())); Page pages = vlogService.getMyFriendVlogList( page); return R.ok(pages); } @PostMapping("publish") public R publish(@RequestBody VlogBO vlogBO) throws Exception { LoginUser loginUser = LoginHelper.getLoginUser(); if (loginUser == null) { throw new ServiceException("用户未登录"); } vlogBO.setVlogerId(String.valueOf(loginUser.getUserId())); String url = vlogBO.getUrl(); log.info("未审核视频地址:"+url); String fileName = url.substring(url.lastIndexOf("/") + 1); log.info("视频文件名称:"+fileName); log.info("开始上传腾讯云点播:"+fileName); String fileId = qcCloud.uploadViaTempFile(fileName); log.info("视频发布ID:"+fileId); vlogBO.setFileId(fileId); // 删除minio文件 // MinIOUtils.removeFile(minIOConfig.getBucketName(),fileName); // log.info("删除minio文件:"+fileName); // FIXME 校验VlogBO vlogService.createVlog(vlogBO); return R.ok(); } @Tag(name = "我的公开视频列表") @PostMapping("/myPublicList") public R> myPublicList(@RequestBody MyListBO bo, @RequestBody Page page) { Page pages = vlogService.queryMyVlogList(bo, page); return R.ok(pages); } private Integer nacosConuts=0; @PostMapping("like") public R like(@RequestBody VlogBO vlogBO) { LoginUser loginUser = LoginHelper.getLoginUser(); if (loginUser == null) { throw new ServiceException("用户未登录"); } String userId = String.valueOf(loginUser.getUserId()); String vlogId = vlogBO.getId(); //获取vlog Vlog vlog = vlogService.getVlog(vlogId); if(vlog==null){ throw new ServiceException("视频不存在"); } // 我点赞的视频,关联关系保存到数据库 vlogService.userLikeVlog(userId, vlogId); // 点赞后,视频和视频发布者的获赞都会 +1 redis.increment(REDIS_VLOGER_BE_LIKED_COUNTS + ":" + vlog.getMemberId(), 1); redis.increment(REDIS_VLOG_BE_LIKED_COUNTS + ":" + vlogId, 1); // 我点赞的视频,需要在redis中保存关联关系 redis.set(REDIS_USER_LIKE_VLOG + ":" + userId + ":" + vlogId, "1"); log.info("nacosConuts="+nacosConuts); String countsStr = redis.get(REDIS_VLOG_BE_LIKED_COUNTS + ":" + vlogId); Integer counts=0; if (StringUtils.isNotBlank(countsStr)){ counts=Integer.valueOf(countsStr); if (counts>=nacosConuts){ vlogService.flushCounts(vlogId, counts); } } if (userId != null && vlog.getMemberId() != null && !userId.equals(vlog.getMemberId())) { // 新版:使用模板类型编号和参数 Map params = new HashMap<>(); params.put("userId", userId); params.put("nickname", loginUser.getNickname()); params.put("action", MessageActionEnum.INTERACTION_LIKE.name()); params.put("toUserId",vlog.getMemberId()); MQMessage message = MQMessage.builder() .messageType(MQMessageType.IM.name()) .data(params) .source("member") .build(); // 关注消息 MqUtil.sendIMMessage(message); } return R.ok(); } @PostMapping("unlike") public R unlike(@RequestBody Map params) { LoginUser loginUser = LoginHelper.getLoginUser(); if (loginUser == null) { throw new ServiceException("用户未登录"); } String userId = String.valueOf(loginUser.getUserId()); String vlogId = params.get("vlogId"); //获取vlog Vlog vlog = vlogService.getVlog(vlogId); if(vlog==null){ throw new ServiceException("视频不存在"); } // 我取消点赞的视频,关联关系删除 vlogService.userUnLikeVlog(userId, vlogId); redis.decrement(REDIS_VLOGER_BE_LIKED_COUNTS + ":" + vlog.getMemberId(), 1); redis.decrement(REDIS_VLOG_BE_LIKED_COUNTS + ":" + vlogId, 1); redis.del(REDIS_USER_LIKE_VLOG + ":" + userId + ":" + vlogId); return R.ok(); } @Tag(name = "手动触发缓存点赞最多视频") @PostMapping("/cacheTopLikedVlogs") public R cacheTopLikedVlogs(@RequestParam(defaultValue = "100") int limit) { try { vlogService.cacheTopLikedVlogs(limit); return R.ok(); } catch (Exception e) { log.error("手动触发缓存点赞最多视频失败", e); return R.fail("缓存失败: " + e.getMessage()); } } @Tag(name = "获取缓存中的点赞最多视频") @GetMapping("/getTopLikedVlogs") public R getTopLikedVlogs(@RequestParam(defaultValue = "") String date, @RequestParam(defaultValue = "10") int pageSize, @RequestParam(defaultValue = "0") int pageNum) { try { String redisKey; if (StringUtils.isBlank(date)) { // 如果没有指定日期,使用今天的日期 redisKey = "top_liked_vlogs:" + java.time.LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd")); } else { redisKey = "top_liked_vlogs:" + date; } String cachedData = redis.get(redisKey); List> resultList = new ArrayList<>(); if (StringUtils.isNotBlank(cachedData)) { // 解析JSON数据 ObjectMapper objectMapper = new ObjectMapper(); List> vlogList = objectMapper.readValue(cachedData, new com.fasterxml.jackson.core.type.TypeReference>>() {}); // 计算分页 int startIndex = pageNum * pageSize; int endIndex = Math.min(startIndex + pageSize, vlogList.size()); if (startIndex < vlogList.size()) { // 从Redis缓存中获取指定页的数据 resultList = vlogList.subList(startIndex, endIndex); log.info("从Redis缓存中获取了{}条视频数据", resultList.size()); } } // 如果Redis中的数据不足,从数据库随机查询补充 if (resultList.size() < pageSize) { int needMore = pageSize - resultList.size(); log.info("Redis缓存数据不足,需要从数据库随机查询{}条视频", needMore); // 从数据库随机查询视频 List> randomVlogs = vlogService.getRandomVlogs(needMore); resultList.addAll(randomVlogs); log.info("从数据库随机查询了{}条视频", randomVlogs.size()); } return R.ok(resultList); } catch (Exception e) { log.error("获取缓存中的点赞最多视频失败", e); return R.fail("获取缓存失败: " + e.getMessage()); } } }