package com.xmzs.midjourney.service; import com.xmzs.midjourney.Constants; import com.xmzs.midjourney.ReturnCode; import com.xmzs.midjourney.enums.BlendDimensions; import com.xmzs.midjourney.loadbalancer.DiscordInstance; import com.xmzs.midjourney.loadbalancer.DiscordLoadBalancer; import com.xmzs.midjourney.result.Message; import com.xmzs.midjourney.result.SubmitResultVO; import com.xmzs.midjourney.support.Task; import com.xmzs.midjourney.util.MimeTypeUtils; import eu.maxschuster.dataurl.DataUrl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; @Slf4j @Service @RequiredArgsConstructor public class TaskServiceImpl implements TaskService { private final TaskStoreService taskStoreService; private final DiscordLoadBalancer discordLoadBalancer; @Override public SubmitResultVO submitImagine(Task task, List dataUrls) { DiscordInstance instance = this.discordLoadBalancer.chooseInstance(); if (instance == null) { return SubmitResultVO.fail(ReturnCode.NOT_FOUND, "无可用的账号实例"); } task.setProperty(Constants.TASK_PROPERTY_DISCORD_INSTANCE_ID, instance.getInstanceId()); return instance.submitTask(task, () -> { List imageUrls = new ArrayList<>(); for (DataUrl dataUrl : dataUrls) { String taskFileName = task.getId() + "." + MimeTypeUtils.guessFileSuffix(dataUrl.getMimeType()); Message uploadResult = instance.upload(taskFileName, dataUrl); if (uploadResult.getCode() != ReturnCode.SUCCESS) { return Message.of(uploadResult.getCode(), uploadResult.getDescription()); } String finalFileName = uploadResult.getResult(); Message sendImageResult = instance.sendImageMessage("upload image: " + finalFileName, finalFileName); if (sendImageResult.getCode() != ReturnCode.SUCCESS) { return Message.of(sendImageResult.getCode(), sendImageResult.getDescription()); } imageUrls.add(sendImageResult.getResult()); } if (!imageUrls.isEmpty()) { task.setPrompt(String.join(" ", imageUrls) + " " + task.getPrompt()); task.setPromptEn(String.join(" ", imageUrls) + " " + task.getPromptEn()); task.setDescription("/imagine " + task.getPrompt()); this.taskStoreService.save(task); } return instance.imagine(task.getPromptEn(), task.getPropertyGeneric(Constants.TASK_PROPERTY_NONCE)); }); } @Override public SubmitResultVO submitUpscale(Task task, String targetMessageId, String targetMessageHash, int index, int messageFlags) { String instanceId = task.getPropertyGeneric(Constants.TASK_PROPERTY_DISCORD_INSTANCE_ID); DiscordInstance discordInstance = this.discordLoadBalancer.getDiscordInstance(instanceId); if (discordInstance == null || !discordInstance.isAlive()) { return SubmitResultVO.fail(ReturnCode.NOT_FOUND, "账号不可用: " + instanceId); } return discordInstance.submitTask(task, () -> discordInstance.upscale(targetMessageId, index, targetMessageHash, messageFlags, task.getPropertyGeneric(Constants.TASK_PROPERTY_NONCE))); } @Override public SubmitResultVO submitVariation(Task task, String targetMessageId, String targetMessageHash, int index, int messageFlags) { String instanceId = task.getPropertyGeneric(Constants.TASK_PROPERTY_DISCORD_INSTANCE_ID); DiscordInstance discordInstance = this.discordLoadBalancer.getDiscordInstance(instanceId); if (discordInstance == null || !discordInstance.isAlive()) { return SubmitResultVO.fail(ReturnCode.NOT_FOUND, "账号不可用: " + instanceId); } return discordInstance.submitTask(task, () -> discordInstance.variation(targetMessageId, index, targetMessageHash, messageFlags, task.getPropertyGeneric(Constants.TASK_PROPERTY_NONCE))); } @Override public SubmitResultVO submitReroll(Task task, String targetMessageId, String targetMessageHash, int messageFlags) { String instanceId = task.getPropertyGeneric(Constants.TASK_PROPERTY_DISCORD_INSTANCE_ID); DiscordInstance discordInstance = this.discordLoadBalancer.getDiscordInstance(instanceId); if (discordInstance == null || !discordInstance.isAlive()) { return SubmitResultVO.fail(ReturnCode.NOT_FOUND, "账号不可用: " + instanceId); } return discordInstance.submitTask(task, () -> discordInstance.reroll(targetMessageId, targetMessageHash, messageFlags, task.getPropertyGeneric(Constants.TASK_PROPERTY_NONCE))); } @Override public SubmitResultVO submitDescribe(Task task, DataUrl dataUrl) { DiscordInstance discordInstance = this.discordLoadBalancer.chooseInstance(); if (discordInstance == null) { return SubmitResultVO.fail(ReturnCode.NOT_FOUND, "无可用的账号实例"); } task.setProperty(Constants.TASK_PROPERTY_DISCORD_INSTANCE_ID, discordInstance.getInstanceId()); return discordInstance.submitTask(task, () -> { String taskFileName = task.getId() + "." + MimeTypeUtils.guessFileSuffix(dataUrl.getMimeType()); Message uploadResult = discordInstance.upload(taskFileName, dataUrl); if (uploadResult.getCode() != ReturnCode.SUCCESS) { return Message.of(uploadResult.getCode(), uploadResult.getDescription()); } String finalFileName = uploadResult.getResult(); return discordInstance.describe(finalFileName, task.getPropertyGeneric(Constants.TASK_PROPERTY_NONCE)); }); } @Override public SubmitResultVO submitBlend(Task task, List dataUrls, BlendDimensions dimensions) { DiscordInstance discordInstance = this.discordLoadBalancer.chooseInstance(); if (discordInstance == null) { return SubmitResultVO.fail(ReturnCode.NOT_FOUND, "无可用的账号实例"); } task.setProperty(Constants.TASK_PROPERTY_DISCORD_INSTANCE_ID, discordInstance.getInstanceId()); return discordInstance.submitTask(task, () -> { List finalFileNames = new ArrayList<>(); for (DataUrl dataUrl : dataUrls) { String taskFileName = task.getId() + "." + MimeTypeUtils.guessFileSuffix(dataUrl.getMimeType()); Message uploadResult = discordInstance.upload(taskFileName, dataUrl); if (uploadResult.getCode() != ReturnCode.SUCCESS) { return Message.of(uploadResult.getCode(), uploadResult.getDescription()); } finalFileNames.add(uploadResult.getResult()); } return discordInstance.blend(finalFileNames, dimensions, task.getPropertyGeneric(Constants.TASK_PROPERTY_NONCE)); }); } }