288ce585418550bbf2fd898fc01bc2ff9245f960..b1383a4dcd8c1b228174e28fb8331ee078115cb8
5 天以前 xiangpei
小程序端视频编辑、下架、删除接口
b1383a 对比 | 目录
5 天以前 xiangpei
视频接口完善
0bcc66 对比 | 目录
8个文件已修改
1个文件已添加
214 ■■■■ 已修改文件
buyer-api/src/main/java/cn/lili/controller/lmk/VideoController.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/form/WxVideoForm.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/vo/WxEditVideoVO.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/domain/vo/WxVideoTagVO.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/enums/general/VideoSupportOpEnum.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/service/VideoService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/service/impl/VideoServiceImpl.java 109 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/java/cn/lili/modules/lmk/service/impl/VideoTagServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
framework/src/main/resources/mapper/lmk/VideoMapper.xml 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
buyer-api/src/main/java/cn/lili/controller/lmk/VideoController.java
@@ -43,7 +43,7 @@
    @PutMapping
    @ApiOperation(value = "修改", notes = "修改")
    public Result update(@RequestBody @Validated(Update.class) WxVideoForm form) {
        return videoService.update(form);
        return videoService.updatePublish(form);
    }
    @DeleteMapping("/{id}")
@@ -52,6 +52,12 @@
        return videoService.removeById(id);
    }
    @PostMapping("/down/{id}")
    @ApiOperation(value = "用户下架视频", notes = "用户下架视频")
    public Result downVideo(@PathVariable("id") String id) {
        return videoService.buyerDownVideo(id);
    }
    @DeleteMapping("/batch")
    @ApiOperation(value = "批量删除", notes = "批量删除")
    public Result remove(@RequestBody @NotEmpty(message = "请选择数据") List<String> ids) {
framework/src/main/java/cn/lili/modules/lmk/domain/form/WxVideoForm.java
@@ -5,12 +5,11 @@
import cn.lili.base.AbsForm;
import cn.lili.modules.lmk.domain.entity.Video;
import cn.lili.modules.lmk.domain.vo.VideoGoodsPublishVO;
import cn.lili.modules.lmk.domain.vo.VideoGoodsVO;
import org.hibernate.validator.constraints.Length;
import org.springframework.beans.BeanUtils;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.springframework.lang.NonNull;
import io.swagger.annotations.ApiModel;
@@ -51,7 +50,7 @@
    private List<String> videoImgs;
    @ApiModelProperty("视频标签")
    @Length(max = 5, message = "最多只能添加五个标签")
    @Size(max = 5, message = "最多只能添加五个标签", groups = {Add.class, Update.class})
    private List<WxVideoTagForm> tags = new ArrayList<>(2);
//    @NotBlank(message = "商品id不能为空", groups = {Add.class, Update.class})
framework/src/main/java/cn/lili/modules/lmk/domain/vo/WxEditVideoVO.java
@@ -35,6 +35,18 @@
    @ApiModelProperty("视频标签")
    private List<WxVideoTagForm> tags;
    @ApiModelProperty("图集-json数组")
    private String videoImgs;
    @ApiModelProperty("图集")
    private List<String> imgs;
    /**
     * @see cn.lili.modules.lmk.enums.general.VideoContentTypeEnum
     */
    @ApiModelProperty("视频内容类型:视频、图片")
    private String videoContentType;
    /** 视频填充模式 */
    @ApiModelProperty("视频填充模式")
    private String videoFit;
@@ -45,7 +57,7 @@
    /** 商品信息 */
    @ApiModelProperty("商品信息")
    private String goodsId;
    private List<VideoGoodsDetailVO> goodsList;
    @ApiModelProperty("视频长度:秒")
    private Long videoDuration;
framework/src/main/java/cn/lili/modules/lmk/domain/vo/WxVideoTagVO.java
New file
@@ -0,0 +1,36 @@
package cn.lili.modules.lmk.domain.vo;
import cn.lili.base.AbsVo;
import cn.lili.modules.lmk.domain.entity.VideoTag;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import org.springframework.lang.NonNull;
/**
 * 视频标签展示
 *
 * @author xp
 * @since 2025-05-13
 */
@Data
@ApiModel(value = "视频标签响应数据", description = "视频标签响应数据")
public class WxVideoTagVO  {
    private String id;
    /** 标签名称 */
    @ApiModelProperty("标签名称")
    private String tagName;
    public static WxVideoTagVO getVoByEntity(@NonNull VideoTag entity, WxVideoTagVO vo) {
        if(vo == null) {
            vo = new WxVideoTagVO();
        }
        BeanUtils.copyProperties(entity, vo);
        return vo;
    }
}
framework/src/main/java/cn/lili/modules/lmk/enums/general/VideoSupportOpEnum.java
@@ -17,7 +17,7 @@
@Getter
public enum VideoSupportOpEnum {
    UP("UP", "发布"),
//    UP("UP", "发布"),
    DOWN("DOWN", "下架"),
    DELETE("DELETE", "删除"),
    EDIT("EDIT", "编辑"),
@@ -43,7 +43,7 @@
        if (VideoStatusEnum.AUDITING.getValue().equals(status)) {
            return Arrays.asList(new VideoOption(EDIT.value, EDIT.desc), new VideoOption(DELETE.value, DELETE.desc));
        } else if (VideoStatusEnum.DISABLE.getValue().equals(status)) {
            return Arrays.asList(new VideoOption(EDIT.value, EDIT.desc), new VideoOption(UP.value, UP.desc), new VideoOption(DELETE.value, DELETE.desc));
            return Arrays.asList(new VideoOption(EDIT.value, EDIT.desc), new VideoOption(DELETE.value, DELETE.desc));
        } else if (VideoStatusEnum.PUBLISHED.getValue().equals(status)) {
            return Arrays.asList(new VideoOption(EDIT.value, EDIT.desc), new VideoOption(DOWN.value, DOWN.desc), new VideoOption(DELETE.value, DELETE.desc));
        } else if (VideoStatusEnum.REJECT.getValue().equals(status)) {
framework/src/main/java/cn/lili/modules/lmk/service/VideoService.java
@@ -237,4 +237,20 @@
     * @return
     */
    Result getGoodsDetail(String videoId);
    /**
     * 用户下架视频
     *
     * @param id
     * @return
     */
    Result buyerDownVideo(String id);
    /**
     * 修改视频
     *
     * @param form
     * @return
     */
    Result updatePublish(WxVideoForm form);
}
framework/src/main/java/cn/lili/modules/lmk/service/impl/VideoServiceImpl.java
@@ -206,6 +206,68 @@
        return Result.ok("发布成功,视频审核中~");
    }
    @Override
    public Result updatePublish(WxVideoForm form) {
        Video video = baseMapper.selectById(form.getId());
        if (Objects.isNull(video)) {
            return Result.error("修改视频不存在");
        }
        // 1.修改视频
        WxVideoForm.getEntityByForm(form, video);
        video.setAuthorId(UserContext.getCurrentUserId());
        video.setStatus(VideoStatusEnum.AUDITING.getValue());
        video.setCoverUrl(form.getCover());
        video.setVideoType(VideoTypeEnum.VIDEO.getValue());
        if (VideoContentTypeEnum.IMG.getValue().equals(form.getVideoContentType())) {
            video.setVideoImgs(JSON.toJSONString(form.getVideoImgs()));
        }
        baseMapper.updateById(video);
        // 2.处理标签---删除之前的视频标签关系,再新增
        new LambdaUpdateChainWrapper<>(videoTagRefService.getBaseMapper())
                .eq(VideoTagRef::getVideoId, video.getId())
                .remove();
        List<VideoTagRef> videoTagRefs = form.getTags().stream().map(tag -> {
            VideoTagRef videoTagRef = new VideoTagRef();
            videoTagRef.setVideoId(video.getId());
            if (StringUtils.isBlank(tag.getId())) {
                VideoTag videoTag = new LambdaQueryChainWrapper<>(videoTagService.getBaseMapper())
                        .eq(VideoTag::getTagName, tag.getTagName())
                        .one();
                if (Objects.nonNull(videoTag)) {
                    videoTagRef.setVideoTagId(videoTag.getId());
                } else {
                    videoTag = new VideoTag();
                    videoTag.setTagName(tag.getTagName());
                    videoTag.setCreateType(TagCreateTypeEnum.USER.getValue());
                    videoTagService.save(videoTag);
                    videoTagRef.setVideoTagId(videoTag.getId());
                }
            } else {
                videoTagRef.setVideoTagId(tag.getId());
            }
            return videoTagRef;
        }).collect(Collectors.toList());
        videoTagRefService.saveBatch(videoTagRefs);
        // 3. 保存视频文件信息
        lmkFileService.addByForm(form.getFileInfo());
        // 4. 处理选择的商品,先删除之前的再新增
        new LambdaUpdateChainWrapper<>(videoGoodsService.getBaseMapper())
                .eq(VideoGoods::getVideoId, video.getId())
                .remove();
        if (CollectionUtils.isNotEmpty(form.getGoodsList())) {
            List<VideoGoods> videoGoods = new ArrayList<>(2);
            for (int i = 0; i < form.getGoodsList().size(); i++) {
                VideoGoods e = new VideoGoods();
                e.setVideoId(video.getId());
                e.setGoodsId(form.getGoodsList().get(i).getGoodsId());
                e.setGoodsNum(form.getGoodsList().get(i).getGoodsNum());
                e.setOrderNum(i);
                videoGoods.add(e);
            }
            videoGoodsService.saveBatch(videoGoods);
        }
        return Result.ok("发布成功,视频审核中~");
    }
    @Override
    public Result managerPage(ManagerVideoQuery query) {
@@ -283,6 +345,15 @@
    }
    @Override
    public Result buyerDownVideo(String id) {
        new LambdaUpdateChainWrapper<>(baseMapper)
                .eq(Video::getId, id)
                .set(Video::getStatus, VideoStatusEnum.DISABLE.getValue())
                .update();
        return Result.ok("下架成功");
    }
    @Override
    public Result recommendVideo(VideoQuery query) {
        // 推荐算法: 1. 根据用户的收藏视频的标签  2. 根据用户关注的作者的其它视频  3. 根据用户的观看记录(观看时长较长的、重复观看次数较多的) 4. 基于相似用户的观看行为来给该用户推荐
        IPage<WxVideoVO> page = PageUtil.getPage(query, WxVideoVO.class);
@@ -317,12 +388,12 @@
                v.setTagList(tagMap.get(v.getId()));
                v.setCollected(CollectionUtils.isNotEmpty(collectMap.get(v.getId())));
                if (VideoContentTypeEnum.VIDEO.getValue().equals(v.getVideoContentType())) {
                                    v.setVideoUrl(cosUtil.getPreviewUrl(v.getVideoFileKey()));
//                    v.setVideoUrl("https://videos.pexels.com/video-files/13602965/13602965-hd_1920_1080_30fps.mp4");
                    v.setVideoUrl(cosUtil.getPreviewUrl(v.getVideoFileKey()));
                    v.setCoverUrl(cosUtil.getPreviewUrl(v.getCoverFileKey()));
                } else if (VideoContentTypeEnum.IMG.getValue().equals(v.getVideoContentType()) && StringUtils.isNotBlank(v.getVideoImgs())) {
                    v.setImgs(JSON.parseArray(v.getVideoImgs(), String.class).stream().map(fileKey -> cosUtil.getPreviewUrl(fileKey)).collect(Collectors.toList()));
                }
                v.setCoverUrl(cosUtil.getPreviewUrl(v.getCoverFileKey()));
                v.setSubscribeThisAuthor(subscribes.contains(v.getAuthorId()));
            });
        }
