You've already forked FrameTour-BE
refactor(puzzle): 重构拼图功能实现会员拼图关联管理
- 移除原有的图片裁切功能和userArea字段 - 删除originalImageUrl字段,统一使用resultImageUrl - 添加MemberPuzzleEntity实体类管理会员拼图关联关系 - 创建MemberPuzzleMapper接口及XML映射文件 - 实现PuzzleRelationProcessor处理器负责关联记录创建 - 在拼图生成完成后自动创建会员拼图关联记录 - 添加景区配置中的免费拼图数量设置 - 实现免费拼图逻辑控制 - 更新拼图模板和生成记录的数据结构 - 修改AppPuzzleController中图片URL的获取方式 - 优化PuzzleEdgeRenderTaskService中的图片处理流程
This commit is contained in:
@@ -18,6 +18,7 @@ import com.ycwl.basic.puzzle.service.IPuzzleGenerateService;
|
||||
import com.ycwl.basic.puzzle.util.PuzzleDuplicationDetector;
|
||||
import com.ycwl.basic.puzzle.util.PuzzleImageRenderer;
|
||||
import com.ycwl.basic.repository.ScenicRepository;
|
||||
import com.ycwl.basic.service.pc.processor.PuzzleRelationProcessor;
|
||||
import com.ycwl.basic.service.printer.PrinterService;
|
||||
import com.ycwl.basic.storage.StorageFactory;
|
||||
import com.ycwl.basic.utils.WxMpUtil;
|
||||
@@ -58,6 +59,7 @@ public class PuzzleGenerateServiceImpl implements IPuzzleGenerateService {
|
||||
private final PrinterService printerService;
|
||||
private final PuzzleEdgeRenderTaskService puzzleEdgeRenderTaskService;
|
||||
private final FaceStatusManager faceStatusManager;
|
||||
private final PuzzleRelationProcessor puzzleRelationProcessor;
|
||||
|
||||
public PuzzleGenerateServiceImpl(
|
||||
PuzzleRepository puzzleRepository,
|
||||
@@ -68,7 +70,8 @@ public class PuzzleGenerateServiceImpl implements IPuzzleGenerateService {
|
||||
@Lazy PuzzleDuplicationDetector duplicationDetector,
|
||||
@Lazy PrinterService printerService,
|
||||
PuzzleEdgeRenderTaskService puzzleEdgeRenderTaskService,
|
||||
@Lazy FaceStatusManager faceStatusManager) {
|
||||
@Lazy FaceStatusManager faceStatusManager,
|
||||
@Lazy PuzzleRelationProcessor puzzleRelationProcessor) {
|
||||
this.puzzleRepository = puzzleRepository;
|
||||
this.recordMapper = recordMapper;
|
||||
this.imageRenderer = imageRenderer;
|
||||
@@ -78,6 +81,7 @@ public class PuzzleGenerateServiceImpl implements IPuzzleGenerateService {
|
||||
this.printerService = printerService;
|
||||
this.puzzleEdgeRenderTaskService = puzzleEdgeRenderTaskService;
|
||||
this.faceStatusManager = faceStatusManager;
|
||||
this.puzzleRelationProcessor = puzzleRelationProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -206,6 +210,14 @@ public class PuzzleGenerateServiceImpl implements IPuzzleGenerateService {
|
||||
faceStatusManager.markPuzzleSourceVersion(request.getFaceId(), template.getId(), 0);
|
||||
}
|
||||
|
||||
// 创建member_puzzle关联记录
|
||||
puzzleRelationProcessor.createPuzzleRelation(
|
||||
request.getUserId(),
|
||||
resolvedScenicId,
|
||||
request.getFaceId(),
|
||||
record.getId()
|
||||
);
|
||||
|
||||
// 重新查询记录获取完整信息(边缘渲染回调已更新)
|
||||
PuzzleGenerationRecordEntity updatedRecord = recordMapper.getById(record.getId());
|
||||
if (updatedRecord != null && updatedRecord.getResultImageUrl() != null) {
|
||||
@@ -456,43 +468,27 @@ public class PuzzleGenerateServiceImpl implements IPuzzleGenerateService {
|
||||
// 渲染图片
|
||||
BufferedImage resultImage = imageRenderer.render(template, elements, finalDynamicData);
|
||||
|
||||
// 上传原图到OSS(未裁切)
|
||||
String originalImageUrl = uploadImage(resultImage, template.getCode(), request.getOutputFormat(), request.getQuality());
|
||||
log.info("原图上传成功: url={}", originalImageUrl);
|
||||
|
||||
// 处理用户区域裁切
|
||||
String finalImageUrl = originalImageUrl;
|
||||
BufferedImage finalImage = resultImage;
|
||||
|
||||
if (StrUtil.isNotBlank(template.getUserArea())) {
|
||||
try {
|
||||
BufferedImage croppedImage = cropImage(resultImage, template.getUserArea());
|
||||
finalImageUrl = uploadImage(croppedImage, template.getCode() + "_cropped", request.getOutputFormat(), request.getQuality());
|
||||
finalImage = croppedImage;
|
||||
log.info("裁切后图片上传成功: userArea={}, url={}", template.getUserArea(), finalImageUrl);
|
||||
} catch (Exception e) {
|
||||
log.error("图片裁切失败,使用原图: userArea={}", template.getUserArea(), e);
|
||||
}
|
||||
}
|
||||
// 上传图片到OSS
|
||||
String imageUrl = uploadImage(resultImage, template.getCode(), request.getOutputFormat(), request.getQuality());
|
||||
log.info("图片上传成功: url={}", imageUrl);
|
||||
|
||||
// 更新记录为成功
|
||||
long duration = System.currentTimeMillis() - startTime;
|
||||
long fileSize = estimateFileSize(finalImage, request.getOutputFormat());
|
||||
long fileSize = estimateFileSize(resultImage, request.getOutputFormat());
|
||||
recordMapper.updateSuccess(
|
||||
record.getId(),
|
||||
finalImageUrl,
|
||||
originalImageUrl,
|
||||
imageUrl,
|
||||
fileSize,
|
||||
finalImage.getWidth(),
|
||||
finalImage.getHeight(),
|
||||
resultImage.getWidth(),
|
||||
resultImage.getHeight(),
|
||||
(int) duration
|
||||
);
|
||||
|
||||
// 清除生成记录缓存(状态已更新)
|
||||
puzzleRepository.clearRecordCache(record.getId(), request.getFaceId());
|
||||
|
||||
log.info("拼图生成成功: recordId={}, originalUrl={}, finalUrl={}, duration={}ms",
|
||||
record.getId(), originalImageUrl, finalImageUrl, duration);
|
||||
log.info("拼图生成成功: recordId={}, imageUrl={}, duration={}ms",
|
||||
record.getId(), imageUrl, duration);
|
||||
|
||||
// 检查是否自动添加到打印队列
|
||||
if (template.getAutoAddPrint() != null && template.getAutoAddPrint() == 1) {
|
||||
@@ -501,7 +497,7 @@ public class PuzzleGenerateServiceImpl implements IPuzzleGenerateService {
|
||||
request.getUserId(),
|
||||
resolvedScenicId,
|
||||
request.getFaceId(),
|
||||
originalImageUrl,
|
||||
imageUrl,
|
||||
0L // 打印特有
|
||||
);
|
||||
log.info("自动添加到打印队列成功: recordId={}, printRecordId={}", record.getId(), printRecordId);
|
||||
@@ -511,10 +507,10 @@ public class PuzzleGenerateServiceImpl implements IPuzzleGenerateService {
|
||||
}
|
||||
|
||||
return PuzzleGenerateResponse.success(
|
||||
finalImageUrl,
|
||||
imageUrl,
|
||||
fileSize,
|
||||
finalImage.getWidth(),
|
||||
finalImage.getHeight(),
|
||||
resultImage.getWidth(),
|
||||
resultImage.getHeight(),
|
||||
(int) duration,
|
||||
record.getId(),
|
||||
false,
|
||||
@@ -761,43 +757,4 @@ public class PuzzleGenerateServiceImpl implements IPuzzleGenerateService {
|
||||
|
||||
return templateScenicId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 裁切图片
|
||||
* @param image 原图
|
||||
* @param userArea 裁切区域,格式:x,y,w,h
|
||||
* @return 裁切后的图片
|
||||
*/
|
||||
private BufferedImage cropImage(BufferedImage image, String userArea) {
|
||||
if (StrUtil.isBlank(userArea)) {
|
||||
return image;
|
||||
}
|
||||
|
||||
try {
|
||||
String[] parts = userArea.split(",");
|
||||
if (parts.length != 4) {
|
||||
throw new IllegalArgumentException("userArea格式错误,应为:x,y,w,h");
|
||||
}
|
||||
|
||||
int x = Integer.parseInt(parts[0].trim());
|
||||
int y = Integer.parseInt(parts[1].trim());
|
||||
int w = Integer.parseInt(parts[2].trim());
|
||||
int h = Integer.parseInt(parts[3].trim());
|
||||
|
||||
// 边界检查
|
||||
if (x < 0 || y < 0 || w <= 0 || h <= 0) {
|
||||
throw new IllegalArgumentException("裁切区域参数必须为正数");
|
||||
}
|
||||
|
||||
if (x + w > image.getWidth() || y + h > image.getHeight()) {
|
||||
throw new IllegalArgumentException("裁切区域超出图片边界");
|
||||
}
|
||||
|
||||
// 执行裁切
|
||||
return image.getSubimage(x, y, w, h);
|
||||
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("userArea格式错误,参数必须为数字", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user