[fix]修改vlog不登陆获取热点数据
This commit is contained in:
parent
832689d040
commit
5586e8cee3
@ -54,11 +54,6 @@ public class AppVlogController {
|
||||
@PostMapping("/indexList")
|
||||
public R<Page<IndexVlogVO>> indexList(@RequestBody IndexListBO bo, @RequestBody Page page) {
|
||||
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
if (loginUser == null) {
|
||||
throw new ServiceException("用户未登录");
|
||||
}
|
||||
bo.setUserId(String.valueOf(loginUser.getUserId()));
|
||||
Page<IndexVlogVO> pages = pullService.page(page);
|
||||
return R.ok(pages);
|
||||
}
|
||||
@ -176,13 +171,13 @@ public class AppVlogController {
|
||||
vlogService.userUnLikeVlog(userId, vlogId);
|
||||
return R.ok();
|
||||
}
|
||||
@GetMapping("/read/{vlogId}")
|
||||
public R<Void> read(@PathVariable String vlogId) {
|
||||
@GetMapping("/read")
|
||||
public R<Void> read(@RequestBody VlogBO vlogBO) {
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
if (loginUser == null) {
|
||||
throw new ServiceException("用户未登录");
|
||||
}
|
||||
vlogService.readVlog(loginUser.getUserId(), vlogId);
|
||||
vlogService.readVlog(loginUser.getUserId(), vlogBO.getId());
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
@ -47,4 +47,10 @@ public interface GlobalConstants {
|
||||
*/
|
||||
String GLOBAL_OFFSET = GLOBAL_REDIS_KEY + "offset:";
|
||||
|
||||
|
||||
/**
|
||||
* 热点视频 redis key
|
||||
*/
|
||||
String HOT_VLOG_TAG = "HOT";
|
||||
|
||||
}
|
||||
|
@ -11,53 +11,27 @@ import org.springframework.context.ApplicationEvent;
|
||||
@Getter
|
||||
public class VlogPushEvent extends ApplicationEvent {
|
||||
|
||||
private final Long userId;
|
||||
private final String tag;
|
||||
private final String userIdStr;
|
||||
|
||||
/**
|
||||
* 使用 Long 类型用户 ID 创建消息事件
|
||||
*/
|
||||
public VlogPushEvent(Object source, Long userId) {
|
||||
public VlogPushEvent(Object source, String tag) {
|
||||
super(source);
|
||||
this.userId = userId;
|
||||
this.userIdStr = userId != null ? String.valueOf(userId) : null;
|
||||
this.tag = tag;
|
||||
this.userIdStr = tag;
|
||||
}
|
||||
/**
|
||||
* 使用 Long 类型用户 ID 创建消息事件
|
||||
*/
|
||||
public VlogPushEvent(Long userId) {
|
||||
super(null);
|
||||
this.userId = userId;
|
||||
public VlogPushEvent(String tag) {
|
||||
super(tag);
|
||||
this.tag = tag;
|
||||
this.userIdStr = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 String 类型用户 ID 创建消息事件
|
||||
*/
|
||||
public VlogPushEvent(Object source, String userIdStr) {
|
||||
super(source);
|
||||
this.userIdStr = userIdStr;
|
||||
|
||||
// 尝试转换为 Long 类型
|
||||
Long parsedUserId = null;
|
||||
try {
|
||||
if (userIdStr != null) {
|
||||
parsedUserId = Long.parseLong(userIdStr);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// 无法解析为 Long 类型,保持 userId 为 null
|
||||
}
|
||||
this.userId = parsedUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 MessageEvent 实例(支持 String 类型用户ID)
|
||||
*
|
||||
* @param source 事件源
|
||||
* @param userIdStr 用户ID (String类型)
|
||||
* @return MessageEvent 实例
|
||||
*/
|
||||
public static VlogPushEvent createWithStringUserId(Object source, String userIdStr) {
|
||||
return new VlogPushEvent(source, userIdStr);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -65,11 +65,16 @@ public class LoginHelper {
|
||||
*/
|
||||
@SuppressWarnings("unchecked cast")
|
||||
public static <T extends LoginUser> T getLoginUser() {
|
||||
SaSession session = StpUtil.getTokenSession();
|
||||
if (ObjectUtil.isNull(session)) {
|
||||
try {
|
||||
SaSession session = StpUtil.getTokenSession();
|
||||
if (ObjectUtil.isNull(session)) {
|
||||
return null;
|
||||
}
|
||||
return (T) session.get(LOGIN_USER_KEY);
|
||||
}catch (Exception e){
|
||||
return null;
|
||||
}
|
||||
return (T) session.get(LOGIN_USER_KEY);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,7 +3,10 @@ package com.wzj.soopin.content.controller;
|
||||
|
||||
|
||||
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
|
||||
import com.wzj.soopin.content.domain.bo.VlogBO;
|
||||
import com.wzj.soopin.content.domain.bo.*;
|
||||
import com.wzj.soopin.content.domain.po.Article;
|
||||
import com.wzj.soopin.content.domain.vo.ArticleVO;
|
||||
import com.wzj.soopin.content.domain.vo.IndexVlogVO;
|
||||
import com.wzj.soopin.content.enums.YesOrNo;
|
||||
import com.wzj.soopin.content.service.IVlogPushService;
|
||||
import org.dromara.common.core.domain.R;
|
||||
@ -21,9 +24,6 @@ import com.wzj.soopin.content.utils.RedisOperator;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import com.wzj.soopin.content.domain.bo.IndexListBO;
|
||||
import com.wzj.soopin.content.domain.bo.MyListBO;
|
||||
import com.wzj.soopin.content.domain.bo.SimpleListBO;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -48,7 +48,12 @@ public class VlogController extends BaseInfoProperties {
|
||||
public RedisOperator redis;
|
||||
@Autowired
|
||||
private IVlogPushService vlogPushService;
|
||||
|
||||
@Tag(name = "查询列表")
|
||||
@PostMapping("/page")
|
||||
public R<IPage<IndexVlogVO>> page(@RequestBody VlogBO bo, @RequestBody Page page) {
|
||||
Page<IndexVlogVO> pages = vlogService.getIndexVlogList(bo ,page);
|
||||
return R.ok(pages);
|
||||
}
|
||||
@PostMapping("/vodCallBack")
|
||||
public R<Void> vodCallBack(@RequestBody Map<String, Object> callbackData) {
|
||||
try {
|
||||
@ -189,21 +194,13 @@ public class VlogController extends BaseInfoProperties {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@PostMapping("/totalLikedCounts")
|
||||
public R<Integer> totalLikedCounts(@RequestParam String vlogId) {
|
||||
return R.ok(vlogService.getVlogBeLikedCounts(vlogId));
|
||||
}
|
||||
@GetMapping("/push/hot")
|
||||
public R pushHot(@RequestParam int count) {
|
||||
return R.ok(vlogPushService.cacheTopLikedVlogs(count));
|
||||
}
|
||||
@GetMapping("/push/member")
|
||||
public R pushMember(@RequestParam int count,@RequestParam Long memberId) {
|
||||
return R.ok(vlogPushService.pushVlogToMember(count,memberId));
|
||||
@GetMapping("/push")
|
||||
public R pushMember(@RequestParam int count,@RequestParam String tag) {
|
||||
return R.ok(vlogPushService.pushVlogToMq(count,tag));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,217 +43,6 @@ public class VlogUploadController extends BaseInfoProperties {
|
||||
@Autowired
|
||||
private IFansService fansService;
|
||||
|
||||
@ApiOperation("获取腾讯云点播视频列表")
|
||||
@PostMapping("/list")
|
||||
public R<IPage<Map<String, Object>>> getVodList(@RequestBody VlogBO vlogBO) {
|
||||
try {
|
||||
// 验证分页参数
|
||||
if (vlogBO.getCurrent() < 1) {
|
||||
vlogBO.setCurrent(1L);
|
||||
}
|
||||
if (vlogBO.getSize() < 1 || vlogBO.getSize() > 50) {
|
||||
vlogBO.setSize(10L);
|
||||
}
|
||||
|
||||
// 如果有模糊查询条件、时间区间条件,或者有排序条件,则只查询数据库
|
||||
if (StringUtils.isNotBlank(vlogBO.getMobile())
|
||||
|| StringUtils.isNotBlank(vlogBO.getNickname())
|
||||
|| StringUtils.isNotBlank(vlogBO.getTitleQuery())
|
||||
|| vlogBO.getStartTime() != null
|
||||
|| vlogBO.getEndTime() != null
|
||||
|| vlogBO.getStatus() != null
|
||||
|| StringUtils.isNotBlank(vlogBO.getColumn())) {
|
||||
|
||||
// 创建分页对象
|
||||
Page<Map<String, Object>> page = new Page<>(vlogBO.getCurrent(), vlogBO.getSize());
|
||||
|
||||
// 调用服务层方法进行查询
|
||||
IPage<Map<String, Object>> result = vlogService.getVlogListByMobile(page, vlogBO);
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
// 否则查询腾讯云点播
|
||||
// 验证密钥配置
|
||||
String secretId = tencentCloudUtil.getSecretId();
|
||||
String secretKey = tencentCloudUtil.getSecretKey();
|
||||
if (secretId == null || secretId.isEmpty() || secretKey == null || secretKey.isEmpty()) {
|
||||
log.error("腾讯云密钥未配置");
|
||||
return R.fail("腾讯云密钥未配置");
|
||||
}
|
||||
|
||||
// 计算实际的offset
|
||||
long offset = (long) ((vlogBO.getCurrent() - 1) * vlogBO.getSize());
|
||||
if (offset < 0) {
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
// 打印分页参数
|
||||
log.info("分页参数 - 当前页码: {}, 每页记录数: {}, 偏移量: {}", vlogBO.getCurrent(), vlogBO.getSize(), offset);
|
||||
|
||||
// 创建请求对象
|
||||
SearchMediaRequest req = new SearchMediaRequest();
|
||||
|
||||
// 设置分页参数
|
||||
req.setOffset(offset);
|
||||
req.setLimit(vlogBO.getSize());
|
||||
|
||||
// 设置排序
|
||||
SortBy sort = new SortBy();
|
||||
sort.setField("CreateTime");
|
||||
sort.setOrder("Desc");
|
||||
req.setSort(sort);
|
||||
|
||||
// 调用腾讯云API获取视频列表
|
||||
log.info("开始调用腾讯云 SearchMedia API");
|
||||
SearchMediaResponse resp = vlogUploadService.searchMedia(req);
|
||||
log.info("腾讯云 SearchMedia API 调用成功,总记录数: {}", resp.getTotalCount());
|
||||
|
||||
// 处理响应结果
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("total", resp.getTotalCount());
|
||||
result.put("current", vlogBO.getCurrent());
|
||||
result.put("size", vlogBO.getSize());
|
||||
result.put("pages", (resp.getTotalCount() + vlogBO.getSize() - 1) / vlogBO.getSize()); // 总页数
|
||||
|
||||
// 批量获取所有视频的统计信息,避免重复查询
|
||||
Map<String, String> fileIdToVlogIdMap = new HashMap<>();
|
||||
List<String> allVlogIds = new ArrayList<>();
|
||||
|
||||
if (resp.getMediaInfoSet() != null) {
|
||||
for (MediaInfo mediaInfo : resp.getMediaInfoSet()) {
|
||||
String fileId = mediaInfo.getFileId();
|
||||
Map<String, Object> statistics = vlogService.getVlogStatistics(fileId);
|
||||
String vlogId = (String) statistics.get("vlogId");
|
||||
if (StringUtils.isNotBlank(vlogId)) {
|
||||
fileIdToVlogIdMap.put(fileId, vlogId);
|
||||
allVlogIds.add(vlogId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 批量获取所有点赞数据
|
||||
Map<String, Integer> vlogLikeCounts = new HashMap<>();
|
||||
Map<String, Integer> vlogCommentCounts = new HashMap<>();
|
||||
long totalLikeCounts = 0;
|
||||
long totalCommentCounts = 0;
|
||||
|
||||
if (!allVlogIds.isEmpty()) {
|
||||
// 批量获取所有点赞键
|
||||
String likePattern = REDIS_USER_LIKE_VLOG + ":*";
|
||||
Collection<String> allLikeKeys = RedisUtils.keys(likePattern);
|
||||
|
||||
if (allLikeKeys != null && !allLikeKeys.isEmpty()) {
|
||||
// 逐个获取点赞值(由于RedisUtils没有批量方法)
|
||||
Map<String, String> likeKeyValueMap = new HashMap<>();
|
||||
for (String likeKey : allLikeKeys) {
|
||||
String likeValue = RedisUtils.getCacheObject(likeKey);
|
||||
if ("1".equals(likeValue)) {
|
||||
likeKeyValueMap.put(likeKey, likeValue);
|
||||
}
|
||||
}
|
||||
|
||||
// 按vlogId分组统计点赞数
|
||||
for (String vlogId : allVlogIds) {
|
||||
int likeCount = 0;
|
||||
for (String likeKey : likeKeyValueMap.keySet()) {
|
||||
if (likeKey.endsWith(":" + vlogId)) {
|
||||
likeCount++;
|
||||
}
|
||||
}
|
||||
vlogLikeCounts.put(vlogId, likeCount);
|
||||
totalLikeCounts += likeCount;
|
||||
}
|
||||
}
|
||||
|
||||
// 批量获取所有评论数
|
||||
for (String vlogId : allVlogIds) {
|
||||
String commentKey = REDIS_VLOG_COMMENT_COUNTS + ":" + vlogId;
|
||||
String commentCountsStr = RedisUtils.getCacheObject(commentKey);
|
||||
int commentCount = 0;
|
||||
if (StringUtils.isNotBlank(commentCountsStr)) {
|
||||
try {
|
||||
commentCount = Integer.valueOf(commentCountsStr);
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("Redis中视频{}的评论数格式错误: {}", vlogId, commentCountsStr);
|
||||
}
|
||||
}
|
||||
vlogCommentCounts.put(vlogId, commentCount);
|
||||
totalCommentCounts += commentCount;
|
||||
}
|
||||
}
|
||||
|
||||
// 将总的点赞数和评论数添加到结果中
|
||||
result.put("totalLikeCounts", totalLikeCounts);
|
||||
result.put("totalCommentCounts", totalCommentCounts);
|
||||
|
||||
List<Map<String, Object>> mediaList = new ArrayList<>();
|
||||
if (resp.getMediaInfoSet() != null) {
|
||||
for (MediaInfo mediaInfo : resp.getMediaInfoSet()) {
|
||||
Map<String, Object> mediaMap = new HashMap<>();
|
||||
// 基础信息
|
||||
MediaBasicInfo basicInfo = mediaInfo.getBasicInfo();
|
||||
mediaMap.put("fileId", mediaInfo.getFileId());
|
||||
mediaMap.put("name", basicInfo.getName());
|
||||
mediaMap.put("description", basicInfo.getDescription());
|
||||
mediaMap.put("createTime", basicInfo.getCreateTime());
|
||||
mediaMap.put("updateTime", basicInfo.getUpdateTime());
|
||||
mediaMap.put("expireTime", basicInfo.getExpireTime());
|
||||
mediaMap.put("classId", basicInfo.getClassId());
|
||||
mediaMap.put("className", basicInfo.getClassName());
|
||||
mediaMap.put("classPath", basicInfo.getClassPath());
|
||||
mediaMap.put("coverUrl", basicInfo.getCoverUrl());
|
||||
mediaMap.put("type", basicInfo.getType());
|
||||
mediaMap.put("mediaUrl", basicInfo.getMediaUrl());
|
||||
mediaMap.put("status", basicInfo.getStatus());
|
||||
mediaMap.put("storageRegion", basicInfo.getStorageRegion());
|
||||
mediaMap.put("category", basicInfo.getCategory());
|
||||
mediaMap.put("storageClass", basicInfo.getStorageClass());
|
||||
mediaMap.put("tagSet", basicInfo.getTagSet());
|
||||
|
||||
// 获取视频统计信息
|
||||
Map<String, Object> statistics = vlogService.getVlogStatistics(mediaInfo.getFileId());
|
||||
mediaMap.putAll(statistics);
|
||||
|
||||
// 从statistics中获取vlogId,用于Redis查询
|
||||
String vlogId = (String) statistics.get("vlogId");
|
||||
log.info("处理视频 fileId: {}, vlogId: {}", mediaInfo.getFileId(), vlogId);
|
||||
|
||||
// 使用批量获取的数据,避免重复查询Redis
|
||||
int videoLikeCounts = 0;
|
||||
int videoCommentCounts = 0;
|
||||
if (StringUtils.isNotBlank(vlogId)) {
|
||||
videoLikeCounts = vlogLikeCounts.getOrDefault(vlogId, 0);
|
||||
videoCommentCounts = vlogCommentCounts.getOrDefault(vlogId, 0);
|
||||
}
|
||||
mediaMap.put("likeCounts", videoLikeCounts);
|
||||
mediaMap.put("commentCounts", videoCommentCounts);
|
||||
|
||||
// 获取视频上传者信息
|
||||
Map<String, String> uploaderInfo = vlogService.getVlogUploaderInfo(mediaInfo.getFileId());
|
||||
if (uploaderInfo != null) {
|
||||
mediaMap.put("nickname", uploaderInfo.get("name"));
|
||||
mediaMap.put("mobile", uploaderInfo.get("phone"));
|
||||
}
|
||||
|
||||
mediaList.add(mediaMap);
|
||||
}
|
||||
}
|
||||
result.put("records", mediaList);
|
||||
|
||||
// 构建Page对象
|
||||
Page<Map<String, Object>> page = new Page<>();
|
||||
page.setCurrent(vlogBO.getCurrent());
|
||||
page.setSize(vlogBO.getSize());
|
||||
page.setTotal(resp.getTotalCount());
|
||||
page.setRecords(mediaList);
|
||||
|
||||
return R.ok(page);
|
||||
} catch (Exception e) {
|
||||
log.error("获取视频列表失败", e);
|
||||
return R.fail("获取视频列表失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频审核接口
|
||||
*/
|
||||
|
@ -12,6 +12,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.dromara.common.core.domain.BaseBO;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@ -64,6 +65,12 @@ public class VlogBO extends BaseBO {
|
||||
@ApiModelProperty("创建时间范围-结束时间")
|
||||
private LocalDateTime endTime;
|
||||
|
||||
private List<String> blockVd;
|
||||
|
||||
private List<String> blockUser;
|
||||
|
||||
private List<String> ids;
|
||||
|
||||
@Override
|
||||
public LambdaQueryWrapper<Vlog> toWrapper() {
|
||||
LambdaQueryWrapper<Vlog> wrapper = new LambdaQueryWrapper<>();
|
||||
|
@ -14,7 +14,7 @@ public class VlogPushEventListener {
|
||||
private final IVlogPushService vlogPushService;
|
||||
@EventListener
|
||||
public void handleNeedPushVlogEvent(VlogPushEvent event) {
|
||||
log.info("收到需要推送的视频事件,用户ID:{}", event.getUserId());
|
||||
vlogPushService.pushVlogToMember(100, event.getUserId());
|
||||
log.info("收到需要推送的视频事件,用户ID:{}", event.getUserIdStr());
|
||||
vlogPushService.pushVlogToMq(100, event.getTag());
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.wzj.soopin.content.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.wzj.soopin.content.domain.bo.VlogBO;
|
||||
import com.wzj.soopin.content.domain.po.Vlog;
|
||||
import com.wzj.soopin.content.domain.vo.IndexVlogVO;
|
||||
import com.wzj.soopin.content.domain.vo.VlogerVO;
|
||||
@ -16,9 +17,9 @@ import java.util.Map;
|
||||
@InterceptorIgnore(tenantLine = "true")
|
||||
public interface VlogMapperCustom extends BaseMapperPlus<Vlog, VlogerVO> {
|
||||
|
||||
List<IndexVlogVO> getIndexVlogList(@Param("paramMap") Map<String, Object> map);
|
||||
List<IndexVlogVO> getIndexVlogList(@Param("bo") VlogBO bo);
|
||||
|
||||
Page<IndexVlogVO> getIndexVlogList(@Param("paramMap") Map<String, Object> map, Page<IndexVlogVO> page);
|
||||
Page<IndexVlogVO> getIndexVlogList(@Param("bo") VlogBO bo, Page<IndexVlogVO> page);
|
||||
|
||||
List<IndexVlogVO> getVlogDetailById(@Param("paramMap") Map<String, Object> map);
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
package com.wzj.soopin.content.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.tencentcloudapi.vod.v20180717.models.SearchMediaRequest;
|
||||
import com.tencentcloudapi.vod.v20180717.models.SearchMediaResponse;
|
||||
import com.wzj.soopin.content.domain.bo.VlogBO;
|
||||
import com.wzj.soopin.content.domain.vo.IndexVlogVO;
|
||||
|
||||
public interface IVlogPullService {
|
||||
@ -9,4 +12,10 @@ public interface IVlogPullService {
|
||||
* 从视频库中拉取视频
|
||||
*/
|
||||
Page<IndexVlogVO> page(Page<IndexVlogVO> page);
|
||||
|
||||
|
||||
void pullVlog(VlogBO vlogBO);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -8,5 +8,5 @@ package com.wzj.soopin.content.service;
|
||||
public interface IVlogPushService {
|
||||
boolean cacheTopLikedVlogs(int limit) ;
|
||||
|
||||
boolean pushVlogToMember(int count,Long memberId);
|
||||
boolean pushVlogToMq(int count,String tag);
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ public interface VlogService extends IService<Vlog> {
|
||||
IPage<String> getVlogForUser(Page<IndexVlogVO> page, Long memberId);
|
||||
int readVlog(Long memberId, String vlogId);
|
||||
|
||||
List<IndexVlogVO> getIndexVlogList(Map<String, Object> paramMap);
|
||||
Page<IndexVlogVO> getIndexVlogList(Map<String, Object> paramMap,Page page);
|
||||
List<IndexVlogVO> getIndexVlogList(VlogBO bo);
|
||||
Page<IndexVlogVO> getIndexVlogList(VlogBO bo,Page page);
|
||||
|
||||
}
|
||||
|
@ -26,13 +26,6 @@ public interface VlogUploadService {
|
||||
// */
|
||||
// Map<String, Object> getTaskStatus(String taskId) throws Exception;
|
||||
|
||||
/**
|
||||
* 搜索媒体文件
|
||||
*
|
||||
* @param req 搜索请求
|
||||
* @return 搜索响应
|
||||
*/
|
||||
SearchMediaResponse searchMedia(SearchMediaRequest req);
|
||||
|
||||
// 新增:视频审核
|
||||
void auditVlog(String vlogId, Integer status, String reason);
|
||||
|
@ -1,28 +1,38 @@
|
||||
package com.wzj.soopin.content.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||
import com.tencentcloudapi.vod.v20180717.VodClient;
|
||||
import com.tencentcloudapi.vod.v20180717.models.*;
|
||||
import com.wzj.soopin.content.domain.bo.VlogBO;
|
||||
import com.wzj.soopin.content.service.IVlogPullService;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.wzj.soopin.content.domain.vo.IndexVlogVO;
|
||||
import com.wzj.soopin.content.service.VlogService;
|
||||
import com.wzj.soopin.content.utils.TencentCloudUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.rocketmq.common.message.MessageExt;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.domain.model.LoginUser;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.dromara.common.mq.domain.MQMessage;
|
||||
import org.dromara.common.mq.domain.VlogPushEvent;
|
||||
import org.dromara.common.mq.utils.UserRocketMQConsumerManager;
|
||||
import org.dromara.common.redis.utils.RedisUtils;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.wzj.soopin.content.domain.base.BaseInfoProperties.REDIS_USER_LIKE_VLOG;
|
||||
import static com.wzj.soopin.content.domain.base.BaseInfoProperties.REDIS_VLOG_COMMENT_COUNTS;
|
||||
import static org.dromara.common.core.constant.GlobalConstants.HOT_VLOG_TAG;
|
||||
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
@ -31,6 +41,7 @@ public class VlogPullServiceImpl implements IVlogPullService {
|
||||
private final UserRocketMQConsumerManager mqConsumerManager;
|
||||
private final VlogService vlogService;
|
||||
private final ApplicationEventPublisher eventPublisher;
|
||||
private final TencentCloudUtil tencentCloudUtil;
|
||||
|
||||
@Override
|
||||
public Page<IndexVlogVO> page(Page<IndexVlogVO> page) {
|
||||
@ -40,7 +51,7 @@ public class VlogPullServiceImpl implements IVlogPullService {
|
||||
try {
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
if (loginUser == null) {
|
||||
messageExts = mqConsumerManager.pullUserMessages("hot", (int) page.getSize());
|
||||
messageExts = mqConsumerManager.pullUserMessages(HOT_VLOG_TAG, (int) page.getSize());
|
||||
} else {
|
||||
messageExts = mqConsumerManager.pullUserMessages(loginUser.getUserId() + "", (int) page.getSize());
|
||||
|
||||
@ -49,18 +60,22 @@ public class VlogPullServiceImpl implements IVlogPullService {
|
||||
MQMessage mqMessage = JsonUtils.parseObject(messageExt.getBody(), MQMessage.class);
|
||||
return mqMessage.getData().toString();
|
||||
}).collect(Collectors.toList());
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
VlogBO vlogBO = new VlogBO();
|
||||
if (ids.size() > 0) {
|
||||
|
||||
paramMap.put("ids", ids);
|
||||
List<IndexVlogVO> vlogVOList = vlogService.getIndexVlogList(paramMap);
|
||||
vlogBO.setIds(ids);
|
||||
List<IndexVlogVO> vlogVOList = vlogService.getIndexVlogList(vlogBO);
|
||||
return page.setRecords(vlogVOList);
|
||||
} else {
|
||||
if (loginUser != null) {
|
||||
eventPublisher.publishEvent(new VlogPushEvent(loginUser.getUserId() + ""));
|
||||
|
||||
} else {
|
||||
eventPublisher.publishEvent(new VlogPushEvent(HOT_VLOG_TAG));
|
||||
}
|
||||
//发出事件
|
||||
eventPublisher.publishEvent(new VlogPushEvent(loginUser.getUserId()));
|
||||
//先临时取10条数据
|
||||
Page<IndexVlogVO> indexVlogVOPage = vlogService.getIndexVlogList(paramMap, page);
|
||||
Page<IndexVlogVO> indexVlogVOPage = vlogService.getIndexVlogList(vlogBO, page);
|
||||
//直接获取数据库数据,并要求push类推送数据
|
||||
return indexVlogVOPage;
|
||||
}
|
||||
@ -70,4 +85,309 @@ public class VlogPullServiceImpl implements IVlogPullService {
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void pullVlog(VlogBO vlogBO) {
|
||||
try {
|
||||
// 验证分页参数
|
||||
if (vlogBO.getCurrent() < 1) {
|
||||
vlogBO.setCurrent(1L);
|
||||
}
|
||||
if (vlogBO.getSize() < 1 || vlogBO.getSize() > 50) {
|
||||
vlogBO.setSize(10L);
|
||||
}
|
||||
|
||||
// 如果有模糊查询条件、时间区间条件,或者有排序条件,则只查询数据库
|
||||
if (StringUtils.isNotBlank(vlogBO.getMobile())
|
||||
|| StringUtils.isNotBlank(vlogBO.getNickname())
|
||||
|| StringUtils.isNotBlank(vlogBO.getTitleQuery())
|
||||
|| vlogBO.getStartTime() != null
|
||||
|| vlogBO.getEndTime() != null
|
||||
|| vlogBO.getStatus() != null
|
||||
|| StringUtils.isNotBlank(vlogBO.getColumn())) {
|
||||
|
||||
// 创建分页对象
|
||||
Page<Map<String, Object>> page = new Page<>(vlogBO.getCurrent(), vlogBO.getSize());
|
||||
|
||||
// 调用服务层方法进行查询
|
||||
IPage<Map<String, Object>> result = vlogService.getVlogListByMobile(page, vlogBO);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 否则查询腾讯云点播
|
||||
// 验证密钥配置
|
||||
String secretId = tencentCloudUtil.getSecretId();
|
||||
String secretKey = tencentCloudUtil.getSecretKey();
|
||||
if (secretId == null || secretId.isEmpty() || secretKey == null || secretKey.isEmpty()) {
|
||||
log.error("腾讯云密钥未配置");
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算实际的offset
|
||||
long offset = (long) ((vlogBO.getCurrent() - 1) * vlogBO.getSize());
|
||||
if (offset < 0) {
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
// 打印分页参数
|
||||
log.info("分页参数 - 当前页码: {}, 每页记录数: {}, 偏移量: {}", vlogBO.getCurrent(), vlogBO.getSize(), offset);
|
||||
|
||||
// 创建请求对象
|
||||
SearchMediaRequest req = new SearchMediaRequest();
|
||||
|
||||
// 设置分页参数
|
||||
req.setOffset(offset);
|
||||
req.setLimit(vlogBO.getSize());
|
||||
|
||||
// 设置排序
|
||||
SortBy sort = new SortBy();
|
||||
sort.setField("CreateTime");
|
||||
sort.setOrder("Desc");
|
||||
req.setSort(sort);
|
||||
|
||||
// 调用腾讯云API获取视频列表
|
||||
log.info("开始调用腾讯云 SearchMedia API");
|
||||
SearchMediaResponse resp = searchMedia(req);
|
||||
log.info("腾讯云 SearchMedia API 调用成功,总记录数: {}", resp.getTotalCount());
|
||||
|
||||
// 处理响应结果
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("total", resp.getTotalCount());
|
||||
result.put("current", vlogBO.getCurrent());
|
||||
result.put("size", vlogBO.getSize());
|
||||
result.put("pages", (resp.getTotalCount() + vlogBO.getSize() - 1) / vlogBO.getSize()); // 总页数
|
||||
|
||||
// 批量获取所有视频的统计信息,避免重复查询
|
||||
Map<String, String> fileIdToVlogIdMap = new HashMap<>();
|
||||
List<String> allVlogIds = new ArrayList<>();
|
||||
|
||||
if (resp.getMediaInfoSet() != null) {
|
||||
for (MediaInfo mediaInfo : resp.getMediaInfoSet()) {
|
||||
String fileId = mediaInfo.getFileId();
|
||||
Map<String, Object> statistics = vlogService.getVlogStatistics(fileId);
|
||||
String vlogId = (String) statistics.get("vlogId");
|
||||
if (StringUtils.isNotBlank(vlogId)) {
|
||||
fileIdToVlogIdMap.put(fileId, vlogId);
|
||||
allVlogIds.add(vlogId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 批量获取所有点赞数据
|
||||
Map<String, Integer> vlogLikeCounts = new HashMap<>();
|
||||
Map<String, Integer> vlogCommentCounts = new HashMap<>();
|
||||
long totalLikeCounts = 0;
|
||||
long totalCommentCounts = 0;
|
||||
|
||||
if (!allVlogIds.isEmpty()) {
|
||||
// 批量获取所有点赞键
|
||||
String likePattern = REDIS_USER_LIKE_VLOG + ":*";
|
||||
Collection<String> allLikeKeys = RedisUtils.keys(likePattern);
|
||||
|
||||
if (allLikeKeys != null && !allLikeKeys.isEmpty()) {
|
||||
// 逐个获取点赞值(由于RedisUtils没有批量方法)
|
||||
Map<String, String> likeKeyValueMap = new HashMap<>();
|
||||
for (String likeKey : allLikeKeys) {
|
||||
String likeValue = RedisUtils.getCacheObject(likeKey);
|
||||
if ("1".equals(likeValue)) {
|
||||
likeKeyValueMap.put(likeKey, likeValue);
|
||||
}
|
||||
}
|
||||
|
||||
// 按vlogId分组统计点赞数
|
||||
for (String vlogId : allVlogIds) {
|
||||
int likeCount = 0;
|
||||
for (String likeKey : likeKeyValueMap.keySet()) {
|
||||
if (likeKey.endsWith(":" + vlogId)) {
|
||||
likeCount++;
|
||||
}
|
||||
}
|
||||
vlogLikeCounts.put(vlogId, likeCount);
|
||||
totalLikeCounts += likeCount;
|
||||
}
|
||||
}
|
||||
|
||||
// 批量获取所有评论数
|
||||
for (String vlogId : allVlogIds) {
|
||||
String commentKey = REDIS_VLOG_COMMENT_COUNTS + ":" + vlogId;
|
||||
String commentCountsStr = RedisUtils.getCacheObject(commentKey);
|
||||
int commentCount = 0;
|
||||
if (StringUtils.isNotBlank(commentCountsStr)) {
|
||||
try {
|
||||
commentCount = Integer.valueOf(commentCountsStr);
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("Redis中视频{}的评论数格式错误: {}", vlogId, commentCountsStr);
|
||||
}
|
||||
}
|
||||
vlogCommentCounts.put(vlogId, commentCount);
|
||||
totalCommentCounts += commentCount;
|
||||
}
|
||||
}
|
||||
|
||||
// 将总的点赞数和评论数添加到结果中
|
||||
result.put("totalLikeCounts", totalLikeCounts);
|
||||
result.put("totalCommentCounts", totalCommentCounts);
|
||||
|
||||
List<Map<String, Object>> mediaList = new ArrayList<>();
|
||||
if (resp.getMediaInfoSet() != null) {
|
||||
for (MediaInfo mediaInfo : resp.getMediaInfoSet()) {
|
||||
Map<String, Object> mediaMap = new HashMap<>();
|
||||
// 基础信息
|
||||
MediaBasicInfo basicInfo = mediaInfo.getBasicInfo();
|
||||
mediaMap.put("fileId", mediaInfo.getFileId());
|
||||
mediaMap.put("name", basicInfo.getName());
|
||||
mediaMap.put("description", basicInfo.getDescription());
|
||||
mediaMap.put("createTime", basicInfo.getCreateTime());
|
||||
mediaMap.put("updateTime", basicInfo.getUpdateTime());
|
||||
mediaMap.put("expireTime", basicInfo.getExpireTime());
|
||||
mediaMap.put("classId", basicInfo.getClassId());
|
||||
mediaMap.put("className", basicInfo.getClassName());
|
||||
mediaMap.put("classPath", basicInfo.getClassPath());
|
||||
mediaMap.put("coverUrl", basicInfo.getCoverUrl());
|
||||
mediaMap.put("type", basicInfo.getType());
|
||||
mediaMap.put("mediaUrl", basicInfo.getMediaUrl());
|
||||
mediaMap.put("status", basicInfo.getStatus());
|
||||
mediaMap.put("storageRegion", basicInfo.getStorageRegion());
|
||||
mediaMap.put("category", basicInfo.getCategory());
|
||||
mediaMap.put("storageClass", basicInfo.getStorageClass());
|
||||
mediaMap.put("tagSet", basicInfo.getTagSet());
|
||||
|
||||
// 获取视频统计信息
|
||||
Map<String, Object> statistics = vlogService.getVlogStatistics(mediaInfo.getFileId());
|
||||
mediaMap.putAll(statistics);
|
||||
|
||||
// 从statistics中获取vlogId,用于Redis查询
|
||||
String vlogId = (String) statistics.get("vlogId");
|
||||
log.info("处理视频 fileId: {}, vlogId: {}", mediaInfo.getFileId(), vlogId);
|
||||
|
||||
// 使用批量获取的数据,避免重复查询Redis
|
||||
int videoLikeCounts = 0;
|
||||
int videoCommentCounts = 0;
|
||||
if (StringUtils.isNotBlank(vlogId)) {
|
||||
videoLikeCounts = vlogLikeCounts.getOrDefault(vlogId, 0);
|
||||
videoCommentCounts = vlogCommentCounts.getOrDefault(vlogId, 0);
|
||||
}
|
||||
mediaMap.put("likeCounts", videoLikeCounts);
|
||||
mediaMap.put("commentCounts", videoCommentCounts);
|
||||
|
||||
// 获取视频上传者信息
|
||||
Map<String, String> uploaderInfo = vlogService.getVlogUploaderInfo(mediaInfo.getFileId());
|
||||
if (uploaderInfo != null) {
|
||||
mediaMap.put("nickname", uploaderInfo.get("name"));
|
||||
mediaMap.put("mobile", uploaderInfo.get("phone"));
|
||||
}
|
||||
|
||||
mediaList.add(mediaMap);
|
||||
}
|
||||
}
|
||||
result.put("records", mediaList);
|
||||
}catch (Exception e){
|
||||
log.error("拉取视频失败: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public SearchMediaResponse searchMedia(SearchMediaRequest req) {
|
||||
try {
|
||||
// 获取VOD客户端实例
|
||||
VodClient client = tencentCloudUtil.getVodClient();
|
||||
|
||||
// 设置默认值
|
||||
if (req.getOffset() == null) {
|
||||
req.setOffset(0L);
|
||||
}
|
||||
if (req.getLimit() == null) {
|
||||
req.setLimit(10L);
|
||||
}
|
||||
|
||||
// 添加日志,打印请求参数
|
||||
// log.info("SearchMediaRequest 请求参数: {}", req.toJsonString());
|
||||
|
||||
// 添加调试信息
|
||||
log.info("请求时间戳: {}", System.currentTimeMillis());
|
||||
log.info("请求参数详情 - Offset: {}, Limit: {}, Sort: {}, Filters: {}",
|
||||
req.getOffset(),
|
||||
req.getLimit(),
|
||||
// req.getSort() != null ? req.getSort().toJsonString() : "null",
|
||||
req.getFilters() != null ? String.join(",", req.getFilters()) : "null");
|
||||
|
||||
// 验证请求参数
|
||||
validateSearchRequest(req);
|
||||
|
||||
SearchMediaResponse response = client.SearchMedia(req);
|
||||
log.info("SearchMedia API 调用成功,返回结果数: {}", response.getTotalCount());
|
||||
return response;
|
||||
} catch (TencentCloudSDKException e) {
|
||||
log.error("搜索媒体文件失败: {}", e.getMessage(), e);
|
||||
// 添加更详细的错误信息
|
||||
if (e.getMessage().contains("signature")) {
|
||||
log.error("签名验证失败,请检查:\n1. 密钥是否正确\n2. 服务器时间是否准确\n3. 时区设置是否正确");
|
||||
} else if (e.getMessage().contains("InvalidParameterValue")) {
|
||||
log.error("参数值错误,请检查:\n1. 分页参数 Offset 和 Limit 是否有效\n2. 搜索条件是否合法\n3. 排序参数是否正确");
|
||||
} else if (e.getMessage().contains("UnauthorizedOperation")) {
|
||||
log.error("未授权操作,请检查:\n1. 密钥是否有权限\n2. 应用 ID 是否正确\n3. 是否开通了点播服务");
|
||||
}
|
||||
throw new RuntimeException("搜索媒体文件失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 验证搜索请求参数
|
||||
*/
|
||||
private void validateSearchRequest(SearchMediaRequest req) {
|
||||
// 验证分页参数
|
||||
if (req.getOffset() < 0) {
|
||||
throw new IllegalArgumentException("Offset 不能小于 0");
|
||||
}
|
||||
if (req.getLimit() < 1 || req.getLimit() > 50) {
|
||||
throw new IllegalArgumentException("Limit 必须在 1-50 之间");
|
||||
}
|
||||
if (req.getOffset() + req.getLimit() > 5000) {
|
||||
throw new IllegalArgumentException("Offset + Limit 不能超过 5000");
|
||||
}
|
||||
|
||||
// 验证搜索条件
|
||||
if (req.getFileIds() != null && req.getFileIds().length > 10) {
|
||||
throw new IllegalArgumentException("FileIds 数组长度不能超过 10");
|
||||
}
|
||||
if (req.getNames() != null && req.getNames().length > 10) {
|
||||
throw new IllegalArgumentException("Names 数组长度不能超过 10");
|
||||
}
|
||||
if (req.getNamePrefixes() != null && req.getNamePrefixes().length > 10) {
|
||||
throw new IllegalArgumentException("NamePrefixes 数组长度不能超过 10");
|
||||
}
|
||||
if (req.getDescriptions() != null && req.getDescriptions().length > 10) {
|
||||
throw new IllegalArgumentException("Descriptions 数组长度不能超过 10");
|
||||
}
|
||||
if (req.getClassIds() != null && req.getClassIds().length > 10) {
|
||||
throw new IllegalArgumentException("ClassIds 数组长度不能超过 10");
|
||||
}
|
||||
if (req.getTags() != null && req.getTags().length > 16) {
|
||||
throw new IllegalArgumentException("Tags 数组长度不能超过 16");
|
||||
}
|
||||
if (req.getSourceTypes() != null && req.getSourceTypes().length > 10) {
|
||||
throw new IllegalArgumentException("SourceTypes 数组长度不能超过 10");
|
||||
}
|
||||
if (req.getStreamIds() != null && req.getStreamIds().length > 10) {
|
||||
throw new IllegalArgumentException("StreamIds 数组长度不能超过 10");
|
||||
}
|
||||
if (req.getStorageRegions() != null && req.getStorageRegions().length > 20) {
|
||||
throw new IllegalArgumentException("StorageRegions 数组长度不能超过 20");
|
||||
}
|
||||
// if (req.getMediaTypes() != null && req.getMediaTypes().length > 10) {
|
||||
// throw new IllegalArgumentException("MediaTypes 数组长度不能超过 10");
|
||||
// }
|
||||
// if (req.getStatus() != null && req.getStatus().length > 10) {
|
||||
// throw new IllegalArgumentException("Status 数组长度不能超过 10");
|
||||
// }
|
||||
// if (req.getReviewResults() != null && req.getReviewResults().length > 10) {
|
||||
// throw new IllegalArgumentException("ReviewResults 数组长度不能超过 10");
|
||||
// }
|
||||
// if (req.getTrtcSdkAppIds() != null && req.getTrtcSdkAppIds().length > 10) {
|
||||
// throw new IllegalArgumentException("TrtcSdkAppIds 数组长度不能超过 10");
|
||||
// }
|
||||
// if (req.getTrtcRoomIds() != null && req.getTrtcRoomIds().length > 10) {
|
||||
// throw new IllegalArgumentException("TrtcRoomIds 数组长度不能超过 10");
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.wzj.soopin.content.domain.base.BaseInfoProperties.REDIS_VLOG_BE_LIKED_COUNTS;
|
||||
import static org.dromara.common.core.constant.GlobalConstants.HOT_VLOG_TAG;
|
||||
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
@ -38,18 +39,29 @@ public class VlogPushServiceImpl implements IVlogPushService {
|
||||
@Override
|
||||
public boolean cacheTopLikedVlogs(int limit ) {
|
||||
try {
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("缓存点赞最多视频到Redis失败", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pushVlogToMq(int count,String tag ) {
|
||||
|
||||
if(tag.equals(HOT_VLOG_TAG)){
|
||||
// 1. 获取 ZSet 中所有成员(按分数升序排列)
|
||||
// 这里我们只关心成员(member),不关心分数(score),所以使用 range(key, start, end)
|
||||
log.info("开始查询点赞最多的{}条视频", limit);
|
||||
Set<String> rankSet = redisCache.zSetRange(REDIS_VLOG_BE_LIKED_COUNTS, 0, limit);
|
||||
log.info("开始查询点赞最多的{}条视频", count);
|
||||
Set<String> rankSet = redisCache.zSetRange(REDIS_VLOG_BE_LIKED_COUNTS, 0, count);
|
||||
if (rankSet == null ||rankSet.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if(rankSet!=null&&rankSet.size()<limit){
|
||||
if(rankSet!=null&&rankSet.size()<count){
|
||||
//从数据库中获取差量数据
|
||||
Page<Vlog> vlogPage = new Page<>(1, limit-rankSet.size());
|
||||
Page<Vlog> vlogPage = new Page<>(1, count-rankSet.size());
|
||||
vlogPage = vlogService.page(vlogPage, new LambdaQueryWrapper<Vlog>()
|
||||
.orderByDesc(Vlog::getLikeCounts));
|
||||
.orderByDesc(Vlog::getLikeCounts));
|
||||
Set<String> vlogIds = vlogPage.getRecords().stream().map(vlog -> vlog.getId()).collect(Collectors.toSet());
|
||||
rankSet.addAll(vlogIds);
|
||||
}
|
||||
@ -63,42 +75,36 @@ public class VlogPushServiceImpl implements IVlogPushService {
|
||||
//将数据发送的mq的热点数据队列
|
||||
MQMessage message = MQMessage.builder()
|
||||
.topic("MEMBER_VLOG_MSG")
|
||||
.tag("hot")
|
||||
.tag(HOT_VLOG_TAG)
|
||||
.messageType("json")
|
||||
.data(vlogId)
|
||||
.source("vlog_service")
|
||||
.sendTime(LocalDateTime.now())
|
||||
.build();
|
||||
MqUtil.sendMessage("MEMBER_VLOG_MSG", message);
|
||||
MqUtil.sendMessage("MEMBER_VLOG_MSG",HOT_VLOG_TAG, message);
|
||||
});
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("缓存点赞最多视频到Redis失败", e);
|
||||
}else{
|
||||
Member member = memberService.getById(tag);
|
||||
String cityCode = member.getCity();
|
||||
IPage<String> vlogPage=vlogService.getVlogForUser(new Page<>(1, 100), Long.parseLong(tag));
|
||||
if(CollectionUtils.isEmpty(vlogPage.getRecords())){
|
||||
return false;
|
||||
}
|
||||
vlogPage.getRecords().stream().forEach(vlogId -> {
|
||||
//将数据发送的mq的热点数据队列
|
||||
MQMessage message = MQMessage.builder()
|
||||
.topic("MEMBER_VLOG_MSG")
|
||||
.tag(tag)
|
||||
.messageType("json")
|
||||
.data(vlogId)
|
||||
.source("vlog_service")
|
||||
.sendTime(LocalDateTime.now())
|
||||
.build();
|
||||
MqUtil.sendMessage("MEMBER_VLOG_MSG"+":"+tag, message);
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pushVlogToMember(int count,Long memberId ) {
|
||||
|
||||
Member member = memberService.getById(memberId);
|
||||
String cityCode = member.getCity();
|
||||
IPage<String> vlogPage=vlogService.getVlogForUser(new Page<>(1, 100), memberId);
|
||||
if(CollectionUtils.isEmpty(vlogPage.getRecords())){
|
||||
return false;
|
||||
}
|
||||
vlogPage.getRecords().stream().forEach(vlogId -> {
|
||||
//将数据发送的mq的热点数据队列
|
||||
MQMessage message = MQMessage.builder()
|
||||
.topic("MEMBER_VLOG_MSG")
|
||||
.tag(memberId+"")
|
||||
.messageType("json")
|
||||
.data(vlogId)
|
||||
.source("vlog_service")
|
||||
.sendTime(LocalDateTime.now())
|
||||
.build();
|
||||
MqUtil.sendMessage("MEMBER_VLOG_MSG"+":"+memberId, message);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -612,15 +612,15 @@ public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements Vl
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IndexVlogVO> getIndexVlogList(Map<String, Object> paramMap) {
|
||||
List<IndexVlogVO> indexVlogVOPage = vlogMapperCustom.getIndexVlogList(paramMap);
|
||||
public List<IndexVlogVO> getIndexVlogList(VlogBO bo) {
|
||||
List<IndexVlogVO> indexVlogVOPage = vlogMapperCustom.getIndexVlogList(bo);
|
||||
fillRedisColumn(indexVlogVOPage );
|
||||
return indexVlogVOPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<IndexVlogVO> getIndexVlogList(Map<String, Object> paramMap, Page page) {
|
||||
Page<IndexVlogVO> indexVlogVOPage = vlogMapperCustom.getIndexVlogList(paramMap,page);
|
||||
public Page<IndexVlogVO> getIndexVlogList(VlogBO bo, Page page) {
|
||||
Page<IndexVlogVO> indexVlogVOPage = vlogMapperCustom.getIndexVlogList(bo,page);
|
||||
fillRedisColumn(indexVlogVOPage.getRecords());
|
||||
return indexVlogVOPage;
|
||||
}
|
||||
|
@ -49,110 +49,8 @@ public class VlogUploadServiceImpl implements VlogUploadService {
|
||||
// return client.PullUpload(req);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public SearchMediaResponse searchMedia(SearchMediaRequest req) {
|
||||
try {
|
||||
// 获取VOD客户端实例
|
||||
VodClient client = tencentCloudUtil.getVodClient();
|
||||
|
||||
// 设置默认值
|
||||
if (req.getOffset() == null) {
|
||||
req.setOffset(0L);
|
||||
}
|
||||
if (req.getLimit() == null) {
|
||||
req.setLimit(10L);
|
||||
}
|
||||
|
||||
// 添加日志,打印请求参数
|
||||
// log.info("SearchMediaRequest 请求参数: {}", req.toJsonString());
|
||||
|
||||
// 添加调试信息
|
||||
log.info("请求时间戳: {}", System.currentTimeMillis());
|
||||
log.info("请求参数详情 - Offset: {}, Limit: {}, Sort: {}, Filters: {}",
|
||||
req.getOffset(),
|
||||
req.getLimit(),
|
||||
// req.getSort() != null ? req.getSort().toJsonString() : "null",
|
||||
req.getFilters() != null ? String.join(",", req.getFilters()) : "null");
|
||||
|
||||
// 验证请求参数
|
||||
validateSearchRequest(req);
|
||||
|
||||
SearchMediaResponse response = client.SearchMedia(req);
|
||||
log.info("SearchMedia API 调用成功,返回结果数: {}", response.getTotalCount());
|
||||
return response;
|
||||
} catch (TencentCloudSDKException e) {
|
||||
log.error("搜索媒体文件失败: {}", e.getMessage(), e);
|
||||
// 添加更详细的错误信息
|
||||
if (e.getMessage().contains("signature")) {
|
||||
log.error("签名验证失败,请检查:\n1. 密钥是否正确\n2. 服务器时间是否准确\n3. 时区设置是否正确");
|
||||
} else if (e.getMessage().contains("InvalidParameterValue")) {
|
||||
log.error("参数值错误,请检查:\n1. 分页参数 Offset 和 Limit 是否有效\n2. 搜索条件是否合法\n3. 排序参数是否正确");
|
||||
} else if (e.getMessage().contains("UnauthorizedOperation")) {
|
||||
log.error("未授权操作,请检查:\n1. 密钥是否有权限\n2. 应用 ID 是否正确\n3. 是否开通了点播服务");
|
||||
}
|
||||
throw new RuntimeException("搜索媒体文件失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证搜索请求参数
|
||||
*/
|
||||
private void validateSearchRequest(SearchMediaRequest req) {
|
||||
// 验证分页参数
|
||||
if (req.getOffset() < 0) {
|
||||
throw new IllegalArgumentException("Offset 不能小于 0");
|
||||
}
|
||||
if (req.getLimit() < 1 || req.getLimit() > 50) {
|
||||
throw new IllegalArgumentException("Limit 必须在 1-50 之间");
|
||||
}
|
||||
if (req.getOffset() + req.getLimit() > 5000) {
|
||||
throw new IllegalArgumentException("Offset + Limit 不能超过 5000");
|
||||
}
|
||||
|
||||
// 验证搜索条件
|
||||
if (req.getFileIds() != null && req.getFileIds().length > 10) {
|
||||
throw new IllegalArgumentException("FileIds 数组长度不能超过 10");
|
||||
}
|
||||
if (req.getNames() != null && req.getNames().length > 10) {
|
||||
throw new IllegalArgumentException("Names 数组长度不能超过 10");
|
||||
}
|
||||
if (req.getNamePrefixes() != null && req.getNamePrefixes().length > 10) {
|
||||
throw new IllegalArgumentException("NamePrefixes 数组长度不能超过 10");
|
||||
}
|
||||
if (req.getDescriptions() != null && req.getDescriptions().length > 10) {
|
||||
throw new IllegalArgumentException("Descriptions 数组长度不能超过 10");
|
||||
}
|
||||
if (req.getClassIds() != null && req.getClassIds().length > 10) {
|
||||
throw new IllegalArgumentException("ClassIds 数组长度不能超过 10");
|
||||
}
|
||||
if (req.getTags() != null && req.getTags().length > 16) {
|
||||
throw new IllegalArgumentException("Tags 数组长度不能超过 16");
|
||||
}
|
||||
if (req.getSourceTypes() != null && req.getSourceTypes().length > 10) {
|
||||
throw new IllegalArgumentException("SourceTypes 数组长度不能超过 10");
|
||||
}
|
||||
if (req.getStreamIds() != null && req.getStreamIds().length > 10) {
|
||||
throw new IllegalArgumentException("StreamIds 数组长度不能超过 10");
|
||||
}
|
||||
if (req.getStorageRegions() != null && req.getStorageRegions().length > 20) {
|
||||
throw new IllegalArgumentException("StorageRegions 数组长度不能超过 20");
|
||||
}
|
||||
// if (req.getMediaTypes() != null && req.getMediaTypes().length > 10) {
|
||||
// throw new IllegalArgumentException("MediaTypes 数组长度不能超过 10");
|
||||
// }
|
||||
// if (req.getStatus() != null && req.getStatus().length > 10) {
|
||||
// throw new IllegalArgumentException("Status 数组长度不能超过 10");
|
||||
// }
|
||||
// if (req.getReviewResults() != null && req.getReviewResults().length > 10) {
|
||||
// throw new IllegalArgumentException("ReviewResults 数组长度不能超过 10");
|
||||
// }
|
||||
// if (req.getTrtcSdkAppIds() != null && req.getTrtcSdkAppIds().length > 10) {
|
||||
// throw new IllegalArgumentException("TrtcSdkAppIds 数组长度不能超过 10");
|
||||
// }
|
||||
// if (req.getTrtcRoomIds() != null && req.getTrtcRoomIds().length > 10) {
|
||||
// throw new IllegalArgumentException("TrtcRoomIds 数组长度不能超过 10");
|
||||
// }
|
||||
}
|
||||
|
||||
// 视频审核
|
||||
@Override
|
||||
|
@ -32,35 +32,35 @@
|
||||
WHERE
|
||||
v.is_private = 0
|
||||
<choose>
|
||||
<when test="paramMap.status != null and paramMap.status!=''">
|
||||
AND v.status = #{paramMap.status}
|
||||
<when test="bo.status != null and bo.status!=''">
|
||||
AND v.status = #{bo.status}
|
||||
</when>
|
||||
<otherwise>
|
||||
AND v.status = 1
|
||||
</otherwise>
|
||||
</choose>
|
||||
AND v.first_frame_img IS NOT NULL
|
||||
<if test="paramMap.cityCode != null and paramMap.cityCode != ''">
|
||||
AND v.city_code = #{paramMap.cityCode}
|
||||
<if test="bo.cityCode != null and bo.cityCode != ''">
|
||||
AND v.city_code = #{bo.cityCode}
|
||||
</if>
|
||||
<if test="paramMap.search != null and paramMap.search != ''">
|
||||
AND v.title like '%${paramMap.search}%'
|
||||
<if test="bo.title != null and bo.title != ''">
|
||||
AND v.title like '%${bo.title}%'
|
||||
</if>
|
||||
<if test="paramMap.blockVd != null and paramMap.blockVd.size() > 0">
|
||||
<if test="bo.blockVd != null and bo.blockVd.size() > 0">
|
||||
AND v.id NOT IN
|
||||
<foreach collection="paramMap.blockVd" item="vlogId" open="(" separator="," close=")">
|
||||
<foreach collection="bo.blockVd" item="vlogId" open="(" separator="," close=")">
|
||||
#{vlogId}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="paramMap.blockUser != null and paramMap.blockUser.size() > 0">
|
||||
<if test="bo.blockUser != null and bo.blockUser.size() > 0">
|
||||
AND v.member_id NOT IN
|
||||
<foreach collection="paramMap.blockUser" item="memberId" open="(" separator="," close=")">
|
||||
<foreach collection="bo.blockUser" item="memberId" open="(" separator="," close=")">
|
||||
#{memberId}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="paramMap.ids != null and paramMap.ids.size() > 0">
|
||||
<if test="bo.ids != null and bo.ids.size() > 0">
|
||||
AND v.id IN
|
||||
<foreach collection="paramMap.ids" item="vlogId" open="(" separator="," close=")">
|
||||
<foreach collection="bo.ids" item="vlogId" open="(" separator="," close=")">
|
||||
#{vlogId}
|
||||
</foreach>
|
||||
</if>
|
||||
|
Loading…
x
Reference in New Issue
Block a user