@@ -338,11 +409,10 @@
            page.getRecords().forEach(v -> {
                if (VideoContentTypeEnum.VIDEO.getValue().equals(v.getVideoContentType())) {
                    v.setVideoUrl(cosUtil.getPreviewUrl(v.getVideoFileKey()));
//                    v.setVideoUrl("https://videos.pexels.com/video-files/13602965/13602965-hd_1920_1080_30fps.mp4");
                    v.setCoverUrl(cosUtil.getPreviewUrl(v.getCoverFileKey()));
                } else if (VideoContentTypeEnum.IMG.getValue().equals(v.getVideoContentType()) && StringUtils.isNotBlank(v.getVideoImgs())) {
                    v.setImgs(JSON.parseArray(v.getVideoImgs(), String.class).stream().map(cosUtil::getPreviewUrl).collect(Collectors.toList()));
                }
                v.setCoverUrl(cosUtil.getPreviewUrl(v.getCoverFileKey()));
            });
        }
        return Result.ok().data(page.getRecords());
@@ -400,9 +470,14 @@
        query.setAuthorSelf(UserContext.getCurrentUserId().equals(query.getAuthorId()));
        baseMapper.getAuthorVideoPage(page, query);
        for (WxVideoVO vo : page.getRecords()) {
            vo.setCoverUrl(cosUtil.getPreviewUrl(vo.getCoverFileKey()));
//            vo.setVideoUrl(cosUtil.getPreviewUrl(vo.getVideoFileKey()));
            vo.setVideoUrl("https://videos.pexels.com/video-files/13602965/13602965-hd_1920_1080_30fps.mp4");
            if (VideoContentTypeEnum.VIDEO.getValue().equals(vo.getVideoContentType())) {
                vo.setVideoUrl(cosUtil.getPreviewUrl(vo.getVideoFileKey()));
                vo.setCoverUrl(cosUtil.getPreviewUrl(vo.getCoverFileKey()));
            } else if (VideoContentTypeEnum.IMG.getValue().equals(vo.getVideoContentType()) && StringUtils.isNotBlank(vo.getVideoImgs())) {
                vo.setImgs(JSON.parseArray(vo.getVideoImgs(), String.class).stream().map(fileKey -> cosUtil.getPreviewUrl(fileKey)).collect(Collectors.toList()));
            }
            vo.setOptions(VideoSupportOpEnum.getVideoOpByStatus(vo.getStatus()));
        }
        return Result.ok().data(page.getRecords()).total(page.getTotal());
