|
@@ -3,6 +3,7 @@ package com.yhlxj.service.midjourney.impl;
|
|
|
import cn.hutool.core.collection.CollectionUtil;
|
|
import cn.hutool.core.collection.CollectionUtil;
|
|
|
import cn.hutool.core.io.FileUtil;
|
|
import cn.hutool.core.io.FileUtil;
|
|
|
import cn.hutool.core.map.MapUtil;
|
|
import cn.hutool.core.map.MapUtil;
|
|
|
|
|
+import cn.hutool.core.util.URLUtil;
|
|
|
import cn.hutool.http.HttpRequest;
|
|
import cn.hutool.http.HttpRequest;
|
|
|
import cn.hutool.http.HttpUtil;
|
|
import cn.hutool.http.HttpUtil;
|
|
|
import cn.hutool.json.JSONArray;
|
|
import cn.hutool.json.JSONArray;
|
|
@@ -21,11 +22,13 @@ import com.yhlxj.dao.model.dto.MessageButton;
|
|
|
import com.yhlxj.dao.model.entity.MidjourneyAccount;
|
|
import com.yhlxj.dao.model.entity.MidjourneyAccount;
|
|
|
import com.yhlxj.dao.model.entity.MidjourneyUser;
|
|
import com.yhlxj.dao.model.entity.MidjourneyUser;
|
|
|
import com.yhlxj.dao.model.entity.MidjourneyUserConversation;
|
|
import com.yhlxj.dao.model.entity.MidjourneyUserConversation;
|
|
|
|
|
+import com.yhlxj.dao.model.enums.WsMessageTypeEnum;
|
|
|
import com.yhlxj.dao.model.response.SubmitResult;
|
|
import com.yhlxj.dao.model.response.SubmitResult;
|
|
|
import com.yhlxj.redis.RedisService;
|
|
import com.yhlxj.redis.RedisService;
|
|
|
import com.yhlxj.service.common.EnvCommonService;
|
|
import com.yhlxj.service.common.EnvCommonService;
|
|
|
import com.yhlxj.service.midjourney.MidjourneyAccountService;
|
|
import com.yhlxj.service.midjourney.MidjourneyAccountService;
|
|
|
import com.yhlxj.service.midjourney.MidjourneyService;
|
|
import com.yhlxj.service.midjourney.MidjourneyService;
|
|
|
|
|
+import com.yhlxj.web.wss.WssSession;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
@@ -34,6 +37,8 @@ import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
import javax.imageio.stream.FileImageOutputStream;
|
|
import javax.imageio.stream.FileImageOutputStream;
|
|
|
import java.io.*;
|
|
import java.io.*;
|
|
|
|
|
+import java.net.MalformedURLException;
|
|
|
|
|
+import java.net.URL;
|
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Files;
|
|
|
import java.nio.file.Path;
|
|
import java.nio.file.Path;
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
@@ -169,6 +174,52 @@ public class MidjourneyServiceImpl implements MidjourneyService {
|
|
|
return saveConversation(user.getId(), user.getMode(), result,"SHORTEN", StringUtils.EMPTY, botType);
|
|
return saveConversation(user.getId(), user.getMode(), result,"SHORTEN", StringUtils.EMPTY, botType);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public MidjourneyUserConversation submitSeed(MidjourneyUser user, Long taskId, String botType) throws Exception {
|
|
|
|
|
+ SubmitResult result = seed(user.getMode(),"seed", taskId);
|
|
|
|
|
+ return saveConversation(user.getId(), user.getMode(), result,"SEED", StringUtils.EMPTY, botType);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private SubmitResult seed(Integer mode, String seed, Long taskId) {
|
|
|
|
|
+ String url = "";
|
|
|
|
|
+ if (mode == 1) {
|
|
|
|
|
+ url = FAST_HOST;
|
|
|
|
|
+ } else if (mode == 2) {
|
|
|
|
|
+ url = RELAX_HOST;
|
|
|
|
|
+ }
|
|
|
|
|
+ url = url + String.format("/mj/task/%d/image-seed", taskId);
|
|
|
|
|
+ String body = HttpRequest.get(url).header("Authorization", FAST_TOKEN).execute().body();
|
|
|
|
|
+ log.info("seed body:{}", body);
|
|
|
|
|
+ SubmitResult submitResult = Jsons.parseObject(body, SubmitResult.class);
|
|
|
|
|
+ int code = submitResult.getCode();
|
|
|
|
|
+ if (code != 1 && code != 21 && code != 22) {
|
|
|
|
|
+ if (code == 3) {
|
|
|
|
|
+ if(mode == 2 && StringUtils.isNotBlank(accountWithMinUsage)){
|
|
|
|
|
+ redisService.hdel(RedisService.key.MIDJOURNEY_ACCOUNT.getName(),accountWithMinUsage);
|
|
|
|
|
+ String finalAccountWithMinUsage = accountWithMinUsage;
|
|
|
|
|
+ TASK_EXECUTOR.execute(() -> {
|
|
|
|
|
+ MidjourneyAccount account = midjourneyAccountService.getOne(Wrappers.lambdaQuery(MidjourneyAccount.class).eq(MidjourneyAccount::getInstanceId, finalAccountWithMinUsage).last("limit 1"));
|
|
|
|
|
+ midjourneyAccountService.updateStatus(account.getId());
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ throw BusinessRuntimeException.getInstance("账号不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (code == 4) {
|
|
|
|
|
+ throw BusinessRuntimeException.getInstance(submitResult.getDescription());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (code == 24) {
|
|
|
|
|
+ JSONObject jsonObject = JSONUtil.parseObj(submitResult.getResult());
|
|
|
|
|
+ throw BusinessRuntimeException.getInstance("prompt包含敏感词:"+jsonObject.getStr("bannedWord"));
|
|
|
|
|
+ }
|
|
|
|
|
+ log.error("action:" + action + " error message:" + submitResult.getDescription());
|
|
|
|
|
+ throw BusinessRuntimeException.getInstance("队列已满,请稍后尝试");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (StringUtils.isNotBlank(accountWithMinUsage) && mode == 2) {
|
|
|
|
|
+ submitResult.setInstanceId(Long.valueOf(accountWithMinUsage));
|
|
|
|
|
+ }
|
|
|
|
|
+ return submitResult;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 恢复次数
|
|
* 恢复次数
|
|
|
*/
|
|
*/
|
|
@@ -387,6 +438,18 @@ public class MidjourneyServiceImpl implements MidjourneyService {
|
|
|
return list;
|
|
return list;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public MidjourneyUserConversation getConversationById(Long id){
|
|
|
|
|
+
|
|
|
|
|
+ //从缓存中查询 该任务是否存在
|
|
|
|
|
+ MidjourneyUserConversation conversation = (MidjourneyUserConversation)redisService.get(RedisService.key.MIDJOURNEY_CONVERSATION.getName() + id);
|
|
|
|
|
+ if(conversation == null){
|
|
|
|
|
+ conversation = conversationMapper.selectById(id);
|
|
|
|
|
+ redisService.set(RedisService.key.MIDJOURNEY_CONVERSATION.getName() + id, conversation, RedisService.key.MIDJOURNEY_CONVERSATION.getTimeout());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return conversation;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
public void sync(MidjourneyUserConversation conversation) throws IOException {
|
|
public void sync(MidjourneyUserConversation conversation) throws IOException {
|
|
|
if ((StringUtils.isNotBlank(conversation.getProgress()) && progress.contains(conversation.getProgress())) || status.contains(conversation.getStatus())) {
|
|
if ((StringUtils.isNotBlank(conversation.getProgress()) && progress.contains(conversation.getProgress())) || status.contains(conversation.getStatus())) {
|
|
@@ -513,16 +576,30 @@ public class MidjourneyServiceImpl implements MidjourneyService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public void notifyHook(String json) {
|
|
|
|
|
|
|
+ public void notifyHook(String json) throws MalformedURLException {
|
|
|
log.info("notifyHook:{}", json);
|
|
log.info("notifyHook:{}", json);
|
|
|
JSONObject jsons = JSONUtil.parseObj(json);
|
|
JSONObject jsons = JSONUtil.parseObj(json);
|
|
|
MidjourneyUserConversation conversation = JSONUtil.toBean(jsons, MidjourneyUserConversation.class);
|
|
MidjourneyUserConversation conversation = JSONUtil.toBean(jsons, MidjourneyUserConversation.class);
|
|
|
conversation.setUserId(jsons.getLong("state"));
|
|
conversation.setUserId(jsons.getLong("state"));
|
|
|
conversation.setTaskId(jsons.getLong("id"));
|
|
conversation.setTaskId(jsons.getLong("id"));
|
|
|
if (StringUtil.isNotBlank(conversation.getImageUrl())) {
|
|
if (StringUtil.isNotBlank(conversation.getImageUrl())) {
|
|
|
- conversation.setImageUrl(conversation.getImageUrl().replace("cdn.discordapp.com", "mj.galaxydvd.com"));
|
|
|
|
|
|
|
+ URL url = new URL(conversation.getImageUrl());
|
|
|
|
|
+
|
|
|
|
|
+ // 使用 Hutool 提取各个部分并构建新 URL
|
|
|
|
|
+ String newUrl = URLUtil.toURI(new URL(url.getProtocol(), "cdn.mj.liuliangbang.vip", url.getPort(), url.getFile()) + "?" + url.getQuery()).toString();
|
|
|
|
|
+ //
|
|
|
|
|
+ conversation.setImageUrl(newUrl);
|
|
|
}
|
|
}
|
|
|
redisService.set(RedisService.key.MIDJOURNEY_CONVERSATION.getName() + conversation.getTaskId(), conversation,RedisService.key.MIDJOURNEY_CONVERSATION.getTimeout());
|
|
redisService.set(RedisService.key.MIDJOURNEY_CONVERSATION.getName() + conversation.getTaskId(), conversation,RedisService.key.MIDJOURNEY_CONVERSATION.getTimeout());
|
|
|
|
|
+
|
|
|
|
|
+ TASK_EXECUTOR.execute(()->{
|
|
|
|
|
+ //WebSocket 直接发送 任务状态
|
|
|
|
|
+ WssSession wssSession = (WssSession) redisService.hget(RedisService.key.MIDJOURNEY_WS_SESSION.getName(), conversation.getTaskId().toString());
|
|
|
|
|
+ if (wssSession != null) {
|
|
|
|
|
+ wssSession.sendMessage(WsMessageTypeEnum.SERVER_TASK_INFO, conversation);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
TASK_EXECUTOR.execute(() -> {
|
|
TASK_EXECUTOR.execute(() -> {
|
|
|
try {
|
|
try {
|
|
|
sync(conversation);
|
|
sync(conversation);
|