feat(content): 新增视频审核功能并优化状态管理

- 新增 AuditVlogBO 类用于视频审核请求参数
- 在 VlogController 中增加视频审核状态变更接口
- 修改 VlogService 接口与实现类,支持通过 BO 对象更新审核状态-为 Vlog 实体类添加 Lombok 注解以简化构建
- 调整视频列表查询逻辑,支持按是否私密和状态筛选
- 更新 VlogMapperCustom.xml 查询条件动态 SQL 结构- 设置默认视频状态为“待审核”
- 移除冗余的用户 ID 参数校验,改用 BO 校验方式
- 引入枚举 VlogStatusEnum 的 Getter 方法便于获取状态值
This commit is contained in:
huk 2025-09-29 16:10:49 +08:00
parent eeab201625
commit 4c1e123214
9 changed files with 141 additions and 123 deletions

View File

@ -3,6 +3,8 @@ package org.dromara.app;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wzj.soopin.content.domain.bo.*;
import com.wzj.soopin.content.domain.vo.IndexVlogVO;
import com.wzj.soopin.content.enums.VlogStatusEnum;
import com.wzj.soopin.content.enums.YesOrNo;
import com.wzj.soopin.content.service.IVlogPullService;
import com.wzj.soopin.content.service.VlogService;
import com.wzj.soopin.content.service.VlogUploadService;
@ -160,11 +162,11 @@ public class AppVlogController {
@Operation(summary = "视频列表")
@PostMapping("/page")
public R<Page<IndexVlogVO>> page(@RequestBody VlogBO vlogBO) {
LoginUser loginUser = LoginHelper.getLoginUser();
if(vlogBO.getMemberId()==null){
throw new ServiceException("用户id不能为空");
}
vlogBO.setStatus(VlogStatusEnum.APPROVED.type);
vlogBO.setIsPrivate(YesOrNo.NO.type);
return R.ok(vlogService.getIndexVlogList(vlogBO,vlogBO.getPage()));
}

View File

@ -3,7 +3,7 @@ package com.wzj.soopin.content.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.dromara.common.core.constant.BaseInfoProperties;
import com.wzj.soopin.content.domain.bo.AuditVlogBO;
import com.wzj.soopin.content.domain.bo.VlogBO;
import com.wzj.soopin.content.domain.vo.IndexVlogVO;
import com.wzj.soopin.content.enums.YesOrNo;
@ -13,19 +13,23 @@ import com.wzj.soopin.content.service.VlogService;
import com.wzj.soopin.content.utils.RedisOperator;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.BaseInfoProperties;
import org.dromara.common.core.domain.R;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@Slf4j
@Tag(name = "短视频相关业务功能的接口")
@Tag(name = "短视频管理")
@RequestMapping("/cms/vlog")
@RestController
@AllArgsConstructor
@Validated
public class VlogController extends BaseInfoProperties {
private final VlogService vlogService;
public final RedisOperator redis;
@ -38,6 +42,7 @@ public class VlogController extends BaseInfoProperties {
Page<IndexVlogVO> pages = vlogService.getIndexVlogList(bo, page);
return R.ok(pages);
}
@PostMapping("/vodCallBack")
public R<Void> vodCallBack(@RequestBody Map<String, Object> callbackData) {
try {
@ -148,36 +153,24 @@ public class VlogController extends BaseInfoProperties {
}
@Operation(summary = "修改视频状态")
@PostMapping("/changeVlogStatus")
public R<Void> changeVlogStatus(@RequestParam String userId,
@RequestParam String vlogId,
@RequestParam Integer status) {
vlogService.changeVlogStatus(userId, vlogId,status);
public R<Void> changeVlogStatus(@RequestBody @Valid AuditVlogBO bo) {
vlogService.changeVlogStatus(bo);
return R.ok();
}
@Operation(summary = "修改视频为私密")
@PostMapping("/changeToPrivate")
public R<Void> changeToPrivate(@RequestParam String userId,
@RequestParam String vlogId) {
vlogService.changeToPrivateOrPublic(userId,
vlogId,
YesOrNo.YES.type);
public R<Void> changeToPrivate(@RequestParam String vlogId) {
vlogService.changeToPrivateOrPublic(vlogId, YesOrNo.YES.type);
return R.ok();
}
@Operation(summary = "修改视频为公开")
@PostMapping("/changeToPublic")
public R<Void> changeToPublic(@RequestParam String userId,
@RequestParam String vlogId) {
vlogService.changeToPrivateOrPublic(userId,
vlogId,
YesOrNo.NO.type);
public R<Void> changeToPublic(@RequestParam String vlogId) {
vlogService.changeToPrivateOrPublic(vlogId, YesOrNo.NO.type);
return R.ok();
}

View File

@ -0,0 +1,35 @@
package com.wzj.soopin.content.domain.bo;
import com.wzj.soopin.content.enums.VlogStatusEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 视频审核BO
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AuditVlogBO {
@Schema(description = "视频id")
@NotBlank(message = "视频id不能为空")
private String vlogId;
/**
* 状态
* @see VlogStatusEnum#getType()
*/
@NotNull(message = "状态不能为空")
@Schema(description = "审核状态", implementation = VlogStatusEnum.class)
private Integer status;
@Schema(description = "未通过原因")
private String reason;
}

View File

@ -54,6 +54,9 @@ public class VlogBO extends BaseBO {
@Schema(description = "视频标题(模糊查询)")
private String titleQuery;
@Schema(description = "是否私密")
private Integer isPrivate;
@Schema(description = "视频状态(精确查询)")
private Integer status;

View File

@ -1,15 +1,16 @@
package com.wzj.soopin.content.domain.po;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.*;
import org.apache.ibatis.type.JdbcType;
import org.dromara.common.core.domain.model.BaseAudit;
@TableName(value = "cont_vlog", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Vlog extends BaseAudit {
@TableId
private String id;

View File

@ -1,8 +1,10 @@
package com.wzj.soopin.content.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum VlogStatusEnum {
AUDITING(0, "待审核"),
APPROVED(1, "通过"),

View File

@ -3,10 +3,12 @@ package com.wzj.soopin.content.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.wzj.soopin.content.domain.bo.*;
import com.wzj.soopin.content.domain.bo.AuditVlogBO;
import com.wzj.soopin.content.domain.bo.MyListBO;
import com.wzj.soopin.content.domain.bo.SearchBO;
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.utils.PagedGridResult;
import java.util.List;
import java.util.Map;
@ -34,13 +36,9 @@ public interface VlogService extends IService<Vlog> {
/**
* 用户把视频改为公开/私密的视频
*/
public void changeToPrivateOrPublic(String userId,
String vlogId,
Integer yesOrNo);
public void changeToPrivateOrPublic(String vlogId, Integer yesOrNo);
public void changeVlogStatus(String userId,
String vlogId,
Integer status);
public void changeVlogStatus(AuditVlogBO auditVlogBO);
/**
* 查询用的公开/私密的视频列表
*/

View File

@ -8,32 +8,36 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wzj.soopin.content.domain.bo.*;
import com.wzj.soopin.content.convert.VlogConvert;
import com.wzj.soopin.content.domain.bo.AuditVlogBO;
import com.wzj.soopin.content.domain.bo.MyListBO;
import com.wzj.soopin.content.domain.bo.SearchBO;
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.enums.VlogStatusEnum;
import com.wzj.soopin.member.domain.po.Member;
import com.wzj.soopin.content.domain.vo.IndexVlogVO;
import com.wzj.soopin.content.enums.VlogStatusEnum;
import com.wzj.soopin.content.enums.YesOrNo;
import com.wzj.soopin.content.mapper.CommentMapper;
import com.wzj.soopin.content.mapper.MyLikedVlogMapper;
import com.wzj.soopin.member.domain.vo.MemberVO;
import com.wzj.soopin.member.mapper.MemberMapper;
import com.wzj.soopin.content.mapper.VlogMapper;
import com.wzj.soopin.content.mapper.VlogMapperCustom;
import com.wzj.soopin.content.service.MsgService;
import com.wzj.soopin.content.service.VlogService;
import com.wzj.soopin.content.utils.RedisOperator;
import com.wzj.soopin.content.utils.Sid;
import com.wzj.soopin.member.domain.po.Member;
import com.wzj.soopin.member.domain.vo.MemberVO;
import com.wzj.soopin.member.mapper.MemberMapper;
import com.wzj.soopin.member.service.IFansService;
import com.wzj.soopin.content.convert.VlogConvert;
import com.wzj.soopin.member.service.IMemberService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.mq.config.RocketMQConfig;
import org.dromara.common.mq.domain.MQMessage;
import org.dromara.common.mq.enums.MQMessageType;
@ -46,16 +50,12 @@ import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.dromara.common.core.utils.MapstructUtils;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;
import java.util.ArrayList;
import lombok.extern.slf4j.Slf4j;
import static org.dromara.common.core.constant.BaseInfoProperties.*;
@ -141,7 +141,7 @@ public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements Vl
vlog.setId(vid);
vlog.setLikeCounts(0);
vlog.setCommentsCounts(0);
vlog.setStatus(0);
vlog.setStatus(VlogStatusEnum.AUDITING.type);
vlog.setIsPrivate(YesOrNo.NO.type);
vlog.setMemberId(loginUser.getUserId()+"");
@ -213,25 +213,16 @@ public class VlogServiceImpl extends ServiceImpl<VlogMapper, Vlog> implements Vl
@Transactional(rollbackFor = Exception.class)
@Override
@CacheEvict(value = GlobalConstants.VLOG_KEY, key = "#vlogId")
public void changeToPrivateOrPublic(String userId, String vlogId, Integer yesOrNo) {
LambdaUpdateWrapper<Vlog> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Vlog::getId, vlogId)
.eq(Vlog::getMemberId, userId)
.set(Vlog::getIsPrivate, yesOrNo);
vlogMapper.update(null, updateWrapper);
public void changeToPrivateOrPublic(String vlogId, Integer yesOrNo) {
vlogMapper.updateById(Vlog.builder().id(vlogId).isPrivate(yesOrNo).build());
}
@Transactional(rollbackFor = Exception.class)
@Override
@CacheEvict(value = GlobalConstants.VLOG_KEY, key = "#vlogId")
public void changeVlogStatus(String userId, String vlogId, Integer status) {
LambdaUpdateWrapper<Vlog> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Vlog::getId, vlogId)
.eq(Vlog::getMemberId, userId)
.set(Vlog::getStatus, status);
vlogMapper.update(null, updateWrapper);
@CacheEvict(value = GlobalConstants.VLOG_KEY, key = "#bo.vlogId")
public void changeVlogStatus(AuditVlogBO bo) {
vlogMapper.updateById(Vlog.builder().id(bo.getVlogId()).status(bo.getStatus()).reason(bo.getReason()).build());
}
@Override

View File

@ -3,8 +3,7 @@
<mapper namespace="com.wzj.soopin.content.mapper.VlogMapperCustom" >
<select id="getIndexVlogList" parameterType="map" resultType="com.wzj.soopin.content.domain.vo.IndexVlogVO">
SELECT
v.id,
SELECT v.id,
v.member_id,
m.avatar,
m.nickname,
@ -24,23 +23,18 @@
v.file_id as fileId,
v.status as status,
v.first_frame_img as firstFrameImg
FROM
cont_vlog v
FROM cont_vlog v
LEFT JOIN
ums_member m
ON
v.member_id = m.id
WHERE
v.is_private = 0
<choose>
<when test="bo.status != null and bo.status!=''">
WHERE v.first_frame_img IS NOT NULL
<if test="bo.isPrivate != null">
AND v.is_private = #{bo.isPrivate}
</if>
<if test="bo.status != null">
AND v.status = #{bo.status}
</when>
<otherwise>
AND v.status = 1
</otherwise>
</choose>
AND v.first_frame_img IS NOT NULL
</if>
<if test="bo.cityCode != null and bo.cityCode != ''">
AND v.city_code = #{bo.cityCode}
</if>
@ -77,8 +71,7 @@
#{vlogId}
</foreach>
</if>
ORDER BY
v.create_time
ORDER BY v.create_time
DESC
</select>