@@ -413,9 +488,12 @@
        IPage<WxVideoVO> page = PageUtil.getPage(query, WxVideoVO.class);
        baseMapper.getAuthorCollectVideoPage(page, query);
        for (WxVideoVO vo : page.getRecords()) {
            vo.setCoverUrl(cosUtil.getPreviewUrl(vo.getCoverFileKey()));
//            vo.setVideoUrl(cosUtil.getPreviewUrl(vo.getVideoFileKey()));
            vo.setVideoUrl("https://videos.pexels.com/video-files/13602965/13602965-hd_1920_1080_30fps.mp4");
            if (VideoContentTypeEnum.VIDEO.getValue().equals(vo.getVideoContentType())) {
                vo.setVideoUrl(cosUtil.getPreviewUrl(vo.getVideoFileKey()));
                vo.setCoverUrl(cosUtil.getPreviewUrl(vo.getCoverFileKey()));
            } else if (VideoContentTypeEnum.IMG.getValue().equals(vo.getVideoContentType()) && StringUtils.isNotBlank(vo.getVideoImgs())) {
                vo.setImgs(JSON.parseArray(vo.getVideoImgs(), String.class).stream().map(fileKey -> cosUtil.getPreviewUrl(fileKey)).collect(Collectors.toList()));
            }
            vo.setCollected(Boolean.TRUE);
        }
        return Result.ok().data(page.getRecords()).total(page.getTotal());
