diff --git a/fruitshorts-module-media/src/main/java/com/fruitshorts/media/dal/mapper/MediaRenditionMapper.java b/fruitshorts-module-media/src/main/java/com/fruitshorts/media/dal/mapper/MediaRenditionMapper.java index 92e7eab..4d2150c 100644 --- a/fruitshorts-module-media/src/main/java/com/fruitshorts/media/dal/mapper/MediaRenditionMapper.java +++ b/fruitshorts-module-media/src/main/java/com/fruitshorts/media/dal/mapper/MediaRenditionMapper.java @@ -4,6 +4,17 @@ package com.fruitshorts.media.dal.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.fruitshorts.media.dal.entity.MediaRendition; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Param; public interface MediaRenditionMapper extends BaseMapper { + + /** + * 物理删除旧产物。唯一索引 uk_rendition(media_asset_id, quality, format) 不含 deleted, + * 逻辑删除的旧行会继续占着唯一键,重转时插入必然冲突,所以这里必须绕过 @TableLogic 真删。 + */ + @Delete("") + int deletePhysically(@Param("mediaAssetId") Long mediaAssetId, @Param("episodeId") Long episodeId); } diff --git a/fruitshorts-module-media/src/main/java/com/fruitshorts/media/service/TranscodeService.java b/fruitshorts-module-media/src/main/java/com/fruitshorts/media/service/TranscodeService.java index 1dac43c..defaf62 100644 --- a/fruitshorts-module-media/src/main/java/com/fruitshorts/media/service/TranscodeService.java +++ b/fruitshorts-module-media/src/main/java/com/fruitshorts/media/service/TranscodeService.java @@ -217,15 +217,8 @@ public class TranscodeService { public void succeed(Long taskId, List renditions, MediaThumbnail thumbnail) { TranscodeTask task = getExisting(taskId); - var renditionDelete = Wrappers.lambdaQuery(); - if (task.getEpisodeId() != null && task.getEpisodeId() > 0) { - renditionDelete.and(wrapper -> wrapper - .eq(MediaRendition::getMediaAssetId, task.getMediaAssetId()) - .or().eq(MediaRendition::getEpisodeId, task.getEpisodeId())); - } else { - renditionDelete.eq(MediaRendition::getMediaAssetId, task.getMediaAssetId()); - } - mediaRenditionMapper.delete(renditionDelete); + // 唯一索引不含 deleted,旧产物必须物理删除,否则重转时插入会撞 uk_rendition + mediaRenditionMapper.deletePhysically(task.getMediaAssetId(), task.getEpisodeId()); for (MediaRendition rendition : renditions) { rendition.setMediaAssetId(task.getMediaAssetId()); rendition.setDramaId(task.getDramaId());