buyer-api/src/main/java/cn/lili/controller/lmk/VideoController.java
@@ -1,21 +1,22 @@ package cn.lili.controller.lmk; import cn.lili.group.Update; import cn.lili.base.Result; import cn.lili.group.Add; import cn.lili.group.Update; import cn.lili.modules.lmk.domain.form.ThumbsUpRecordForm; import cn.lili.modules.lmk.domain.form.VideoFootPrintForm; import cn.lili.modules.lmk.domain.form.VideoHomePageInfoForm; import cn.lili.modules.lmk.domain.form.WxVideoForm; import cn.lili.modules.lmk.domain.query.*; import org.springframework.validation.annotation.Validated; import lombok.RequiredArgsConstructor; import java.util.List; import javax.validation.constraints.NotEmpty; import cn.lili.modules.lmk.service.VideoService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import cn.lili.modules.lmk.service.VideoService; import cn.lili.base.Result; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.validation.constraints.NotEmpty; import java.util.List; /** * 视频内容 前端控制器 @@ -154,4 +155,10 @@ public Result goodsSimilarly(@RequestBody VideoQuery query) { return videoService.recommendVideo(query); } @GetMapping("/history") @ApiOperation(value = "获取历史播放记录") public Result getHistoryPage(VideoHistoryQuery query) { return videoService.getHistoryPage(query); } } buyer-api/src/main/java/cn/lili/controller/member/FootprintController.java
@@ -1,5 +1,6 @@ package cn.lili.controller.member; import cn.lili.base.Result; import cn.lili.common.enums.ResultUtil; import cn.lili.common.security.context.UserContext; import cn.lili.common.utils.StringUtils; @@ -40,6 +41,7 @@ @Autowired private COSUtil cosUtil; @ApiOperation(value = "分页获取") @GetMapping public ResultMessage<IPage<EsGoodsIndex>> getByPage(FootPrintQueryParams params) { framework/src/main/java/cn/lili/modules/lmk/domain/query/VideoHistoryQuery.java
New file @@ -0,0 +1,18 @@ package cn.lili.modules.lmk.domain.query; import cn.lili.base.AbsQuery; import lombok.Data; /** * 视频标签查询 * * @author xp * @since 2025-05-13 */ @Data public class VideoHistoryQuery extends AbsQuery { private String userId; } framework/src/main/java/cn/lili/modules/lmk/domain/vo/VideoHistoryVO.java
New file @@ -0,0 +1,26 @@ package cn.lili.modules.lmk.domain.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.Date; /** * @author:xp * @date:2025/7/4 17:43 */ @Data @ApiModel("视频播放记录") public class VideoHistoryVO extends WxVideoVO { @ApiModelProperty("历史记录id") private String historyId; @ApiModelProperty("播放至") private String playAt; @ApiModelProperty("观看日期") private Date playTime; } framework/src/main/java/cn/lili/modules/lmk/mapper/VideoMapper.java
@@ -163,4 +163,13 @@ * @param goodsSimilarlyQuery */ IPage goodsSimilarlyPage(IPage page, @Param("query") GoodsSimilarlyQuery goodsSimilarlyQuery); /** * 获取播放记录 * * @param page * @param query * @return */ IPage getHistoryPage(IPage page, @Param("query") VideoHistoryQuery query); } framework/src/main/java/cn/lili/modules/lmk/service/VideoService.java
@@ -298,4 +298,11 @@ */ Result esSearch(VideoEsQuery query); /** * 获取播放记录 * * @param query * @return */ Result getHistoryPage(VideoHistoryQuery query); } framework/src/main/java/cn/lili/modules/lmk/service/impl/VideoServiceImpl.java
@@ -525,6 +525,7 @@ v.setCommentNum(this.getCommentNum(v.getId(), v.getCommentNum())); v.setCollectNum(this.getCollectNum(v.getId(), v.getCollectNum())); v.setThumbsUpNum(this.getThumbsUpNum(v.getId(), v.getThumbsUpNum())); v.setAuthorAvatar(cosUtil.getPreviewUrl(v.getAuthorAvatar())); if (VideoContentTypeEnum.VIDEO.getValue().equals(v.getVideoContentType())) { v.setVideoUrl(cosUtil.getPreviewUrl(v.getVideoFileKey())); v.setCoverUrl(cosUtil.getPreviewUrl(v.getCoverFileKey())); @@ -597,9 +598,10 @@ public Result healthRecommendVideo(WxHealthVideoQuery query) { IPage<WxVideoVO> page = PageUtil.getPage(query, WxVideoVO.class); //获取大健康视频列表 baseMapper.recommendHealthVideo(page,query); baseMapper.recommendHealthVideo(page,query); if (page.getTotal() > 0) { page.getRecords().forEach(v -> { v.setAuthorAvatar(cosUtil.getPreviewUrl(v.getAuthorAvatar())); if (VideoContentTypeEnum.VIDEO.getValue().equals(v.getVideoContentType())) { v.setVideoUrl(cosUtil.getPreviewUrl(v.getVideoFileKey())); v.setCoverUrl(cosUtil.getPreviewUrl(v.getCoverFileKey())); @@ -622,6 +624,7 @@ IPage<WxVideoVO> page = PageUtil.getPage(query, WxVideoVO.class); baseMapper.wxKitchenVideoQuery(page, query); page.getRecords().forEach(v -> { v.setAuthorAvatar(cosUtil.getPreviewUrl(v.getAuthorAvatar())); if (VideoContentTypeEnum.VIDEO.getValue().equals(v.getVideoContentType())) { v.setVideoUrl(cosUtil.getPreviewUrl(v.getVideoFileKey())); v.setCoverUrl(cosUtil.getPreviewUrl(v.getCoverFileKey())); @@ -672,13 +675,24 @@ @Override public Result saveViewRecord(VideoFootPrintForm form) { FootPrint footPrint = new FootPrint(); footPrint.setViewType(ViewTypeEnum.VIDEO.getValue()); footPrint.setRefId(form.getVideoId()); footPrint.setMemberId(UserContext.getCurrentUserId()); footPrint.setViewDuration(form.getViewDuration()); footPrint.setPlayAt(form.getPlayAt()); footprintService.saveFootprint(footPrint); FootPrint one = new LambdaQueryChainWrapper<>(footprintService.getBaseMapper()) .eq(FootPrint::getRefId, form.getVideoId()) .eq(FootPrint::getMemberId, UserContext.getCurrentUserId()) .eq(FootPrint::getViewType, ViewTypeEnum.VIDEO.getValue()) .one(); if (Objects.nonNull(one)) { one.setViewDuration(one.getViewDuration() + form.getViewDuration()); one.setPlayAt(form.getPlayAt()); footprintService.updateById(one); } else { FootPrint footPrint = new FootPrint(); footPrint.setViewType(ViewTypeEnum.VIDEO.getValue()); footPrint.setRefId(form.getVideoId()); footPrint.setMemberId(UserContext.getCurrentUserId()); footPrint.setViewDuration(form.getViewDuration()); footPrint.setPlayAt(form.getPlayAt()); footprintService.saveFootprint(footPrint); } return Result.ok(); } @@ -720,6 +734,7 @@ v.setCommentNum(this.getCommentNum(v.getId(), v.getCommentNum())); v.setCollectNum(this.getCollectNum(v.getId(), v.getCollectNum())); v.setThumbsUpNum(this.getThumbsUpNum(v.getId(), v.getThumbsUpNum())); v.setAuthorAvatar(cosUtil.getPreviewUrl(v.getAuthorAvatar())); if (VideoContentTypeEnum.VIDEO.getValue().equals(v.getVideoContentType())) { v.setVideoUrl(cosUtil.getPreviewUrl(v.getVideoFileKey())); v.setCoverUrl(cosUtil.getPreviewUrl(v.getCoverFileKey())); @@ -758,6 +773,7 @@ v.setCommentNum(this.getCommentNum(v.getId(), v.getCommentNum())); v.setCollectNum(this.getCollectNum(v.getId(), v.getCollectNum())); v.setThumbsUpNum(this.getThumbsUpNum(v.getId(), v.getThumbsUpNum())); v.setAuthorAvatar(cosUtil.getPreviewUrl(v.getAuthorAvatar())); if (VideoContentTypeEnum.VIDEO.getValue().equals(v.getVideoContentType())) { v.setVideoUrl(cosUtil.getPreviewUrl(v.getVideoFileKey())); v.setCoverUrl(cosUtil.getPreviewUrl(v.getCoverFileKey())); @@ -795,6 +811,7 @@ v.setCommentNum(this.getCommentNum(v.getId(), v.getCommentNum())); v.setCollectNum(this.getCollectNum(v.getId(), v.getCollectNum())); v.setThumbsUpNum(this.getThumbsUpNum(v.getId(), v.getThumbsUpNum())); v.setAuthorAvatar(cosUtil.getPreviewUrl(v.getAuthorAvatar())); if (VideoContentTypeEnum.VIDEO.getValue().equals(v.getVideoContentType())) { v.setVideoUrl(cosUtil.getPreviewUrl(v.getVideoFileKey())); v.setCoverUrl(cosUtil.getPreviewUrl(v.getCoverFileKey())); @@ -1199,6 +1216,7 @@ // 判断是否关注作者、是否点赞、是否收藏 wxVideoVO.setCollected(CollectionUtils.isNotEmpty(collectMap.get(wxVideoVO.getId()))); wxVideoVO.setThumbsUp(CollectionUtils.isNotEmpty(thumbsUpMap.get(wxVideoVO.getId()))); wxVideoVO.setAuthorAvatar(cosUtil.getPreviewUrl(wxVideoVO.getAuthorAvatar())); if (UserContext.getCurrentUserId().equals(wxVideoVO.getAuthorId())) { wxVideoVO.setSubscribeThisAuthor(Boolean.TRUE); } else { @@ -1216,4 +1234,48 @@ return Result.ok().data(vos).total(searchHits.getTotalHits()); } @Override public Result getHistoryPage(VideoHistoryQuery query) { query.setUserId(UserContext.getCurrentUserId()); IPage<VideoHistoryVO> page = PageUtil.getPage(query, VideoHistoryVO.class); baseMapper.getHistoryPage(page, query); if (CollectionUtils.isNotEmpty(page.getRecords())) { if (page.getTotal() > 0) { List<String> videoIds = page.getRecords().stream().map(VideoHistoryVO::getId).collect(Collectors.toList()); Map<String, List<SimpleVideoTagVO>> tagMap = videoTagRefService.getTagsByVideoIds(videoIds) .stream() .collect(Collectors.groupingBy(SimpleVideoTagVO::getVideoId)); Map<String, List<SimpleMyCollectVO>> collectMap = myCollectService.getCollectsByVideoIds(videoIds) .stream() .collect(Collectors.groupingBy(SimpleMyCollectVO::getRefId)); Map<String, List<SimpleMyThumbsUpVO>> thumbsUpMap = thumbsUpRecordService.getThumbssByVideoIds(videoIds) .stream() .collect(Collectors.groupingBy(SimpleMyThumbsUpVO::getRefId)); List<String> subscribes = mySubscribeService.getSubscribesByUserId(UserContext.getCurrentUserId()); // 3. 获取视频临时访问地址、设置视频标签、我是否收藏、是否点赞、作者是否关注 page.getRecords().forEach(v -> { v.setTagList(tagMap.get(v.getId())); v.setCollected(CollectionUtils.isNotEmpty(collectMap.get(v.getId()))); v.setThumbsUp(CollectionUtils.isNotEmpty(thumbsUpMap.get(v.getId()))); v.setCommentNum(this.getCommentNum(v.getId(), v.getCommentNum())); v.setCollectNum(this.getCollectNum(v.getId(), v.getCollectNum())); v.setThumbsUpNum(this.getThumbsUpNum(v.getId(), v.getThumbsUpNum())); v.setAuthorAvatar(cosUtil.getPreviewUrl(v.getAuthorAvatar())); if (VideoContentTypeEnum.VIDEO.getValue().equals(v.getVideoContentType())) { 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())); } if (CollectionUtils.isNotEmpty(v.getGoodsList())) { v.getGoodsList().stream().forEach(goods -> { goods.setThumbnail(cosUtil.getPreviewUrl(goods.getThumbnail())); }); } v.setSubscribeThisAuthor(subscribes.contains(v.getAuthorId())); }); } } return Result.ok().data(page.getRecords()).total(page.getTotal()); } } framework/src/main/java/cn/lili/modules/member/service/FootprintService.java
@@ -1,5 +1,6 @@ package cn.lili.modules.member.service; import cn.lili.base.Result; import cn.lili.common.vo.PageVO; import cn.lili.modules.member.entity.dos.FootPrint; import cn.lili.modules.member.entity.dto.FootPrintQueryParams; @@ -55,4 +56,4 @@ */ long getFootprintNum(); } } framework/src/main/java/cn/lili/modules/member/serviceimpl/FootprintServiceImpl.java
@@ -1,5 +1,6 @@ package cn.lili.modules.member.serviceimpl; import cn.lili.base.Result; import cn.lili.common.security.context.UserContext; import cn.lili.modules.goods.entity.dos.GoodsSku; import cn.lili.modules.goods.service.GoodsSkuService; @@ -98,4 +99,5 @@ lambdaQueryWrapper.eq(FootPrint::getDeleteFlag, false); return this.count(lambdaQueryWrapper); } } framework/src/main/resources/mapper/lmk/VideoMapper.xml
@@ -101,6 +101,29 @@ <collection property="goodsList" column="id" select="getVideoGoods" ofType="cn.lili.modules.lmk.domain.vo.VideoGoodsDetailVO"/> </resultMap> <!-- 播放历史 --> <resultMap id="HistoryMap" type="cn.lili.modules.lmk.domain.vo.VideoHistoryVO"> <id column="id" property="id"/> <result column="author_id" property="authorId" /> <result column="authorName" property="authorName" /> <result column="authorAvatar" property="authorAvatar" /> <result column="cover_url" property="coverFileKey" /> <result column="video_file_key" property="videoFileKey" /> <result column="video_fit" property="videoFit" /> <result column="video_duration" property="videoDuration" /> <result column="title" property="title" /> <result column="collect_num" property="collectNum" /> <result column="comment_num" property="commentNum" /> <result column="thumbs_up_num" property="thumbsUpNum" /> <result column="status" property="status" /> <result column="video_content_type" property="videoContentType" /> <result column="video_type" property="videoType" /> <result column="video_imgs" property="videoImgs" /> <result column="historyId" property="historyId" /> <result column="play_at" property="playAt" /> <result column="playTime" property="playTime" /> <collection property="goodsList" column="id" select="getVideoGoods" ofType="cn.lili.modules.lmk.domain.vo.VideoGoodsDetailVO"/> </resultMap> <select id="getById" resultMap="BaseResultMap"> SELECT @@ -288,6 +311,53 @@ LV.create_time DESC </select> <select id="getHistoryPage" resultMap="HistoryMap"> 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.thumbs_up_num, LV.weight, LV.audit_pass_time, LV.update_time, LV.create_time, LV.video_content_type, LV.video_type, LV.video_imgs, LV.id, CASE WHEN LM.nick_name IS NOT NULL THEN LM.nick_name WHEN LM.nick_name IS NULL THEN (SELECT nick_name FROM li_admin_user WHERE id = LV.author_id) ELSE '' END as authorName, CASE WHEN LM.face IS NOT NULL THEN LM.face WHEN LM.face IS NULL THEN (SELECT avatar FROM li_admin_user WHERE id = LV.author_id) ELSE '' END as authorAvatar, LFP.id as historyId, LFP.play_at, LFP.update_time as playTime FROM lmk_video LV INNER JOIN li_foot_print LFP ON LFP.ref_id = LV.id AND LFP.view_type = 'video' AND LFP.delete_flag = 0 AND LFP.member_id = #{query.userId} LEFT JOIN li_member LM ON LV.author_id = LM.id WHERE LV.delete_flag = 0 AND LV.status = '1' ORDER BY LFP.update_time DESC </select> <select id="recommendHealthVideo" resultMap="WxResultMap"> SELECT LV.author_id,