@@ -448,9 +526,12 @@
        if (Objects.isNull(vo)) {
            return Result.error("视频不存在");
        }
        vo.setCoverUrl(cosUtil.getPreviewUrl(vo.getCoverFileKey()));
//        vo.setVideoUrl(cosUtil.getPreviewUrl(vo.getVideoFileKey()));
        vo.setVideoUrl("https://videos.pexels.com/video-files/13602965/13602965-hd_1920_1080_30fps.mp4");
        if (VideoContentTypeEnum.VIDEO.getValue().equals(vo.getVideoContentType())) {
            vo.setVideoUrl(cosUtil.getPreviewUrl(vo.getVideoFileKey()));
            vo.setCoverUrl(cosUtil.getPreviewUrl(vo.getCoverFileKey()));
        } else if (VideoContentTypeEnum.IMG.getValue().equals(vo.getVideoContentType()) && StringUtils.isNotBlank(vo.getVideoImgs())) {
            vo.setImgs(JSON.parseArray(vo.getVideoImgs(), String.class).stream().map(fileKey -> cosUtil.getPreviewUrl(fileKey)).collect(Collectors.toList()));
        }
        List<WxVideoTagForm> tags = videoTagRefService.getTagsByVideoIds(Arrays.asList(vo.getId()))
                .stream()
                .map(i -> {
framework/src/main/java/cn/lili/modules/lmk/service/impl/VideoTagServiceImpl.java
@@ -2,6 +2,7 @@
import cn.lili.modules.lmk.domain.query.WxVideoTagQuery;
import cn.lili.modules.lmk.domain.vo.SimpleVideoTagVO;
import cn.lili.modules.lmk.domain.vo.WxVideoTagVO;
import cn.lili.modules.lmk.enums.general.TagCreateTypeEnum;
import com.baomidou.mybatisplus.core.metadata.IPage;
import cn.lili.modules.lmk.domain.entity.VideoTag;
@@ -139,7 +140,7 @@
    @Override
    public Result recommend(WxVideoTagQuery query) {
        List<VideoTagVO> tags = new ArrayList<>(3);
        List<WxVideoTagVO> tags = new ArrayList<>(3);
        switch (query.getSearchType()) {
            case "HOT":
                // TODO 热门标签通过定时任务统计表lmk_video_tag_ref数量到lmk_video_tag中
@@ -147,7 +148,7 @@
                        .orderByDesc(VideoTag::getUseNum)
                        .last("limit 3")
                        .list().stream().map(entity -> {
                            return VideoTagVO.getVoByEntity(entity, null);
                            return WxVideoTagVO.getVoByEntity(entity, null);
                        }).collect(Collectors.toList());
            case "SEARCH":
                tags = new LambdaQueryChainWrapper<>(baseMapper)
@@ -155,7 +156,7 @@
                        .like(VideoTag::getTagName, query.getTagName())
                        .last("limit 3")
                        .list().stream().map(entity -> {
                            return VideoTagVO.getVoByEntity(entity, null);
                            return WxVideoTagVO.getVoByEntity(entity, null);
                        }).collect(Collectors.toList());
        }
        return Result.ok().data(tags);
framework/src/main/resources/mapper/lmk/VideoMapper.xml
@@ -404,28 +404,19 @@
        <result column="video_fit" property="videoFit" />
        <result column="title" property="title" />
        <result column="video_duration" property="videoDuration" />
        <result column="video_imgs" property="videoImgs" />
        <result column="video_content_type" property="videoContentType" />
        <collection property="goodsList" column="id" select="getVideoGoods" ofType="cn.lili.modules.lmk.domain.vo.VideoGoodsDetailVO"/>
    </resultMap>
    <select id="wxDetail" resultMap="WxEditResultMap">
        SELECT
            LV.author_id,
            LV.cover_url,
            LV.video_fit,
            LV.video_duration,
            LV.video_file_key,
            LV.title,
            LV.goods_view_num,
            LV.goods_order_num,
            LV.recommend,
            LV.status,
            LV.play_num,
            LV.comment_num,
            LV.collect_num,
            LV.weight,
            LV.audit_pass_time,
            LV.update_time,
            LV.video_content_type,
            LV.video_type,
            LV.video_imgs,
            LV.id
        FROM