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());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user