优化水印
This commit is contained in:
@@ -0,0 +1,45 @@
|
|||||||
|
package com.aida.seller.module.listing.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品图片水印实体
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("seller_listing_watermark_image")
|
||||||
|
public class ListingWatermarkImageEntity implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 主键ID */
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/** 商品ID */
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long listingId;
|
||||||
|
|
||||||
|
/** 图片类别: cover/main_product/product/sketch/apparel */
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
/** 原图 logical path */
|
||||||
|
private String originalUrl;
|
||||||
|
|
||||||
|
/** 加水印图的 logical path */
|
||||||
|
private String watermarkedUrl;
|
||||||
|
|
||||||
|
/** 创建时间 */
|
||||||
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
/** 是否删除:0-否,1-是 */
|
||||||
|
@TableLogic
|
||||||
|
private Integer deleted;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.aida.seller.module.listing.mapper;
|
||||||
|
|
||||||
|
import com.aida.seller.module.listing.entity.ListingWatermarkImageEntity;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品图片水印 Mapper
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface ListingWatermarkImageMapper extends BaseMapper<ListingWatermarkImageEntity> {
|
||||||
|
|
||||||
|
int deleteByListingId(@Param("listingId") Long listingId);
|
||||||
|
|
||||||
|
List<ListingWatermarkImageEntity> selectByListingId(@Param("listingId") Long listingId);
|
||||||
|
}
|
||||||
@@ -6,12 +6,15 @@ import com.aida.seller.common.exception.BusinessException;
|
|||||||
import com.aida.seller.module.listing.dto.*;
|
import com.aida.seller.module.listing.dto.*;
|
||||||
import com.aida.seller.module.listing.entity.ListingEntity;
|
import com.aida.seller.module.listing.entity.ListingEntity;
|
||||||
import com.aida.seller.module.listing.entity.ListingImageEntity;
|
import com.aida.seller.module.listing.entity.ListingImageEntity;
|
||||||
|
import com.aida.seller.module.listing.entity.ListingWatermarkImageEntity;
|
||||||
import com.aida.seller.module.listing.enums.ImageCategoryEnum;
|
import com.aida.seller.module.listing.enums.ImageCategoryEnum;
|
||||||
import com.aida.seller.module.listing.enums.ListingStatusEnum;
|
import com.aida.seller.module.listing.enums.ListingStatusEnum;
|
||||||
import com.aida.seller.module.listing.enums.DesignForEnum;
|
import com.aida.seller.module.listing.enums.DesignForEnum;
|
||||||
import com.aida.seller.module.listing.enums.ProductCategoryEnum;
|
import com.aida.seller.module.listing.enums.ProductCategoryEnum;
|
||||||
import com.aida.seller.module.listing.mapper.ListingImageMapper;
|
import com.aida.seller.module.listing.mapper.ListingImageMapper;
|
||||||
import com.aida.seller.module.listing.mapper.ListingMapper;
|
import com.aida.seller.module.listing.mapper.ListingMapper;
|
||||||
|
import com.aida.seller.module.listing.mapper.ListingWatermarkImageMapper;
|
||||||
|
import com.aida.seller.util.ImageWatermarkUtil;
|
||||||
import com.aida.seller.module.listing.vo.ListingPageVO;
|
import com.aida.seller.module.listing.vo.ListingPageVO;
|
||||||
import com.aida.seller.module.order.mapper.OrderItemMapper;
|
import com.aida.seller.module.order.mapper.OrderItemMapper;
|
||||||
import com.aida.seller.module.order.entity.OrderItemEntity;
|
import com.aida.seller.module.order.entity.OrderItemEntity;
|
||||||
@@ -44,9 +47,11 @@ import java.util.stream.Collectors;
|
|||||||
public class ListingServiceImpl extends ServiceImpl<ListingMapper, ListingEntity> implements ListingService {
|
public class ListingServiceImpl extends ServiceImpl<ListingMapper, ListingEntity> implements ListingService {
|
||||||
|
|
||||||
private final ListingImageMapper listingImageMapper;
|
private final ListingImageMapper listingImageMapper;
|
||||||
|
private final ListingWatermarkImageMapper listingWatermarkImageMapper;
|
||||||
private final OrderItemMapper orderItemMapper;
|
private final OrderItemMapper orderItemMapper;
|
||||||
private final RedisTemplate<String, Object> redisTemplate;
|
private final RedisTemplate<String, Object> redisTemplate;
|
||||||
private final MinioUtil minioUtil;
|
private final MinioUtil minioUtil;
|
||||||
|
private final ImageWatermarkUtil imageWatermarkUtil;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@@ -68,6 +73,7 @@ public class ListingServiceImpl extends ServiceImpl<ListingMapper, ListingEntity
|
|||||||
}
|
}
|
||||||
|
|
||||||
Long listingId;
|
Long listingId;
|
||||||
|
Map<String, String> oldWatermarks = Map.of();
|
||||||
if (dto.getId() == null) {
|
if (dto.getId() == null) {
|
||||||
entity.setStatus(dto.getStatus());
|
entity.setStatus(dto.getStatus());
|
||||||
this.save(entity);
|
this.save(entity);
|
||||||
@@ -86,6 +92,15 @@ public class ListingServiceImpl extends ServiceImpl<ListingMapper, ListingEntity
|
|||||||
listingImageMapper.delete(new LambdaQueryWrapper<ListingImageEntity>()
|
listingImageMapper.delete(new LambdaQueryWrapper<ListingImageEntity>()
|
||||||
.eq(ListingImageEntity::getListingId, dto.getId()));
|
.eq(ListingImageEntity::getListingId, dto.getId()));
|
||||||
listingId = dto.getId();
|
listingId = dto.getId();
|
||||||
|
|
||||||
|
if (Objects.equals(dto.getStatus(), 1)) {
|
||||||
|
List<ListingWatermarkImageEntity> oldWmList = listingWatermarkImageMapper.selectByListingId(listingId);
|
||||||
|
oldWatermarks = oldWmList.stream()
|
||||||
|
.collect(Collectors.toMap(ListingWatermarkImageEntity::getOriginalUrl,
|
||||||
|
ListingWatermarkImageEntity::getWatermarkedUrl,
|
||||||
|
(a, b) -> a));
|
||||||
|
listingWatermarkImageMapper.deleteByListingId(listingId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CollectionUtils.isEmpty(dto.getImages())) {
|
if (!CollectionUtils.isEmpty(dto.getImages())) {
|
||||||
@@ -98,6 +113,10 @@ public class ListingServiceImpl extends ServiceImpl<ListingMapper, ListingEntity
|
|||||||
update.setCover(minioUtil.convertToLogicalPath(cover));
|
update.setCover(minioUtil.convertToLogicalPath(cover));
|
||||||
this.updateById(update);
|
this.updateById(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Objects.equals(dto.getStatus(), 1)) {
|
||||||
|
generateWatermarks(listingId, oldWatermarks);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,6 +278,45 @@ public class ListingServiceImpl extends ServiceImpl<ListingMapper, ListingEntity
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void generateWatermarks(Long listingId, Map<String, String> oldWatermarks) {
|
||||||
|
Set<String> watermarkCategories = Set.of(
|
||||||
|
ImageCategoryEnum.COVER.getCode(),
|
||||||
|
ImageCategoryEnum.MAIN_PRODUCT.getCode(),
|
||||||
|
ImageCategoryEnum.PRODUCT.getCode(),
|
||||||
|
ImageCategoryEnum.SKETCH.getCode(),
|
||||||
|
ImageCategoryEnum.APPAREL.getCode());
|
||||||
|
|
||||||
|
List<ListingImageEntity> images = listingImageMapper.selectList(
|
||||||
|
new LambdaQueryWrapper<ListingImageEntity>()
|
||||||
|
.eq(ListingImageEntity::getListingId, listingId)
|
||||||
|
.in(ListingImageEntity::getCategory, watermarkCategories));
|
||||||
|
|
||||||
|
for (ListingImageEntity img : images) {
|
||||||
|
String originalUrl = img.getImageUrl();
|
||||||
|
String watermarkedUrl;
|
||||||
|
|
||||||
|
String existingWm = oldWatermarks.get(originalUrl);
|
||||||
|
if (existingWm != null) {
|
||||||
|
watermarkedUrl = existingWm;
|
||||||
|
} else {
|
||||||
|
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);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 唯一索引冲突,忽略
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPopupReminder(Long sellerId) {
|
public void setPopupReminder(Long sellerId) {
|
||||||
|
|||||||
@@ -8,17 +8,18 @@ import com.aida.seller.module.designer.mapper.DesignerMapper;
|
|||||||
import com.aida.seller.module.listing.dto.ListingMallQueryDTO;
|
import com.aida.seller.module.listing.dto.ListingMallQueryDTO;
|
||||||
import com.aida.seller.module.listing.entity.ListingEntity;
|
import com.aida.seller.module.listing.entity.ListingEntity;
|
||||||
import com.aida.seller.module.listing.entity.ListingImageEntity;
|
import com.aida.seller.module.listing.entity.ListingImageEntity;
|
||||||
|
import com.aida.seller.module.listing.entity.ListingWatermarkImageEntity;
|
||||||
import com.aida.seller.module.listing.enums.DesignForEnum;
|
import com.aida.seller.module.listing.enums.DesignForEnum;
|
||||||
import com.aida.seller.module.listing.enums.ImageCategoryEnum;
|
import com.aida.seller.module.listing.enums.ImageCategoryEnum;
|
||||||
import com.aida.seller.module.listing.mapper.ListingImageMapper;
|
import com.aida.seller.module.listing.mapper.ListingImageMapper;
|
||||||
import com.aida.seller.module.listing.mapper.ListingMallMapper;
|
import com.aida.seller.module.listing.mapper.ListingMallMapper;
|
||||||
|
import com.aida.seller.module.listing.mapper.ListingWatermarkImageMapper;
|
||||||
import com.aida.seller.module.listing.vo.ListingDetailVO;
|
import com.aida.seller.module.listing.vo.ListingDetailVO;
|
||||||
import com.aida.seller.module.listing.vo.ListingMallVO;
|
import com.aida.seller.module.listing.vo.ListingMallVO;
|
||||||
import com.aida.seller.module.order.entity.OrderItemEntity;
|
import com.aida.seller.module.order.entity.OrderItemEntity;
|
||||||
import com.aida.seller.module.order.entity.OrderItemImageEntity;
|
import com.aida.seller.module.order.entity.OrderItemImageEntity;
|
||||||
import com.aida.seller.module.order.mapper.OrderItemImageMapper;
|
import com.aida.seller.module.order.mapper.OrderItemImageMapper;
|
||||||
import com.aida.seller.module.order.mapper.OrderItemMapper;
|
import com.aida.seller.module.order.mapper.OrderItemMapper;
|
||||||
import com.aida.seller.util.ImageWatermarkUtil;
|
|
||||||
import com.aida.seller.util.MinioUtil;
|
import com.aida.seller.util.MinioUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
@@ -44,17 +45,17 @@ import com.aida.seller.module.listing.vo.ListingMallVO;
|
|||||||
public class ListingMallServiceImpl extends ServiceImpl<ListingMallMapper, ListingEntity> implements com.aida.seller.module.listing.service.ListingMallService {
|
public class ListingMallServiceImpl extends ServiceImpl<ListingMallMapper, ListingEntity> implements com.aida.seller.module.listing.service.ListingMallService {
|
||||||
|
|
||||||
private final MinioUtil minioUtil;
|
private final MinioUtil minioUtil;
|
||||||
private final ImageWatermarkUtil imageWatermarkUtil;
|
|
||||||
private final ListingImageMapper listingImageMapper;
|
private final ListingImageMapper listingImageMapper;
|
||||||
|
private final ListingWatermarkImageMapper listingWatermarkImageMapper;
|
||||||
private final DesignerMapper designerMapper;
|
private final DesignerMapper designerMapper;
|
||||||
private final OrderItemImageMapper orderItemImageMapper;
|
private final OrderItemImageMapper orderItemImageMapper;
|
||||||
private final OrderItemMapper orderItemMapper;
|
private final OrderItemMapper orderItemMapper;
|
||||||
|
|
||||||
public ListingMallServiceImpl(MinioUtil minioUtil, ImageWatermarkUtil imageWatermarkUtil, ListingImageMapper listingImageMapper, DesignerMapper designerMapper,
|
public ListingMallServiceImpl(MinioUtil minioUtil, ListingImageMapper listingImageMapper, ListingWatermarkImageMapper listingWatermarkImageMapper, DesignerMapper designerMapper,
|
||||||
OrderItemImageMapper orderItemImageMapper, OrderItemMapper orderItemMapper) {
|
OrderItemImageMapper orderItemImageMapper, OrderItemMapper orderItemMapper) {
|
||||||
this.minioUtil = minioUtil;
|
this.minioUtil = minioUtil;
|
||||||
this.imageWatermarkUtil = imageWatermarkUtil;
|
|
||||||
this.listingImageMapper = listingImageMapper;
|
this.listingImageMapper = listingImageMapper;
|
||||||
|
this.listingWatermarkImageMapper = listingWatermarkImageMapper;
|
||||||
this.designerMapper = designerMapper;
|
this.designerMapper = designerMapper;
|
||||||
this.orderItemImageMapper = orderItemImageMapper;
|
this.orderItemImageMapper = orderItemImageMapper;
|
||||||
this.orderItemMapper = orderItemMapper;
|
this.orderItemMapper = orderItemMapper;
|
||||||
@@ -252,6 +253,40 @@ public class ListingMallServiceImpl extends ServiceImpl<ListingMallMapper, Listi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 步骤3:从数据库读取预生成的水印记录,将原图 URL 替换为水印图 URL
|
||||||
|
List<ListingWatermarkImageEntity> watermarks = listingWatermarkImageMapper.selectByListingId(id);
|
||||||
|
if (!watermarks.isEmpty()) {
|
||||||
|
// 以 originalUrl 为 key,水印图 logical path 为 value,构建查询 map
|
||||||
|
Map<String, String> watermarkMap = watermarks.stream()
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
ListingWatermarkImageEntity::getOriginalUrl,
|
||||||
|
ListingWatermarkImageEntity::getWatermarkedUrl,
|
||||||
|
(a, b) -> a
|
||||||
|
));
|
||||||
|
for (Map.Entry<String, List<String>> entry : imageMap.entrySet()) {
|
||||||
|
List<String> urls = entry.getValue();
|
||||||
|
if (urls == null || urls.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 遍历该类别的所有图片 URL,尝试从 watermarkMap 中找到对应的水印图
|
||||||
|
// 命中则替换为水印图的 presigned URL;未命中则保留原 URL(说明该图未生成水印或不在水印表)
|
||||||
|
List<String> watermarkedUrls = urls.stream()
|
||||||
|
.map(url -> {
|
||||||
|
try {
|
||||||
|
String logicalPath = minioUtil.convertToLogicalPath(url);
|
||||||
|
String wmUrl = watermarkMap.get(logicalPath);
|
||||||
|
if (wmUrl != null) {
|
||||||
|
return minioUtil.getImageUrl(wmUrl, CommonConstants.MINIO_PATH_TIMEOUT);
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
})
|
||||||
|
.toList();
|
||||||
|
imageMap.put(entry.getKey(), watermarkedUrls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DesignerEntity designer = designerMapper.selectOne(
|
DesignerEntity designer = designerMapper.selectOne(
|
||||||
new LambdaQueryWrapper<DesignerEntity>()
|
new LambdaQueryWrapper<DesignerEntity>()
|
||||||
.eq(DesignerEntity::getUserId, entity.getSellerId())
|
.eq(DesignerEntity::getUserId, entity.getSellerId())
|
||||||
@@ -292,14 +327,6 @@ public class ListingMallServiceImpl extends ServiceImpl<ListingMallMapper, Listi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> apparelUrls = imageMap.get("apparel");
|
|
||||||
if (!CollectionUtils.isEmpty(apparelUrls)) {
|
|
||||||
List<String> watermarkedUrls = apparelUrls.parallelStream()
|
|
||||||
.map(imageWatermarkUtil::applyWatermark)
|
|
||||||
.toList();
|
|
||||||
imageMap.put("apparel", watermarkedUrls);
|
|
||||||
}
|
|
||||||
|
|
||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ import java.awt.geom.AffineTransform;
|
|||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@@ -22,17 +20,10 @@ public class ImageWatermarkUtil {
|
|||||||
private final WatermarkProperties watermarkProperties;
|
private final WatermarkProperties watermarkProperties;
|
||||||
private final MinioUtil minioUtil;
|
private final MinioUtil minioUtil;
|
||||||
|
|
||||||
private static final String WATERMARK_CACHE_PREFIX = "watermark:";
|
|
||||||
private static final int PRESIGNED_URL_EXPIRE_SECONDS = 7 * 24 * 60 * 60;
|
private static final int PRESIGNED_URL_EXPIRE_SECONDS = 7 * 24 * 60 * 60;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局水印结果缓存,key = 原图 logical path hash,value = 带水印图片的 logical path
|
* 对指定 MinIO 资源添加平铺文字水印,返回带水印图片的 presigned URL(有效期 7 天)。
|
||||||
*/
|
|
||||||
private final Map<String, String> watermarkCache = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对指定 MinIO 资源添加平铺文字水印,返回带水印图片的 presigned URL。
|
|
||||||
* 相同原图结果会被缓存 30 天。
|
|
||||||
*/
|
*/
|
||||||
public String applyWatermark(String minioResource) {
|
public String applyWatermark(String minioResource) {
|
||||||
try {
|
try {
|
||||||
@@ -40,13 +31,6 @@ public class ImageWatermarkUtil {
|
|||||||
? minioUtil.getLogicalPathFromPresignedUrl(minioResource)
|
? minioUtil.getLogicalPathFromPresignedUrl(minioResource)
|
||||||
: minioResource.trim();
|
: minioResource.trim();
|
||||||
|
|
||||||
String cacheKey = String.valueOf(logicalPath.hashCode());
|
|
||||||
|
|
||||||
String cachedPath = watermarkCache.get(cacheKey);
|
|
||||||
if (cachedPath != null) {
|
|
||||||
return minioUtil.getImageUrl(cachedPath, PRESIGNED_URL_EXPIRE_SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
try (InputStream originalStream = minioUtil.downloadFile(logicalPath);
|
try (InputStream originalStream = minioUtil.downloadFile(logicalPath);
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||||
|
|
||||||
@@ -55,8 +39,6 @@ public class ImageWatermarkUtil {
|
|||||||
detectContentType(logicalPath));
|
detectContentType(logicalPath));
|
||||||
|
|
||||||
String newPath = uploadWatermarkedImage(watermarkedBytes, logicalPath);
|
String newPath = uploadWatermarkedImage(watermarkedBytes, logicalPath);
|
||||||
watermarkCache.put(cacheKey, newPath);
|
|
||||||
|
|
||||||
return minioUtil.getImageUrl(newPath, PRESIGNED_URL_EXPIRE_SECONDS);
|
return minioUtil.getImageUrl(newPath, PRESIGNED_URL_EXPIRE_SECONDS);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -141,18 +123,4 @@ public class ImageWatermarkUtil {
|
|||||||
if (lower.endsWith(".webp")) return "image/webp";
|
if (lower.endsWith(".webp")) return "image/webp";
|
||||||
return "image/jpeg";
|
return "image/jpeg";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 清理指定原图的水印缓存(供外部在原图更新时调用)
|
|
||||||
*/
|
|
||||||
public void evictCache(String minioResource) {
|
|
||||||
try {
|
|
||||||
String logicalPath = minioUtil.isPresignedUrl(minioResource)
|
|
||||||
? minioUtil.getLogicalPathFromPresignedUrl(minioResource)
|
|
||||||
: minioResource.trim();
|
|
||||||
watermarkCache.remove(String.valueOf(logicalPath.hashCode()));
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("清理水印缓存失败 resource={}", minioResource, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,3 +112,17 @@ CREATE TABLE seller_order_item_image (
|
|||||||
deleted INT(1) DEFAULT 0 COMMENT '是否删除:0-否,1-是',
|
deleted INT(1) DEFAULT 0 COMMENT '是否删除:0-否,1-是',
|
||||||
INDEX idx_listing_buyer (listing_id, buyer_id)
|
INDEX idx_listing_buyer (listing_id, buyer_id)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单商品图片快照表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单商品图片快照表';
|
||||||
|
|
||||||
|
-- 商品图片水印表
|
||||||
|
CREATE TABLE seller_listing_watermark_image (
|
||||||
|
id BIGINT PRIMARY KEY COMMENT '主键ID',
|
||||||
|
listing_id BIGINT NOT NULL COMMENT '商品ID',
|
||||||
|
category VARCHAR(50) NOT NULL COMMENT '图片类别: cover/main_product/product/sketch/apparel',
|
||||||
|
original_url VARCHAR(500) NOT NULL COMMENT '原图 logical path',
|
||||||
|
watermarked_url VARCHAR(500) NOT NULL COMMENT '加水印图的 logical path',
|
||||||
|
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
deleted INT(1) DEFAULT 0 COMMENT '是否删除:0-否,1-是',
|
||||||
|
UNIQUE KEY uk_listing_category (listing_id, category, original_url),
|
||||||
|
INDEX idx_listing_id (listing_id),
|
||||||
|
INDEX idx_deleted (deleted)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品图片水印表';
|
||||||
|
|||||||
16
src/main/resources/mapper/ListingWatermarkImageMapper.xml
Normal file
16
src/main/resources/mapper/ListingWatermarkImageMapper.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.aida.seller.module.listing.mapper.ListingWatermarkImageMapper">
|
||||||
|
|
||||||
|
<delete id="deleteByListingId">
|
||||||
|
DELETE FROM seller_listing_watermark_image
|
||||||
|
WHERE listing_id = #{listingId} AND deleted = 0
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
<select id="selectByListingId" resultType="com.aida.seller.module.listing.entity.ListingWatermarkImageEntity">
|
||||||
|
SELECT id, listing_id, category, original_url, watermarked_url, create_time
|
||||||
|
FROM seller_listing_watermark_image
|
||||||
|
WHERE listing_id = #{listingId} AND deleted = 0
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
<update id="incrementSalesVolumeByOrderIds">
|
<update id="incrementSalesVolumeByOrderIds">
|
||||||
UPDATE seller_listing
|
UPDATE seller_listing
|
||||||
SET sales_volume = sales_volume + 1
|
SET sales_volume = sales_volume + 1, update_time = update_time
|
||||||
WHERE id IN (
|
WHERE id IN (
|
||||||
SELECT DISTINCT listing_id FROM seller_order_item
|
SELECT DISTINCT listing_id FROM seller_order_item
|
||||||
WHERE order_id IN
|
WHERE order_id IN
|
||||||
|
|||||||
Reference in New Issue
Block a user