You've already forked FrameTour-BE
feat(printer): 添加打印照片水印处理功能
- 引入图片水印处理相关依赖和工具类 - 实现根据景区配置动态添加水印逻辑 - 支持从配置中读取存储类型和水印类型 - 下载原始图片并应用水印处理 - 将处理后的水印图片上传至指定存储服务 - 打印任务使用水印图片URL替代原始URL - 增加异常失败时回处理确保水印退到原始图片- 清理处理过程中产生的临时文件
This commit is contained in:
@@ -1,9 +1,17 @@
|
||||
package com.ycwl.basic.service.printer.impl;
|
||||
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.ycwl.basic.biz.OrderBiz;
|
||||
import com.ycwl.basic.constant.NumberConstant;
|
||||
import com.ycwl.basic.constant.StorageConstant;
|
||||
import com.ycwl.basic.enums.OrderStateEnum;
|
||||
import com.ycwl.basic.exception.BaseException;
|
||||
import com.ycwl.basic.image.watermark.ImageWatermarkFactory;
|
||||
import com.ycwl.basic.image.watermark.entity.WatermarkInfo;
|
||||
import com.ycwl.basic.image.watermark.enums.ImageWatermarkOperatorEnum;
|
||||
import com.ycwl.basic.image.watermark.exception.ImageWatermarkException;
|
||||
import com.ycwl.basic.image.watermark.operator.IOperator;
|
||||
import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
|
||||
import com.ycwl.basic.mapper.MemberMapper;
|
||||
import com.ycwl.basic.mapper.OrderMapper;
|
||||
import com.ycwl.basic.mapper.PrintTaskMapper;
|
||||
@@ -31,9 +39,14 @@ import com.ycwl.basic.model.printer.req.WorkerAuthReqVo;
|
||||
import com.ycwl.basic.model.printer.resp.PrintTaskResp;
|
||||
import com.ycwl.basic.model.wx.WXPayOrderReqVO;
|
||||
import com.ycwl.basic.repository.PriceRepository;
|
||||
import com.ycwl.basic.repository.ScenicRepository;
|
||||
import com.ycwl.basic.service.mobile.WxPayService;
|
||||
import com.ycwl.basic.service.printer.PrinterService;
|
||||
import com.ycwl.basic.storage.StorageFactory;
|
||||
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
||||
import com.ycwl.basic.storage.enums.StorageAcl;
|
||||
import com.ycwl.basic.utils.ApiResponse;
|
||||
import com.ycwl.basic.utils.JacksonUtil;
|
||||
import com.ycwl.basic.utils.SnowFlakeUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -43,6 +56,7 @@ import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
@@ -75,6 +89,8 @@ public class PrinterServiceImpl implements PrinterService {
|
||||
private PrintTaskMapper printTaskMapper;
|
||||
@Autowired
|
||||
private IPriceCalculationService priceCalculationService;
|
||||
@Autowired
|
||||
private ScenicRepository scenicRepository;
|
||||
|
||||
@Override
|
||||
public List<PrinterResp> listByScenicId(Long scenicId) {
|
||||
@@ -421,10 +437,74 @@ public class PrinterServiceImpl implements PrinterService {
|
||||
List<MemberPrintResp> userPhotoListByOrderId = getUserPhotoListByOrderId(orderId);
|
||||
userPhotoListByOrderId.forEach(item -> {
|
||||
PrinterEntity printer = printerMapper.getById(item.getPrinterId());
|
||||
|
||||
// 水印处理逻辑
|
||||
String printUrl = item.getCropUrl();
|
||||
try {
|
||||
ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(item.getScenicId());
|
||||
String printWatermarkType = scenicConfig.getString("print_watermark_type");
|
||||
|
||||
if (printWatermarkType != null && StringUtils.isNotBlank(printWatermarkType)) {
|
||||
ImageWatermarkOperatorEnum watermarkType = ImageWatermarkOperatorEnum.getByCode(printWatermarkType);
|
||||
if (watermarkType != null) {
|
||||
// 准备存储适配器
|
||||
IStorageAdapter adapter;
|
||||
String storeType = scenicConfig.getString("store_type");
|
||||
if (storeType != null) {
|
||||
adapter = StorageFactory.get(storeType);
|
||||
String storeConfigJson = scenicConfig.getString("store_config_json");
|
||||
if (StringUtils.isNotBlank(storeConfigJson)) {
|
||||
adapter.loadConfig(JacksonUtil.parseObject(storeConfigJson, Map.class));
|
||||
}
|
||||
} else {
|
||||
adapter = StorageFactory.use("assets-ext");
|
||||
}
|
||||
|
||||
// 准备水印处理器
|
||||
IOperator operator = ImageWatermarkFactory.get(watermarkType);
|
||||
|
||||
// 下载原图
|
||||
File originalFile = new File("print_" + item.getId() + ".jpg");
|
||||
File watermarkedFile = new File("print_" + item.getId() + "_" + watermarkType.getType() + "." + watermarkType.getPreferFileType());
|
||||
|
||||
try {
|
||||
HttpUtil.downloadFile(item.getCropUrl().replace("oss.zhentuai.com", "frametour-assets.oss-cn-shanghai-internal.aliyuncs.com"), originalFile);
|
||||
|
||||
// 处理水印
|
||||
WatermarkInfo watermarkInfo = new WatermarkInfo();
|
||||
watermarkInfo.setOriginalFile(originalFile);
|
||||
watermarkInfo.setWatermarkedFile(watermarkedFile);
|
||||
|
||||
operator.process(watermarkInfo);
|
||||
|
||||
// 上传水印图片
|
||||
String watermarkedUrl = adapter.uploadFile(null, watermarkedFile, StorageConstant.PHOTO_WATERMARKED_PATH, watermarkedFile.getName());
|
||||
adapter.setAcl(StorageAcl.PUBLIC_READ, StorageConstant.PHOTO_WATERMARKED_PATH, watermarkedFile.getName());
|
||||
|
||||
printUrl = watermarkedUrl;
|
||||
log.info("水印处理成功,打印照片ID: {}, 水印URL: {}", item.getId(), watermarkedUrl);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("水印处理失败,使用原始照片进行打印。照片ID: {}", item.getId(), e);
|
||||
} finally {
|
||||
// 清理临时文件
|
||||
if (originalFile.exists()) {
|
||||
originalFile.delete();
|
||||
}
|
||||
if (watermarkedFile.exists()) {
|
||||
watermarkedFile.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("获取景区配置失败,使用原始照片进行打印。景区ID: {}, 照片ID: {}", item.getScenicId(), item.getId(), e);
|
||||
}
|
||||
|
||||
PrintTaskEntity task = new PrintTaskEntity();
|
||||
task.setPrinterId(printer.getId());
|
||||
task.setStatus(0);
|
||||
task.setUrl(item.getCropUrl());
|
||||
task.setUrl(printUrl);
|
||||
task.setHeight(printer.getPreferH());
|
||||
task.setWidth(printer.getPreferW());
|
||||
task.setCreateTime(new Date());
|
||||
|
||||
Reference in New Issue
Block a user