package cn.lili.modules.lmk.service.impl; import cn.lili.cache.Cache; import cn.lili.cache.CachePrefix; import cn.lili.common.properties.RocketmqCustomProperties; import cn.lili.common.security.context.UserContext; import cn.lili.common.utils.CommonUtil; import cn.lili.elasticsearch.EsSuffix; import cn.lili.modules.lmk.constant.RedisKeyExpireConstant; import cn.lili.modules.lmk.domain.dto.VideoEsUpdateDTO; import cn.lili.modules.lmk.domain.entity.*; import cn.lili.modules.lmk.domain.es.VideoIndex; import cn.lili.modules.lmk.domain.form.*; import cn.lili.modules.lmk.domain.query.*; import cn.lili.modules.lmk.domain.vo.*; import cn.lili.modules.lmk.enums.general.*; import cn.lili.modules.lmk.service.*; import cn.lili.modules.member.entity.dos.FootPrint; import cn.lili.modules.member.entity.dos.Member; import cn.lili.modules.member.service.FootprintService; import cn.lili.modules.member.service.MemberService; import cn.lili.modules.search.entity.dos.EsGoodsIndex; import cn.lili.rocketmq.RocketmqSendCallbackBuilder; import cn.lili.rocketmq.tags.CommentTagsEnum; import cn.lili.rocketmq.tags.VideoTagsEnum; import cn.lili.utils.COSUtil; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.metadata.IPage; import cn.lili.modules.lmk.mapper.VideoMapper; import cn.lili.base.Result; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.ListUtils; import org.apache.commons.lang3.StringUtils; import org.apache.lucene.search.join.ScoreMode; import org.apache.rocketmq.spring.core.RocketMQTemplate; import org.elasticsearch.index.query.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; import cn.lili.utils.PageUtil; import org.springframework.beans.BeanUtils; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; /** * 视频内容 服务实现类 * * @author xp * @since 2025-05-16 */ @Service @RequiredArgsConstructor public class VideoServiceImpl extends ServiceImpl implements VideoService { private final VideoMapper videoMapper; private final VideoTagService videoTagService; private final VideoTagRefService videoTagRefService; private final LmkFileService lmkFileService; private final VideoAuditRecordService videoAuditRecordService; private final MyCollectService myCollectService; private final COSUtil cosUtil; private final FootprintService footprintService; private final MySubscribeService mySubscribeService; private final MemberService memberService; private final VideoAccountService videoAccountService; private final KitchenVideoTypeRefService kitchenVideoTypeRefService; private final VideoGoodsService videoGoodsService; private final KitchenTypeService kitchenTypeService; private final Cache cache; private final RocketmqCustomProperties rocketmqCustomProperties; private final RocketMQTemplate rocketMQTemplate; private final ThumbsUpRecordService thumbsUpRecordService; private final ElasticsearchOperations restTemplate; @Qualifier("videoEsServiceImpl") private final EsService esService; /** * 批量删除 * @param ids * @return */ @Override public Result remove(List ids) { baseMapper.deleteBatchIds(ids); return Result.ok("删除成功"); } /** * id删除 * @param id * @return */ @Override @Transactional(rollbackFor = Exception.class) public Result removeById(String id) { baseMapper.deleteById(id); new LambdaUpdateChainWrapper<>(videoGoodsService.getBaseMapper()) .eq(VideoGoods::getVideoId, id) .remove(); new LambdaUpdateChainWrapper<>(videoTagRefService.getBaseMapper()) .eq(VideoTagRef::getVideoId, id) .remove(); // mq异步删除es数据 String destination = rocketmqCustomProperties.getVideoTopic() + ":" + VideoTagsEnum.ES_DOC_DEL.name(); rocketMQTemplate.asyncSend(destination, id, RocketmqSendCallbackBuilder.commonCallback()); return Result.ok("删除成功"); } /** * 分页查询 * @param query * @return */ @Override public Result page(VideoQuery query) { IPage page = PageUtil.getPage(query, VideoVO.class); baseMapper.getPage(page, query); return Result.ok().data(page.getRecords()).total(page.getTotal()); } /** * 根据id查找 * @param id * @return */ @Override public Result detail(String id) { VideoVO vo = baseMapper.getById(id); Assert.notNull(vo, "记录不存在"); List tags = videoTagRefService.getTagsByVideoIds(Arrays.asList(id)); vo.setTagList(tags); if (VideoContentTypeEnum.VIDEO.getValue().equals(vo.getVideoContentType())) { vo.setVideoUrl(cosUtil.getPreviewUrl(vo.getVideoFileKey())); } 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())); } if (CollectionUtils.isNotEmpty(vo.getGoodsList())) { vo.getGoodsList().stream().forEach(goods -> { goods.setThumbnail(cosUtil.getPreviewUrl(goods.getThumbnail())); }); } return Result.ok().data(vo); } /** * 列表 * @return */ @Override public Result all() { List