diff --git a/src/main/java/com/aida/seller/module/listing/controller/ListingController.java b/src/main/java/com/aida/seller/module/listing/controller/ListingController.java index a5d4df9..a96609c 100644 --- a/src/main/java/com/aida/seller/module/listing/controller/ListingController.java +++ b/src/main/java/com/aida/seller/module/listing/controller/ListingController.java @@ -94,4 +94,11 @@ public class ListingController { IPage page = listingService.getShopListings(sellerId, designFor, pageNum, pageSize); return Response.success(PageResponse.success(page)); } + + @Operation(summary = "迁移旧商品水印数据", description = "为所有已发布商品中缺失水印记录的图片生成水印并写入数据库,返回处理数量") + @PostMapping("/migrate/watermarks") + public Response migrateWatermarks() { + int count = listingService.migrateWatermarks(); + return Response.success(count); + } } diff --git a/src/main/java/com/aida/seller/module/listing/service/ListingService.java b/src/main/java/com/aida/seller/module/listing/service/ListingService.java index b8903c9..5e8d128 100644 --- a/src/main/java/com/aida/seller/module/listing/service/ListingService.java +++ b/src/main/java/com/aida/seller/module/listing/service/ListingService.java @@ -82,4 +82,12 @@ public interface ListingService extends IService { * @return 分页商品列表 */ IPage getShopListings(Long sellerId, String designFor, int pageNum, int pageSize); + + /** + * 迁移旧商品图片的水印数据:为所有已发布商品生成缺失的水印记录并存入数据库。 + * 仅处理尚无水印记录的原图,已存在水印记录的图片跳过。 + * + * @return 迁移处理的商品数量 + */ + int migrateWatermarks(); } diff --git a/src/main/java/com/aida/seller/module/listing/service/ListingServiceImpl.java b/src/main/java/com/aida/seller/module/listing/service/ListingServiceImpl.java index 174584e..c59f0c7 100644 --- a/src/main/java/com/aida/seller/module/listing/service/ListingServiceImpl.java +++ b/src/main/java/com/aida/seller/module/listing/service/ListingServiceImpl.java @@ -432,4 +432,67 @@ public class ListingServiceImpl extends ServiceImpl watermarkCategories = Set.of( + ImageCategoryEnum.COVER.getCode(), + ImageCategoryEnum.MAIN_PRODUCT.getCode(), + ImageCategoryEnum.PRODUCT.getCode(), + ImageCategoryEnum.SKETCH.getCode(), + ImageCategoryEnum.APPAREL.getCode()); + + // 查出所有已发布且未删除的商品 + List listings = this.list( + new LambdaQueryWrapper() + .eq(ListingEntity::getStatus, 1) + .eq(ListingEntity::getDeleted, 0)); + + int count = 0; + for (ListingEntity listing : listings) { + Long listingId = listing.getId(); + + // 查出该商品已有的水印记录,构建 originalUrl -> watermarkedUrl map + List existingWatermarks = + listingWatermarkImageMapper.selectByListingId(listingId); + Map existingMap = existingWatermarks.stream() + .collect(Collectors.toMap( + ListingWatermarkImageEntity::getOriginalUrl, + ListingWatermarkImageEntity::getWatermarkedUrl, + (a, b) -> a)); + + // 查出该商品所有需要水印的图片 + List images = listingImageMapper.selectList( + new LambdaQueryWrapper() + .eq(ListingImageEntity::getListingId, listingId) + .in(ListingImageEntity::getCategory, watermarkCategories)); + + for (ListingImageEntity img : images) { + String originalUrl = img.getImageUrl(); + + // 已有水印记录则跳过 + if (existingMap.containsKey(originalUrl)) { + continue; + } + + // 生成水印并入库 + String watermarkedUrl = imageWatermarkUtil.applyWatermark(originalUrl); + watermarkedUrl = minioUtil.convertToLogicalPath(watermarkedUrl); + + ListingWatermarkImageEntity watermark = new ListingWatermarkImageEntity(); + watermark.setListingId(listingId); + watermark.setCategory(img.getCategory()); + watermark.setOriginalUrl(originalUrl); + watermark.setWatermarkedUrl(watermarkedUrl); + + try { + listingWatermarkImageMapper.insert(watermark); + count++; + } catch (Exception ignored) { + // 唯一索引冲突(并发或重复数据),忽略 + } + } + } + return count; + } }