You've already forked FrameTour-BE
refactor(printer): 优化照片处理管线与自动发券逻辑
- 调整自动发券判断条件,仅当存在type=3的source记录时触发 - 修改普通照片与拼图处理流程中的图像增强控制逻辑 - 移除冗余的图像缩放阶段,优化处理效率 - 增加processPhotoWithPipeline重载方法支持图像增强选项 - 重构水印配置方法,新增scale参数控制缩放比例 - 异步处理打印任务创建与推送,提升响应速度 - 复用processPhotoWithPipeline方法简化重打印处理逻辑
This commit is contained in:
@@ -0,0 +1,126 @@
|
|||||||
|
package com.ycwl.basic.image.pipeline.stages;
|
||||||
|
|
||||||
|
import com.ycwl.basic.image.pipeline.core.PhotoProcessContext;
|
||||||
|
import com.ycwl.basic.pipeline.annotation.StageConfig;
|
||||||
|
import com.ycwl.basic.pipeline.core.AbstractPipelineStage;
|
||||||
|
import com.ycwl.basic.pipeline.core.StageResult;
|
||||||
|
import com.ycwl.basic.pipeline.enums.StageOptionalMode;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图像缩放Stage
|
||||||
|
* 支持按比例放大或缩小图片
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@StageConfig(
|
||||||
|
stageId = "image_resize",
|
||||||
|
optionalMode = StageOptionalMode.SUPPORT,
|
||||||
|
description = "图像缩放处理",
|
||||||
|
defaultEnabled = true
|
||||||
|
)
|
||||||
|
public class ImageResizeStage extends AbstractPipelineStage<PhotoProcessContext> {
|
||||||
|
|
||||||
|
private final double scaleFactor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造函数
|
||||||
|
* @param scaleFactor 缩放比例(例如: 1.5表示放大1.5倍, 0.333表示缩小到1/3)
|
||||||
|
*/
|
||||||
|
public ImageResizeStage(double scaleFactor) {
|
||||||
|
if (scaleFactor <= 0) {
|
||||||
|
throw new IllegalArgumentException("scaleFactor must be positive");
|
||||||
|
}
|
||||||
|
this.scaleFactor = scaleFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "ImageResizeStage";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected StageResult<PhotoProcessContext> doExecute(PhotoProcessContext context) {
|
||||||
|
File currentFile = context.getCurrentFile();
|
||||||
|
if (currentFile == null || !currentFile.exists()) {
|
||||||
|
return StageResult.skipped("当前文件不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferedImage originalImage = null;
|
||||||
|
BufferedImage resizedImage = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
log.debug("开始图像缩放处理: file={}, scaleFactor={}", currentFile.getName(), scaleFactor);
|
||||||
|
|
||||||
|
// 读取原图
|
||||||
|
originalImage = ImageIO.read(currentFile);
|
||||||
|
if (originalImage == null) {
|
||||||
|
return StageResult.failed("无法读取图片文件");
|
||||||
|
}
|
||||||
|
|
||||||
|
int originalWidth = originalImage.getWidth();
|
||||||
|
int originalHeight = originalImage.getHeight();
|
||||||
|
|
||||||
|
// 计算新尺寸
|
||||||
|
int newWidth = (int) Math.round(originalWidth * scaleFactor);
|
||||||
|
int newHeight = (int) Math.round(originalHeight * scaleFactor);
|
||||||
|
|
||||||
|
// 检查尺寸是否合理
|
||||||
|
if (newWidth <= 0 || newHeight <= 0) {
|
||||||
|
return StageResult.failed("缩放后尺寸无效: " + newWidth + "x" + newHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建缩放后的图像
|
||||||
|
resizedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
|
||||||
|
Graphics2D g2d = resizedImage.createGraphics();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 设置高质量渲染选项
|
||||||
|
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
||||||
|
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||||
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
|
// 执行缩放
|
||||||
|
g2d.drawImage(originalImage, 0, 0, newWidth, newHeight, null);
|
||||||
|
} finally {
|
||||||
|
g2d.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存缩放后的图片
|
||||||
|
File resizedFile = context.getTempFileManager().createTempFile("resized", ".jpg");
|
||||||
|
ImageIO.write(resizedImage, "jpg", resizedFile);
|
||||||
|
|
||||||
|
if (!resizedFile.exists() || resizedFile.length() == 0) {
|
||||||
|
return StageResult.failed("缩放后图片保存失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新处理后的文件
|
||||||
|
context.updateProcessedFile(resizedFile);
|
||||||
|
|
||||||
|
log.info("图像缩放完成: {}x{} -> {}x{} (比例: {})",
|
||||||
|
originalWidth, originalHeight,
|
||||||
|
newWidth, newHeight,
|
||||||
|
scaleFactor);
|
||||||
|
|
||||||
|
return StageResult.success(String.format("缩放完成 (%dx%d -> %dx%d)",
|
||||||
|
originalWidth, originalHeight, newWidth, newHeight));
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("图像缩放失败: {}", e.getMessage(), e);
|
||||||
|
return StageResult.failed("缩放失败: " + e.getMessage(), e);
|
||||||
|
} finally {
|
||||||
|
// 释放图像资源
|
||||||
|
if (originalImage != null) {
|
||||||
|
originalImage.flush();
|
||||||
|
}
|
||||||
|
if (resizedImage != null) {
|
||||||
|
resizedImage.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package com.ycwl.basic.image.pipeline.stages;
|
||||||
|
|
||||||
|
import com.ycwl.basic.image.pipeline.core.PhotoProcessContext;
|
||||||
|
import com.ycwl.basic.mapper.PrinterMapper;
|
||||||
|
import com.ycwl.basic.pipeline.annotation.StageConfig;
|
||||||
|
import com.ycwl.basic.pipeline.core.AbstractPipelineStage;
|
||||||
|
import com.ycwl.basic.pipeline.core.StageResult;
|
||||||
|
import com.ycwl.basic.pipeline.enums.StageOptionalMode;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新MemberPrint记录Stage
|
||||||
|
* 用于更新member_print表中的cropUrl字段
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@StageConfig(
|
||||||
|
stageId = "update_member_print",
|
||||||
|
optionalMode = StageOptionalMode.UNSUPPORT,
|
||||||
|
description = "更新MemberPrint记录",
|
||||||
|
defaultEnabled = true
|
||||||
|
)
|
||||||
|
public class UpdateMemberPrintStage extends AbstractPipelineStage<PhotoProcessContext> {
|
||||||
|
|
||||||
|
private final PrinterMapper printerMapper;
|
||||||
|
private final Integer memberPrintId;
|
||||||
|
private final Long memberId;
|
||||||
|
private final Long scenicId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造函数
|
||||||
|
* @param printerMapper PrinterMapper实例
|
||||||
|
* @param memberPrintId MemberPrint记录ID
|
||||||
|
* @param memberId 用户ID
|
||||||
|
* @param scenicId 景区ID
|
||||||
|
*/
|
||||||
|
public UpdateMemberPrintStage(PrinterMapper printerMapper, Integer memberPrintId, Long memberId, Long scenicId) {
|
||||||
|
this.printerMapper = printerMapper;
|
||||||
|
this.memberPrintId = memberPrintId;
|
||||||
|
this.memberId = memberId;
|
||||||
|
this.scenicId = scenicId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "UpdateMemberPrintStage";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected StageResult<PhotoProcessContext> doExecute(PhotoProcessContext context) {
|
||||||
|
String resultUrl = context.getResultUrl();
|
||||||
|
|
||||||
|
if (resultUrl == null || resultUrl.trim().isEmpty()) {
|
||||||
|
return StageResult.skipped("结果URL为空,跳过更新");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memberPrintId == null || memberId == null || scenicId == null) {
|
||||||
|
log.warn("MemberPrint更新参数不完整: memberPrintId={}, memberId={}, scenicId={}",
|
||||||
|
memberPrintId, memberId, scenicId);
|
||||||
|
return StageResult.skipped("更新参数不完整");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
log.debug("开始更新MemberPrint记录: id={}, newCropUrl={}", memberPrintId, resultUrl);
|
||||||
|
|
||||||
|
// 更新cropUrl字段
|
||||||
|
int rows = printerMapper.setPhotoCropped(memberId, scenicId, memberPrintId.longValue(), resultUrl, null);
|
||||||
|
|
||||||
|
if (rows > 0) {
|
||||||
|
log.info("MemberPrint记录更新成功: id={}, cropUrl已更新", memberPrintId);
|
||||||
|
return StageResult.success("更新成功");
|
||||||
|
} else {
|
||||||
|
log.warn("MemberPrint记录更新失败: 可能记录不存在, id={}", memberPrintId);
|
||||||
|
return StageResult.degraded("更新失败,记录可能不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("更新MemberPrint记录异常: id={}", memberPrintId, e);
|
||||||
|
// 更新失败不影响整个流程,使用降级状态
|
||||||
|
return StageResult.degraded("更新异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -351,6 +351,8 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
|
|
||||||
log.info("照片裁剪成功: memberId={}, scenicId={}, 原图={}, 裁剪后={}, 尺寸={}x{}",
|
log.info("照片裁剪成功: memberId={}, scenicId={}, 原图={}, 裁剪后={}, 尺寸={}x{}",
|
||||||
memberId, scenicId, url, cropUrl, printWidth, printHeight);
|
memberId, scenicId, url, cropUrl, printWidth, printHeight);
|
||||||
|
String crop = JacksonUtil.toJSONString(new Crop(270));
|
||||||
|
entity.setCrop(crop);
|
||||||
} finally {
|
} finally {
|
||||||
// 清理临时文件
|
// 清理临时文件
|
||||||
if (croppedFile != null && croppedFile.exists()) {
|
if (croppedFile != null && croppedFile.exists()) {
|
||||||
@@ -471,19 +473,20 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
|
|
||||||
request.setProducts(productItems);
|
request.setProducts(productItems);
|
||||||
|
|
||||||
if (mobileCount > 0) {
|
// 检查是否存在type=3的source记录,存在才自动发券
|
||||||
|
boolean hasType3Source = userPhotoList.stream()
|
||||||
|
.filter(item -> item.getSourceId() != null && item.getSourceId() > 0)
|
||||||
|
.anyMatch(item -> {
|
||||||
try {
|
try {
|
||||||
autoCouponService.autoGrantCoupon(
|
SourceEntity source = sourceMapper.getEntity(item.getSourceId());
|
||||||
memberId,
|
return source != null && Integer.valueOf(3).equals(source.getType());
|
||||||
faceId,
|
|
||||||
scenicId,
|
|
||||||
ProductType.PHOTO_PRINT_MU
|
|
||||||
);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("自动发券失败,不影响下单流程: memberId={}, faceId={}, scenicId={}, error={}",
|
log.warn("查询source失败: sourceId={}, error={}", item.getSourceId(), e.getMessage());
|
||||||
memberId, faceId, scenicId, e.getMessage());
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasType3Source) {
|
||||||
if (normalCount > 0) {
|
if (normalCount > 0) {
|
||||||
try {
|
try {
|
||||||
autoCouponService.autoGrantCoupon(
|
autoCouponService.autoGrantCoupon(
|
||||||
@@ -497,6 +500,20 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
memberId, faceId, scenicId, e.getMessage());
|
memberId, faceId, scenicId, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (mobileCount > 0) {
|
||||||
|
try {
|
||||||
|
autoCouponService.autoGrantCoupon(
|
||||||
|
memberId,
|
||||||
|
faceId,
|
||||||
|
scenicId,
|
||||||
|
ProductType.PHOTO_PRINT_MU
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("自动发券失败,不影响下单流程: memberId={}, faceId={}, scenicId={}, error={}",
|
||||||
|
memberId, faceId, scenicId, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
request.setAutoUseCoupon(true);
|
request.setAutoUseCoupon(true);
|
||||||
request.setPreviewOnly(true); // 仅查询价格,不实际使用优惠
|
request.setPreviewOnly(true); // 仅查询价格,不实际使用优惠
|
||||||
|
|
||||||
@@ -795,7 +812,6 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
.addStage(new ImageOrientationStage())
|
.addStage(new ImageOrientationStage())
|
||||||
.addStage(new ConditionalRotateStage())
|
.addStage(new ConditionalRotateStage())
|
||||||
.addStage(new ImageEnhanceStage(config)) // 通过setStageState方法设置是否启用
|
.addStage(new ImageEnhanceStage(config)) // 通过setStageState方法设置是否启用
|
||||||
.addStage(new ImageResizeStage(2.0 / 3.0)) // 缩小2/3倍(回到原分辨率)
|
|
||||||
.addStage(new WatermarkStage(watermarkConfig))
|
.addStage(new WatermarkStage(watermarkConfig))
|
||||||
.addStage(new RestoreOrientationStage())
|
.addStage(new RestoreOrientationStage())
|
||||||
.addStage(new UploadStage())
|
.addStage(new UploadStage())
|
||||||
@@ -823,6 +839,18 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
* @return 处理后的URL,失败返回原URL
|
* @return 处理后的URL,失败返回原URL
|
||||||
*/
|
*/
|
||||||
private String processPhotoWithPipeline(MemberPrintResp item, Long scenicId, File qrCodeFile) {
|
private String processPhotoWithPipeline(MemberPrintResp item, Long scenicId, File qrCodeFile) {
|
||||||
|
return processPhotoWithPipeline(item, scenicId, qrCodeFile, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用管线处理照片(支持增强选项)
|
||||||
|
* @param item 打印项
|
||||||
|
* @param scenicId 景区ID
|
||||||
|
* @param qrCodeFile 二维码文件
|
||||||
|
* @param needEnhance 是否需要图像增强(null 或 false 表示不增强)
|
||||||
|
* @return 处理后的URL,失败返回原URL
|
||||||
|
*/
|
||||||
|
private String processPhotoWithPipeline(MemberPrintResp item, Long scenicId, File qrCodeFile, Boolean needEnhance) {
|
||||||
PrinterOrderItem orderItem = PrinterOrderItem.fromMemberPrintResp(item);
|
PrinterOrderItem orderItem = PrinterOrderItem.fromMemberPrintResp(item);
|
||||||
|
|
||||||
PhotoProcessContext context = PhotoProcessContext.fromPrinterOrderItem(orderItem, scenicId);
|
PhotoProcessContext context = PhotoProcessContext.fromPrinterOrderItem(orderItem, scenicId);
|
||||||
@@ -835,6 +863,11 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
// 设置管线场景为图片打印
|
// 设置管线场景为图片打印
|
||||||
context.setScene(PipelineScene.IMAGE_PRINT);
|
context.setScene(PipelineScene.IMAGE_PRINT);
|
||||||
|
|
||||||
|
// 处理图像增强选项
|
||||||
|
if (needEnhance != null && needEnhance) {
|
||||||
|
context.setStageState("image_enhance", true);
|
||||||
|
}
|
||||||
|
|
||||||
// 根据sourceId判断图片来源和source类型
|
// 根据sourceId判断图片来源和source类型
|
||||||
SourceEntity source = null;
|
SourceEntity source = null;
|
||||||
if (item.getSourceId() != null && item.getSourceId() > 0) {
|
if (item.getSourceId() != null && item.getSourceId() > 0) {
|
||||||
@@ -861,13 +894,13 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
bceConfig.setSecretKey("dYatXReVriPeiktTjUblhfubpcmYfuMk");
|
bceConfig.setSecretKey("dYatXReVriPeiktTjUblhfubpcmYfuMk");
|
||||||
|
|
||||||
// 准备水印配置
|
// 准备水印配置
|
||||||
WatermarkConfig watermarkConfig = prepareWatermarkConfig(context, qrCodeFile);
|
WatermarkConfig watermarkConfig = prepareWatermarkConfig(context, qrCodeFile, 3.0);
|
||||||
// 准备存储适配器
|
// 准备存储适配器
|
||||||
prepareStorageAdapter(context);
|
prepareStorageAdapter(context);
|
||||||
context.enableStage("image_sr");
|
context.enableStage("image_sr");
|
||||||
context.enableStage("image_enhance");
|
context.enableStage("image_enhance");
|
||||||
|
|
||||||
// 构建特殊管线: 放大1.5倍 -> 超分(2倍) -> 增强 -> 更新MemberPrint -> 缩小3倍 -> 水印 -> 上传
|
// 构建特殊管线: 超分(2倍) -> 增强 -> 更新MemberPrint -> 缩小2倍 -> 水印 -> 上传
|
||||||
pipeline = new PipelineBuilder<PhotoProcessContext>("Type3Pipeline")
|
pipeline = new PipelineBuilder<PhotoProcessContext>("Type3Pipeline")
|
||||||
.addStage(new DownloadStage()) // 1. 下载图片
|
.addStage(new DownloadStage()) // 1. 下载图片
|
||||||
.addStage(new ImageOrientationStage()) // 2. 检测方向
|
.addStage(new ImageOrientationStage()) // 2. 检测方向
|
||||||
@@ -877,7 +910,6 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
.addStage(new UploadStage()) // 6. 上传(用于更新MemberPrint)
|
.addStage(new UploadStage()) // 6. 上传(用于更新MemberPrint)
|
||||||
.addStage(new UpdateMemberPrintStage(printerMapper, // 7. 更新MemberPrint的cropUrl
|
.addStage(new UpdateMemberPrintStage(printerMapper, // 7. 更新MemberPrint的cropUrl
|
||||||
item.getId(), item.getMemberId(), scenicId))
|
item.getId(), item.getMemberId(), scenicId))
|
||||||
.addStage(new ImageResizeStage(4.0 / 3.0)) // 8. 缩小3倍(回到原分辨率)
|
|
||||||
.addStage(new WatermarkStage(watermarkConfig)) // 9. 添加水印
|
.addStage(new WatermarkStage(watermarkConfig)) // 9. 添加水印
|
||||||
.addStage(new RestoreOrientationStage()) // 10. 恢复方向
|
.addStage(new RestoreOrientationStage()) // 10. 恢复方向
|
||||||
.addStage(new UploadStage()) // 11. 最终上传
|
.addStage(new UploadStage()) // 11. 最终上传
|
||||||
@@ -886,7 +918,7 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
|
|
||||||
} else if (context.getImageType() == ImageType.NORMAL_PHOTO) {
|
} else if (context.getImageType() == ImageType.NORMAL_PHOTO) {
|
||||||
// 普通照片处理流程
|
// 普通照片处理流程
|
||||||
WatermarkConfig watermarkConfig = prepareWatermarkConfig(context, qrCodeFile);
|
WatermarkConfig watermarkConfig = prepareWatermarkConfig(context, qrCodeFile, 1.5);
|
||||||
prepareStorageAdapter(context);
|
prepareStorageAdapter(context);
|
||||||
pipeline = createNormalPhotoPipeline(watermarkConfig);
|
pipeline = createNormalPhotoPipeline(watermarkConfig);
|
||||||
} else {
|
} else {
|
||||||
@@ -924,7 +956,7 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
* @param qrCodeFile 二维码文件
|
* @param qrCodeFile 二维码文件
|
||||||
* @return WatermarkConfig
|
* @return WatermarkConfig
|
||||||
*/
|
*/
|
||||||
private WatermarkConfig prepareWatermarkConfig(PhotoProcessContext context, File qrCodeFile) {
|
private WatermarkConfig prepareWatermarkConfig(PhotoProcessContext context, File qrCodeFile, Double scale) {
|
||||||
ScenicConfigManager scenicConfig = context.getScenicConfigManager();
|
ScenicConfigManager scenicConfig = context.getScenicConfigManager();
|
||||||
if (scenicConfig == null) {
|
if (scenicConfig == null) {
|
||||||
log.warn("scenicConfigManager未设置,返回空水印配置");
|
log.warn("scenicConfigManager未设置,返回空水印配置");
|
||||||
@@ -945,6 +977,7 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
.scenicText(scenicText)
|
.scenicText(scenicText)
|
||||||
.dateFormat(dateFormat)
|
.dateFormat(dateFormat)
|
||||||
.qrcodeFile(qrCodeFile)
|
.qrcodeFile(qrCodeFile)
|
||||||
|
.scale(scale)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -994,6 +1027,7 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
Thread.ofVirtual().start(() -> {
|
||||||
userPhotoListByOrderId.forEach(item -> {
|
userPhotoListByOrderId.forEach(item -> {
|
||||||
PrinterEntity printer = printerMapper.getById(item.getPrinterId());
|
PrinterEntity printer = printerMapper.getById(item.getPrinterId());
|
||||||
|
|
||||||
@@ -1042,6 +1076,7 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1475,58 +1510,15 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
needEnhance = false; // 默认不增强
|
needEnhance = false; // 默认不增强
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3.1 创建图片处理上下文
|
// 3.1 使用管线处理照片(复用 processPhotoWithPipeline)
|
||||||
PrinterOrderItem orderItem = PrinterOrderItem.fromMemberPrintResp(memberPrint);
|
String newPrintUrl;
|
||||||
PhotoProcessContext context = PhotoProcessContext.fromPrinterOrderItem(orderItem, memberPrint.getScenicId());
|
|
||||||
context.setStageState("image_enhance", needEnhance); // 通过setStageState方法设置是否启用
|
|
||||||
|
|
||||||
// 3.2 设置景区配置和场景
|
|
||||||
ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(memberPrint.getScenicId());
|
|
||||||
context.setScenicConfigManager(scenicConfig);
|
|
||||||
context.setScene(PipelineScene.IMAGE_PRINT);
|
|
||||||
|
|
||||||
// 3.3 判断图片来源
|
|
||||||
if (memberPrint.getSourceId() != null && memberPrint.getSourceId() > 0) {
|
|
||||||
context.setSource(ImageSource.IPC);
|
|
||||||
} else if (memberPrint.getSourceId() == null) {
|
|
||||||
context.setSource(ImageSource.PHONE);
|
|
||||||
} else {
|
|
||||||
context.setSource(ImageSource.UNKNOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3.4 构建管线(关键:条件性添加 ImageEnhanceStage)
|
|
||||||
Pipeline<PhotoProcessContext> pipeline;
|
|
||||||
String newPrintUrl = null;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (context.getImageType() == ImageType.NORMAL_PHOTO) {
|
newPrintUrl = processPhotoWithPipeline(memberPrint, memberPrint.getScenicId(), qrCodeFile, needEnhance);
|
||||||
// 准备水印配置(重打印需要二维码)
|
|
||||||
WatermarkConfig watermarkConfig = prepareWatermarkConfig(context, qrCodeFile);
|
|
||||||
prepareStorageAdapter(context);
|
|
||||||
|
|
||||||
// 创建管线,条件性添加增强 Stage
|
|
||||||
pipeline = createNormalPhotoPipeline(watermarkConfig);
|
|
||||||
} else {
|
|
||||||
// 拼图
|
|
||||||
prepareStorageAdapter(context);
|
|
||||||
pipeline = createPuzzlePipeline();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3.5 执行管线
|
|
||||||
boolean success = pipeline.execute(context);
|
|
||||||
if (success && context.getResultUrl() != null) {
|
|
||||||
newPrintUrl = context.getResultUrl();
|
|
||||||
log.info("handleReprint: 照片重新处理成功, taskId={}, mpId={}, enhance={}, newUrl={}",
|
log.info("handleReprint: 照片重新处理成功, taskId={}, mpId={}, enhance={}, newUrl={}",
|
||||||
id, mpId, needEnhance, newPrintUrl);
|
id, mpId, needEnhance, newPrintUrl);
|
||||||
} else {
|
|
||||||
log.warn("handleReprint: 照片重新处理失败, taskId={}, 使用原图", id);
|
|
||||||
newPrintUrl = memberPrint.getCropUrl(); // 使用原裁剪图
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("handleReprint: 照片重新处理异常, taskId={}, 使用原图", id, e);
|
log.error("handleReprint: 照片重新处理异常, taskId={}, 使用原图", id, e);
|
||||||
newPrintUrl = memberPrint.getCropUrl();
|
newPrintUrl = memberPrint.getCropUrl();
|
||||||
} finally {
|
|
||||||
context.cleanup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 更新打印任务
|
// 4. 更新打印任务
|
||||||
|
|||||||
Reference in New Issue
Block a user