Browse Source

修改回调保存内容方式

glx
glx 3 days ago
parent
commit
89b0e34eb0
  1. 1
      .gitignore
  2. 14
      src/main/java/com/youlai/boot/mini/controller/AiGenerationController.java
  3. 4
      src/main/java/com/youlai/boot/mini/model/entity/MiniAiGenerationTask.java
  4. 3
      src/main/java/com/youlai/boot/mini/model/form/AiFourPanelGenerateForm.java
  5. 3
      src/main/java/com/youlai/boot/mini/model/form/AiSingleImageGenerateForm.java
  6. 3
      src/main/java/com/youlai/boot/mini/model/form/AiVideoGenerateForm.java
  7. 162
      src/main/java/com/youlai/boot/mini/service/impl/AiGenerationServiceImpl.java

1
.gitignore

@ -17,3 +17,4 @@ docker/*/data/
docker/minio/config docker/minio/config
docker/xxljob/logs docker/xxljob/logs
application-youlai.yml application-youlai.yml
.claude

14
src/main/java/com/youlai/boot/mini/controller/AiGenerationController.java

@ -159,4 +159,18 @@ public class AiGenerationController {
aiGenerationService.setMiniProgramState(miniProgramState); aiGenerationService.setMiniProgramState(miniProgramState);
return Result.success(); return Result.success();
} }
//需要在三个回调接口中控制状态,更新其他状态; 更新状态时需要判断 当前状态已是成功或失败时不能再更新状态,当状态是失败时需要退还补偿积分;
// mini_point_rule积分规则表,每个回调回退的积分是对应的规则扣减积分的负数值;mini_point_record积分记录表;mini_point_account用户积分账户
// 当外部服务挂掉,不回调我的接口时,需要根据时间段判断,如果超过一定时间未回调,则更新状态为失败,并退还积分;
//TODO 现在 用户生成内容时,需要增加一个参数,同意或不同意公开生成的作品内容
//TODO mini 中增加 查询 用户公开生成作品的接口,考虑设计一下查询规则 满足平台前中后期运营需求
//TODO admin 中 后台管理中增加 查询用户生成任务历史的接口
//TODO admin 中 编辑用户生成作品历史接口
//TODO admin 中 增加 手动查询生成任务接口,手动跳转生成失败任务,或做个接口给用户手动刷新查看,需要注意状态流转,只有超时未完成任务可出现刷新按钮
} }

4
src/main/java/com/youlai/boot/mini/model/entity/MiniAiGenerationTask.java

@ -48,6 +48,10 @@ public class MiniAiGenerationTask implements Serializable {
@Schema(description = "任务状态:0=生成中 1=成功 2=失败 3=超时 4=已取消") @Schema(description = "任务状态:0=生成中 1=成功 2=失败 3=超时 4=已取消")
private Integer status; private Integer status;
@TableField("visibility")
@Schema(description = "可见范围:public-公开,private-仅自己可见,friends-好友可见")
private String visibility;
@TableField("result_resource_url") @TableField("result_resource_url")
@Schema(description = "生成结果资源URL") @Schema(description = "生成结果资源URL")
private String resultResourceUrl; private String resultResourceUrl;

3
src/main/java/com/youlai/boot/mini/model/form/AiFourPanelGenerateForm.java

@ -51,4 +51,7 @@ public class AiFourPanelGenerateForm {
@Schema(description = "故事梗概:AI会据此生成四格漫画脚本") @Schema(description = "故事梗概:AI会据此生成四格漫画脚本")
private String description; private String description;
@Schema(description = "可见范围: public公开 private仅自己", defaultValue = "private")
private String visibility;
} }

3
src/main/java/com/youlai/boot/mini/model/form/AiSingleImageGenerateForm.java

@ -51,4 +51,7 @@ public class AiSingleImageGenerateForm {
@Schema(description = "场景描述:用户自定义生成场景") @Schema(description = "场景描述:用户自定义生成场景")
private String description; private String description;
@Schema(description = "可见范围: public公开 private仅自己", defaultValue = "private")
private String visibility;
} }

3
src/main/java/com/youlai/boot/mini/model/form/AiVideoGenerateForm.java

@ -24,4 +24,7 @@ public class AiVideoGenerateForm {
@Schema(description = "视频时长,单位秒,最大15秒", defaultValue = "5") @Schema(description = "视频时长,单位秒,最大15秒", defaultValue = "5")
private Integer duration = 5; private Integer duration = 5;
@Schema(description = "可见范围: public公开 private仅自己", defaultValue = "private")
private String visibility;
} }

162
src/main/java/com/youlai/boot/mini/service/impl/AiGenerationServiceImpl.java

@ -75,6 +75,8 @@ public class AiGenerationServiceImpl implements AiGenerationService {
private static final String OSS_IMAGE_DIR = "ai/image/"; private static final String OSS_IMAGE_DIR = "ai/image/";
private static final String OSS_VIDEO_DIR = "ai/video/"; private static final String OSS_VIDEO_DIR = "ai/video/";
private static final String OSS_THUMBNAIL_DIR = "ai/thumbnail/"; private static final String OSS_THUMBNAIL_DIR = "ai/thumbnail/";
private static final String OSS_GENERATE_IMAGE_DIR = "ai/generate/image";
private static final String OSS_GENERATE_VIDEO_DIR = "ai/generate/video";
//AI单图生成服务地址 //AI单图生成服务地址
@Value("${ai.generate.single-image-server-url:http://127.0.0.1:8001/api/v1/photo-to-comic}") @Value("${ai.generate.single-image-server-url:http://127.0.0.1:8001/api/v1/photo-to-comic}")
@ -255,6 +257,7 @@ public class AiGenerationServiceImpl implements AiGenerationService {
MiniAiGenerationTask task = new MiniAiGenerationTask(); MiniAiGenerationTask task = new MiniAiGenerationTask();
task.setUuid(taskUuid) task.setUuid(taskUuid)
.setMiniUserId(userId) .setMiniUserId(userId)
.setVisibility(form.getVisibility())
.setType("img_single") // 单图 .setType("img_single") // 单图
.setGenerateParams(JSONUtil.toJsonStr(form)) .setGenerateParams(JSONUtil.toJsonStr(form))
.setPointsConsumed(Math.abs(deductPoint)) .setPointsConsumed(Math.abs(deductPoint))
@ -343,6 +346,7 @@ public class AiGenerationServiceImpl implements AiGenerationService {
MiniAiGenerationTask task = new MiniAiGenerationTask(); MiniAiGenerationTask task = new MiniAiGenerationTask();
task.setUuid(taskUuid) task.setUuid(taskUuid)
.setMiniUserId(userId) .setMiniUserId(userId)
.setVisibility(form.getVisibility())
.setType("img_grid_4") // 四宫格漫画 .setType("img_grid_4") // 四宫格漫画
.setGenerateParams(JSONUtil.toJsonStr(form)) .setGenerateParams(JSONUtil.toJsonStr(form))
.setPointsConsumed(Math.abs(deductPoint)) .setPointsConsumed(Math.abs(deductPoint))
@ -427,6 +431,7 @@ public class AiGenerationServiceImpl implements AiGenerationService {
// 创建生成任务 // 创建生成任务
MiniAiGenerationTask task = new MiniAiGenerationTask(); MiniAiGenerationTask task = new MiniAiGenerationTask();
task.setUuid(taskUuid) task.setUuid(taskUuid)
.setVisibility(form.getVisibility())
.setMiniUserId(userId) .setMiniUserId(userId)
.setType("video") .setType("video")
.setGenerateParams(JSONUtil.toJsonStr(form)) .setGenerateParams(JSONUtil.toJsonStr(form))
@ -440,7 +445,7 @@ public class AiGenerationServiceImpl implements AiGenerationService {
// 组装第三方接口参数 // 组装第三方接口参数
Map<String, Object> aiRequest = new HashMap<>(); Map<String, Object> aiRequest = new HashMap<>();
aiRequest.put("model", form.getModel() == null ? aiDefaultVideoModel : form.getModel());//TODO写到上面 aiRequest.put("model", form.getModel() == null ? aiDefaultVideoModel : form.getModel());
aiRequest.put("content", form.getContent()); aiRequest.put("content", form.getContent());
aiRequest.put("resolution", form.getResolution()); aiRequest.put("resolution", form.getResolution());
aiRequest.put("duration", form.getDuration()); aiRequest.put("duration", form.getDuration());
@ -524,12 +529,8 @@ public class AiGenerationServiceImpl implements AiGenerationService {
// 如果生成成功,下载外部视频到OSS // 如果生成成功,下载外部视频到OSS
if (status == 1 && vo.getContent() != null && vo.getContent().getVideoUrl() != null) { if (status == 1 && vo.getContent() != null && vo.getContent().getVideoUrl() != null) {
String externalVideoUrl = vo.getContent().getVideoUrl(); String externalVideoUrl = vo.getContent().getVideoUrl();
// 调用下载方法,存储到视频目录 String ossUrl = downloadExternalUrlToOss(externalVideoUrl, OSS_GENERATE_VIDEO_DIR);
String ossUrl = downloadExternalUrlToOss(externalVideoUrl, OSS_VIDEO_DIR);
task.setResultResourceUrl(ossUrl);
aiGenerationTaskMapper.updateById(task);
// 保存视频媒体记录
MiniAiTaskMedia media = new MiniAiTaskMedia(); MiniAiTaskMedia media = new MiniAiTaskMedia();
String mediaUuid = UUID.randomUUID().toString().replace("-", ""); String mediaUuid = UUID.randomUUID().toString().replace("-", "");
media.setUuid(mediaUuid) media.setUuid(mediaUuid)
@ -598,44 +599,41 @@ public class AiGenerationServiceImpl implements AiGenerationService {
task.setUpdateTimestamp(System.currentTimeMillis()); task.setUpdateTimestamp(System.currentTimeMillis());
aiGenerationTaskMapper.updateById(task); aiGenerationTaskMapper.updateById(task);
// 如果生成成功,下载外部URL到OSS // 如果生成成功,下载外部URL到OSS,存储所有结果图片
if (status == 1 && form.getResult() != null && !form.getResult().isEmpty()) { if (status == 1 && form.getResult() != null && !form.getResult().isEmpty()) {
String externalImageUrl = form.getResult().get(0).getUrl(); long now = System.currentTimeMillis();
// 调用下载方法,存储到图片目录
String ossUrl = downloadExternalUrlToOss(externalImageUrl); for (AiCallbackImage image : form.getResult()) {
task.setResultResourceUrl(ossUrl); String ossUrl = downloadExternalUrlToOss(image.getUrl(), OSS_GENERATE_IMAGE_DIR);
aiGenerationTaskMapper.updateById(task);
// 解析尺寸
// 保存生成的媒体记录 Integer width = null;
MiniAiTaskMedia media = new MiniAiTaskMedia(); Integer height = null;
String mediaUuid = UUID.randomUUID().toString().replace("-", ""); if (image.getSize() != null && image.getSize().contains("x")) {
AiCallbackImage image = form.getResult().get(0); String[] sizeArr = image.getSize().split("x");
// 解析尺寸 try {
Integer width = null; width = Integer.parseInt(sizeArr[0]);
Integer height = null; height = Integer.parseInt(sizeArr[1]);
if (image.getSize() != null && image.getSize().contains("x")) { } catch (Exception e) {
String[] sizeArr = image.getSize().split("x"); log.warn("解析四宫格图片尺寸失败,size:{}", image.getSize(), e);
try { }
width = Integer.parseInt(sizeArr[0]);
height = Integer.parseInt(sizeArr[1]);
} catch (Exception e) {
log.warn("解析四宫格图片尺寸失败,size:{}", image.getSize(), e);
} }
}
media.setUuid(mediaUuid) MiniAiTaskMedia media = new MiniAiTaskMedia();
.setTaskId(task.getId()) String mediaUuid = UUID.randomUUID().toString().replace("-", "");
.setMiniUserId(task.getMiniUserId()) media.setUuid(mediaUuid)
.setFileSource("ai_generate") .setTaskId(task.getId())
.setMediaType("image") .setMiniUserId(task.getMiniUserId())
.setSourceUrl(ossUrl) .setFileSource("ai_generate")
.setWidth(width) .setMediaType("image")
.setHeight(height) .setSourceUrl(ossUrl)
.setCreateBy(task.getCreateBy()) .setWidth(width)
.setCreateTimestamp(System.currentTimeMillis()) .setHeight(height)
.setCreateTime(new Date()); .setCreateBy(task.getCreateBy())
.setCreateTimestamp(now)
aiTaskMediaMapper.insert(media); .setCreateTime(new Date(now));
aiTaskMediaMapper.insert(media);
}
// 更新用户上传的参考文件:关联当前任务ID并软删除 // 更新用户上传的参考文件:关联当前任务ID并软删除
LambdaUpdateWrapper<MiniAiTaskMedia> updateMediaWrapper = new LambdaUpdateWrapper<>(); LambdaUpdateWrapper<MiniAiTaskMedia> updateMediaWrapper = new LambdaUpdateWrapper<>();
@ -662,6 +660,7 @@ public class AiGenerationServiceImpl implements AiGenerationService {
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public boolean handleTaskCallback(AiSingleImageCallbackForm form) { public boolean handleTaskCallback(AiSingleImageCallbackForm form) {
log.info("处理单图生成任务回调,任务UUID:{}", form.getUuid()); log.info("处理单图生成任务回调,任务UUID:{}", form.getUuid());
try { try {
@ -684,45 +683,45 @@ public class AiGenerationServiceImpl implements AiGenerationService {
return false; return false;
} }
// 如果生成成功,下载外部URL到OSS // 如果生成成功,下载外部URL到OSS,存储所有结果图片
String ossUrl = null;
if (status == 1 && form.getResult() != null && !form.getResult().isEmpty()) { if (status == 1 && form.getResult() != null && !form.getResult().isEmpty()) {
String externalResultUrl = form.getResult().get(0).getUrl(); long now = System.currentTimeMillis();
ossUrl = downloadExternalUrlToOss(externalResultUrl);
for (AiCallbackImage image : form.getResult()) {
// 保存生成的媒体记录 String ossUrl = downloadExternalUrlToOss(image.getUrl(), OSS_GENERATE_IMAGE_DIR);
MiniAiTaskMedia media = new MiniAiTaskMedia();
String mediaUuid = UUID.randomUUID().toString().replace("-", ""); // 解析尺寸
AiCallbackImage image = form.getResult().get(0); Integer width = null;
// 解析尺寸 Integer height = null;
Integer width = null; if (image.getSize() != null && image.getSize().contains("x")) {
Integer height = null; String[] sizeArr = image.getSize().split("x");
if (image.getSize() != null && image.getSize().contains("x")) { try {
String[] sizeArr = image.getSize().split("x"); width = Integer.parseInt(sizeArr[0]);
try { height = Integer.parseInt(sizeArr[1]);
width = Integer.parseInt(sizeArr[0]); } catch (Exception e) {
height = Integer.parseInt(sizeArr[1]); log.warn("解析单图图片尺寸失败,size:{}", image.getSize(), e);
} catch (Exception e) { }
log.warn("解析单图图片尺寸失败,size:{}", image.getSize(), e);
} }
}
media.setUuid(mediaUuid)
.setMiniUserId(task.getMiniUserId())
.setTaskId(task.getId())
.setFileSource("ai_generated")
.setMediaType("image")
.setSourceUrl(ossUrl)
.setWidth(width)
.setHeight(height)
.setCreateBy(task.getCreateBy())
.setCreateTime(new Date())
.setCreateTimestamp(System.currentTimeMillis())
.setUpdateTime(new Date())
.setUpdateTimestamp(System.currentTimeMillis())
.setDeleted(false);
aiTaskMediaMapper.insert(media); MiniAiTaskMedia media = new MiniAiTaskMedia();
String mediaUuid = UUID.randomUUID().toString().replace("-", "");
media.setUuid(mediaUuid)
.setMiniUserId(task.getMiniUserId())
.setTaskId(task.getId())
.setFileSource("ai_generated")
.setMediaType("image")
.setSourceUrl(ossUrl)
.setWidth(width)
.setHeight(height)
.setCreateBy(task.getCreateBy())
.setCreateTime(new Date(now))
.setCreateTimestamp(now)
.setUpdateTime(new Date(now))
.setUpdateTimestamp(now)
.setDeleted(false);
aiTaskMediaMapper.insert(media);
}
// 更新用户上传的参考文件:关联当前任务ID并软删除 // 更新用户上传的参考文件:关联当前任务ID并软删除
LambdaUpdateWrapper<MiniAiTaskMedia> updateMediaWrapper = new LambdaUpdateWrapper<>(); LambdaUpdateWrapper<MiniAiTaskMedia> updateMediaWrapper = new LambdaUpdateWrapper<>();
@ -741,7 +740,7 @@ public class AiGenerationServiceImpl implements AiGenerationService {
} }
// 更新任务状态 // 更新任务状态
return updateTaskStatus(taskUuid, status, ossUrl); return updateTaskStatus(taskUuid, status, null);
} catch (Exception e) { } catch (Exception e) {
log.error("处理AI任务回调异常,UUID:{},异常信息:{}", form.getUuid(), e.getMessage(), e); log.error("处理AI任务回调异常,UUID:{},异常信息:{}", form.getUuid(), e.getMessage(), e);
@ -795,13 +794,6 @@ public class AiGenerationServiceImpl implements AiGenerationService {
} }
} }
/**
* 下载外部URL到OSS返回OSS访问地址
*/
private String downloadExternalUrlToOss(String externalUrl) {
return downloadExternalUrlToOss(externalUrl, "ai/generate/");
}
/** /**
* 下载外部URL到指定OSS目录返回OSS访问地址 * 下载外部URL到指定OSS目录返回OSS访问地址
*/ */

Loading…
Cancel
Save