741 lines
27 KiB
TypeScript
741 lines
27 KiB
TypeScript
import { isEmpty, join } from "lodash";
|
||
import { Book } from "../../../model/book";
|
||
import { checkStringValueAddPrefix, checkStringValueAddSuffix, errorMessage, successMessage } from "../../Public/generalTools";
|
||
import { BookBackTaskListService } from "../../../define/db/service/Book/bookBackTaskListService";
|
||
import { BookTaskDetailService } from "../../../define/db/service/Book/bookTaskDetailService";
|
||
import { CheckFolderExistsOrCreate, CopyFileOrFolder, JoinPath } from "../../../define/Tools/file";
|
||
import { define } from "../../../define/define"
|
||
import { GetImageBase64, ImageSplit } from "../../../define/Tools/image";
|
||
import MJApi from "./mjApi"
|
||
import { BookBackTaskStatus, BookBackTaskType, BookTaskStatus, BookType, DialogType, MJAction, OperateBookType, TaskExecuteType } from "../../../define/enum/bookEnum";
|
||
import { DEFINE_STRING } from "../../../define/define_string";
|
||
import { MJ } from "../../../model/mj";
|
||
import { MJRespoonseType } from "../../../define/enum/mjEnum";
|
||
import { MJSetting } from "../../../model/Setting/mjSetting";
|
||
import { GeneralResponse } from "../../../model/generalResponse"
|
||
import { LoggerStatus, ResponseMessageType } from "../../../define/enum/softwareEnum";
|
||
import { BookTaskService } from "../../../define/db/service/Book/bookTaskService";
|
||
import { ReverseBook } from "../Book/ReverseBook";
|
||
import { ImageStyle } from "../Book/imageStyle";
|
||
import { TaskScheduler } from "../taskScheduler";
|
||
import { BookService } from "../../../define/db/service/Book/bookService";
|
||
import { Tools } from "../../../main/tools"
|
||
import { MJSettingService } from "../../../define/db/service/SoftWare/mjSettingService";
|
||
import { BookServiceBasic } from "../ServiceBasic/bookServiceBasic";
|
||
|
||
import path from "path"
|
||
const { v4: uuidv4 } = require('uuid')
|
||
import fs from "fs"
|
||
const fspromise = fs.promises
|
||
|
||
export class MJOpt {
|
||
bookBackTaskList: BookBackTaskListService
|
||
bookTaskDetail: BookTaskDetailService
|
||
reverseBook: ReverseBook;
|
||
bookTaskService: BookTaskService
|
||
mjApi: MJApi;
|
||
mjSetting: MJSetting.MjSetting
|
||
imageStyle: ImageStyle;
|
||
taskScheduler: TaskScheduler;
|
||
bookService: BookService
|
||
tools: Tools;
|
||
mjSettingService: MJSettingService;
|
||
bookServiceBasic: BookServiceBasic
|
||
constructor() {
|
||
this.imageStyle = new ImageStyle()
|
||
this.taskScheduler = new TaskScheduler()
|
||
this.tools = new Tools()
|
||
this.bookServiceBasic = new BookServiceBasic();
|
||
}
|
||
async InitService() {
|
||
if (!this.reverseBook) {
|
||
this.reverseBook = new ReverseBook()
|
||
}
|
||
if (!this.bookBackTaskList) {
|
||
this.bookBackTaskList = await BookBackTaskListService.getInstance()
|
||
}
|
||
if (!this.bookTaskDetail) {
|
||
this.bookTaskDetail = await BookTaskDetailService.getInstance()
|
||
}
|
||
if (!this.mjApi) {
|
||
this.mjApi = new MJApi()
|
||
}
|
||
if (!this.bookTaskService) {
|
||
this.bookTaskService = await BookTaskService.getInstance()
|
||
}
|
||
if (!this.bookService) {
|
||
this.bookService = await BookService.getInstance()
|
||
}
|
||
if (!this.mjSettingService) {
|
||
this.mjSettingService = await MJSettingService.getInstance()
|
||
}
|
||
this.mjSetting = await this.mjApi.InitMJSetting()
|
||
}
|
||
/**
|
||
* 返回MJ的数据到前端界面,前端界面做出相应的改变
|
||
* @param {*} data
|
||
*/
|
||
sendChangeMessage(data: GeneralResponse.MessageResponse, message_name = DEFINE_STRING.BOOK.MAIN_DATA_RETURN) {
|
||
global.newWindow[0].win.webContents.send(message_name, data)
|
||
}
|
||
|
||
//#region 选择反推的提示词相关
|
||
|
||
/**
|
||
* MJ反推,将反推的数据写入到GPT中
|
||
* @param bookTaskDetailId
|
||
* @param index
|
||
*/
|
||
async SingleReverseToGptPrompt(bookTaskDetailId: string, index: number): Promise<GeneralResponse.ErrorItem | GeneralResponse.SuccessItem> {
|
||
try {
|
||
await this.InitService();
|
||
let bookTaskDetail = this.bookTaskDetail.GetBookTaskDetailDataById(bookTaskDetailId)
|
||
if (bookTaskDetail == null) {
|
||
throw new Error("没有找到对应的数据")
|
||
}
|
||
let reversePrompts = bookTaskDetail.reversePrompt
|
||
if (!reversePrompts || reversePrompts.length <= 0) {
|
||
throw new Error("没有找到对应的反推提示词数据")
|
||
}
|
||
let reversePrompt = reversePrompts[index]
|
||
let gptPrompt = reversePrompt.promptCN ? reversePrompt.promptCN : reversePrompt.prompt
|
||
// 开始修改
|
||
this.bookTaskDetail.UpdateBookTaskDetail(bookTaskDetailId, {
|
||
gptPrompt: gptPrompt
|
||
})
|
||
|
||
// 保存完毕
|
||
return successMessage(gptPrompt, "反推数据写出成功", "ReverseBook_ReversePromptToGptPrompt")
|
||
|
||
} catch (error) {
|
||
return errorMessage("反推数据写出失败,错误信息如下:" + error.message, "ReverseBook_ReversePromptToGptPrompt")
|
||
}
|
||
}
|
||
//#endregion
|
||
|
||
|
||
//#region MJ反推相关
|
||
/**
|
||
* 循环请求数据,判断反推任务是不是完成,返回数据
|
||
* @param task
|
||
* @param reqRes
|
||
*/
|
||
async fetchWithRetry(task: TaskModal.Task, reqRes: string) {
|
||
while (true) {
|
||
try {
|
||
// 执行你的操作
|
||
let task_res = await this.mjApi.GetMJAPITaskById(reqRes, task.id);
|
||
|
||
// 判断他的状态是不是成功
|
||
if (task_res.code == 0) {
|
||
// 反推失败
|
||
this.bookTaskDetail.UpdateBookTaskDetail(task.bookTaskDetailId, {
|
||
status: BookTaskStatus.REVERSE_FAIL
|
||
});
|
||
this.bookBackTaskList.UpdateTaskStatus({
|
||
id: task.id,
|
||
status: BookBackTaskStatus.FAIL,
|
||
errorMessage: task_res.message
|
||
});
|
||
throw new Error(`${task_res.message}`);
|
||
} else {
|
||
if (task_res.progress == 100) {
|
||
task_res.type == MJRespoonseType.FINISHED;
|
||
|
||
this.bookBackTaskList.UpdateTaskStatus({
|
||
id: task.id,
|
||
status: BookBackTaskStatus.DONE
|
||
});
|
||
|
||
// 这边还要再处理一下数据,将反推获取的数据进行切割处理
|
||
let reversePrompt = [];
|
||
if (task_res.prompt != undefined && task_res.prompt != "" && task_res.prompt != null) {
|
||
let string_res = task_res.prompt.split(/(?=\d️⃣)/).map(part => part.replace(/^\d️⃣\s*/, '').trim());
|
||
reversePrompt = string_res.map((item) => {
|
||
return {
|
||
id: uuidv4(),
|
||
bookTaskDetailId: task.bookTaskDetailId,
|
||
prompt: item,
|
||
promptCN: item,
|
||
isSelect: false
|
||
};
|
||
});
|
||
}
|
||
|
||
this.bookTaskDetail.UpdateBookTaskDetail(task.bookTaskDetailId, {
|
||
status: BookTaskStatus.REVERSE_DONE,
|
||
reversePrompt: reversePrompt,
|
||
gptPrompt: undefined
|
||
});
|
||
|
||
task_res.prompt = JSON.stringify(reversePrompt);
|
||
task_res.id = task.bookTaskDetailId;
|
||
this.sendChangeMessage({
|
||
code: 1,
|
||
type: ResponseMessageType.MJ_REVERSE,
|
||
id: task.bookTaskDetailId,
|
||
data: task_res
|
||
});
|
||
break;
|
||
} else {
|
||
// 当获取的图片的进度小于100的时候,等待5秒继续监听
|
||
await new Promise(resolve => setTimeout(resolve, 5000));
|
||
}
|
||
}
|
||
|
||
task_res.id = task.bookTaskDetailId;
|
||
this.sendChangeMessage({
|
||
code: 1,
|
||
type: ResponseMessageType.MJ_REVERSE,
|
||
id: task.bookTaskDetailId,
|
||
data: task_res
|
||
});
|
||
} catch (error) {
|
||
throw error;
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* MJ反推
|
||
* @param task
|
||
*/
|
||
async MJImage2Text(task: TaskModal.Task): Promise<GeneralResponse.SuccessItem | GeneralResponse.ErrorItem> {
|
||
try {
|
||
if (isEmpty(task.bookTaskDetailId)) {
|
||
throw new Error("MJ反推,没有找到对应的分镜信息")
|
||
}
|
||
await this.InitService()
|
||
|
||
let bookTaskDetail = this.bookTaskDetail.GetBookTaskDetailDataById(task.bookTaskDetailId);
|
||
|
||
let oldImagePath = bookTaskDetail.oldImage
|
||
if (isEmpty(oldImagePath)) {
|
||
throw new Error(`${bookTaskDetail.name} 没有需要反推的图片`);
|
||
}
|
||
oldImagePath = JoinPath(define.project_path, oldImagePath)
|
||
let imageBase64 = await GetImageBase64(oldImagePath)
|
||
// 这个就是任务ID
|
||
let reqRes = await this.mjApi.SubmitMJDescribe({
|
||
image: imageBase64,
|
||
taskId: task.id
|
||
})
|
||
if (reqRes == '23') {
|
||
// 任务队列过多,重新提交排队
|
||
this.bookBackTaskList.UpdateTaskStatus({
|
||
id: task.id,
|
||
status: BookBackTaskStatus.RECONNECT,
|
||
})
|
||
// throw new Error(`任务队列过多,${task.bookTaskDetailId} 重新提交排队`);
|
||
return;
|
||
}
|
||
|
||
this.bookTaskDetail.UpdateBookTaskDetail(task.bookTaskDetailId, {
|
||
status: BookTaskStatus.REVERSE
|
||
})
|
||
this.sendChangeMessage({
|
||
code: 1,
|
||
type: ResponseMessageType.MJ_REVERSE,
|
||
id: task.bookTaskDetailId,
|
||
data: {
|
||
code: 1,
|
||
type: MJRespoonseType.UPDATED,
|
||
mjType: MJAction.DESCRIBE,
|
||
category: this.mjSetting.type,
|
||
message_id: reqRes,
|
||
id: task.bookTaskDetailId,
|
||
progress: 0,
|
||
status: "success"
|
||
} as MJ.MJResponseToFront
|
||
})
|
||
|
||
await this.fetchWithRetry(task, reqRes);
|
||
} catch (error) {
|
||
console.log(error.toString())
|
||
let errorMsg = "MJ反推失败,失败信息如下:" + error.toString()
|
||
this.bookBackTaskList.UpdateTaskStatus({
|
||
id: task.id,
|
||
status: BookBackTaskStatus.FAIL,
|
||
errorMessage: errorMsg
|
||
})
|
||
this.sendChangeMessage({
|
||
code: 0,
|
||
id: task.bookTaskDetailId,
|
||
type: ResponseMessageType.MJ_REVERSE,
|
||
dialogType: DialogType.NOTIFICATION,
|
||
message: errorMsg,
|
||
data: {
|
||
code: 0,
|
||
type: MJRespoonseType.UPDATED,
|
||
mjType: MJAction.DESCRIBE,
|
||
category: this.mjSetting.type,
|
||
message_id: undefined,
|
||
id: task.bookTaskDetailId,
|
||
progress: 0,
|
||
message: error.toString(),
|
||
status: "failure"
|
||
}
|
||
})
|
||
return errorMessage(errorMsg, "MJReverse_MJImage2Text")
|
||
}
|
||
}
|
||
|
||
//#endregion
|
||
|
||
//#region 合并提示词相关
|
||
/**
|
||
* MJ 进行合并提示词,通过类型进行判断是单个还是全部合并
|
||
* @param id 合并的ID
|
||
* @param mergeType 合并的类型
|
||
*/
|
||
async MergePrompt(id: string, operateBookType: OperateBookType): Promise<GeneralResponse.ErrorItem | GeneralResponse.SuccessItem> {
|
||
try {
|
||
await this.InitService()
|
||
|
||
let bookTaskDetail = undefined as Book.SelectBookTaskDetail[];
|
||
let bookTask = undefined as Book.SelectBookTask;
|
||
|
||
if (operateBookType == OperateBookType.BOOKTASK) {
|
||
bookTaskDetail = this.bookTaskDetail.GetBookTaskData({
|
||
bookTaskId: id
|
||
}).data
|
||
bookTask = this.bookTaskService.GetBookTaskDataById(id);
|
||
// 判断是不是有为空的
|
||
let emptyName = [] as string[]
|
||
for (let i = 0; i < bookTaskDetail.length; i++) {
|
||
const element = bookTaskDetail[i];
|
||
if (isEmpty(element.gptPrompt)) {
|
||
emptyName.push(element.name)
|
||
}
|
||
}
|
||
if (emptyName.length > 0) {
|
||
throw new Error(`${emptyName.join(',')} 的提示词为空,请先推理`)
|
||
}
|
||
} else if (operateBookType == OperateBookType.BOOKTASKDETAIL) {
|
||
let tempBookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailDataById(id);
|
||
if (isEmpty(tempBookTaskDetail.gptPrompt)) {
|
||
throw new Error("当前分镜没有推理提示词,请先生成")
|
||
}
|
||
bookTaskDetail = [tempBookTaskDetail]
|
||
bookTask = this.bookTaskService.GetBookTaskDataById(bookTaskDetail[0].bookTaskId);
|
||
} else {
|
||
throw new Error("未知的合并类型")
|
||
}
|
||
|
||
// 获取合并的排序
|
||
let imageBaseSetting = JSON.parse(await fspromise.readFile(define.img_base, 'utf-8')); // 没有就直接报错
|
||
let promptSort = imageBaseSetting.prompt_sort; // 没有就直接报错
|
||
if (!promptSort) {
|
||
throw new Error("未找到提示词排序,请先设置")
|
||
}
|
||
|
||
// let suffixParam = imageBaseSetting.mj_config.image_suffix ; // 没有就直接报错
|
||
let mjSettingDb = this.mjSettingService.GetMjSetting({}).data
|
||
if (mjSettingDb.length <= 0) {
|
||
throw new Error("请先添加MJ配置")
|
||
}
|
||
let suffixParam = mjSettingDb[0].imageSuffix
|
||
|
||
// let styleString = '';
|
||
// 拿到所有的风格
|
||
let styleArr = await this.imageStyle.GetAllImageStyleList(bookTask.imageStyle, bookTask.customizeImageStyle);
|
||
let result = []
|
||
|
||
for (let i = 0; i < bookTaskDetail.length; i++) {
|
||
const element = bookTaskDetail[i];
|
||
let promptStr = '';
|
||
for (let i = 0; i < promptSort.length; i++) {
|
||
const element = promptSort[i];
|
||
promptStr += `${'${' + element.value + '}'} `
|
||
}
|
||
console.log(promptStr)
|
||
|
||
|
||
// TODO 后面需要完善人物和场景的提示词
|
||
let characterString = '' // 人物
|
||
let sceneString = "" // 场景
|
||
// 获取当前的自定义风格的垫图字符串
|
||
|
||
let styleString = ""
|
||
let style_url = ''
|
||
let sw = undefined
|
||
styleArr.forEach((item) => {
|
||
if (item.type && item.type == 'style_main') {
|
||
if (sw == undefined) {
|
||
sw = item.sref_sw
|
||
}
|
||
if (!isEmpty(item.image_url)) {
|
||
let url = item.image_url ? item.image_url : ''
|
||
style_url += ' ' + url
|
||
}
|
||
if (item.prompt) {
|
||
styleString += item.prompt + ','
|
||
}
|
||
} else {
|
||
styleString += item.english_style + ','
|
||
}
|
||
})
|
||
|
||
style_url = checkStringValueAddPrefix(style_url, '--sref ')
|
||
if (sw != undefined) {
|
||
style_url = checkStringValueAddSuffix(style_url, ` --sw ${sw}`)
|
||
}
|
||
let cref_url = ''
|
||
|
||
promptStr = promptStr.replace('${style}', styleString)
|
||
promptStr = promptStr.replace('${character}', characterString)
|
||
promptStr = promptStr.replace('${scene}', sceneString)
|
||
promptStr = promptStr.replace(
|
||
'${prompt}',
|
||
checkStringValueAddSuffix(element.gptPrompt, ',')
|
||
)
|
||
|
||
// 判断是不是需要加前后缀
|
||
if (bookTask.prefixPrompt) {
|
||
promptStr = checkStringValueAddSuffix(bookTask.prefixPrompt, ',') + promptStr
|
||
}
|
||
if (bookTask.prefixPrompt) {
|
||
promptStr = checkStringValueAddSuffix(promptStr, ',') + bookTask.prefixPrompt
|
||
}
|
||
promptStr = ' ' + promptStr;
|
||
promptStr += ` ${cref_url} ${style_url}${suffixParam}`
|
||
// 修改数据库数据
|
||
this.bookTaskDetail.UpdateBookTaskDetail(element.id, {
|
||
prompt: promptStr
|
||
})
|
||
// 写回数据
|
||
result.push({
|
||
id: element.id,
|
||
prompt: promptStr
|
||
})
|
||
}
|
||
return successMessage(result, "MJ模式合并数据成功", "MJOpt_MergePrompt")
|
||
|
||
} catch (error) {
|
||
return errorMessage("MJ合并提示词失败,错误信息如下:" + error.message, "MJOpt_MergePrompt")
|
||
}
|
||
}
|
||
//#endregion
|
||
|
||
|
||
//#region MJ生成图片相关
|
||
/**
|
||
* 单个生成图片,将任务添加到队列中
|
||
* @param id 要添加的ID
|
||
* @param operateBookType 操作的类型
|
||
*/
|
||
async AddMJGenerateImageTask(id: string, operateBookType: OperateBookType): Promise<GeneralResponse.ErrorItem | GeneralResponse.SuccessItem> {
|
||
try {
|
||
await this.InitService()
|
||
let bookTaskDetail = undefined as Book.SelectBookTaskDetail[];
|
||
// let bookTask = undefined as Book.SelectBookTask;
|
||
|
||
if (operateBookType == OperateBookType.BOOKTASK) {
|
||
bookTaskDetail = this.bookTaskDetail.GetBookTaskData({
|
||
bookTaskId: id
|
||
}).data
|
||
// bookTask = this.bookTaskService.GetBookTaskDataById(id);
|
||
} else if (operateBookType == OperateBookType.BOOKTASKDETAIL) {
|
||
bookTaskDetail = [this.bookTaskDetail.GetBookTaskDetailDataById(id)]
|
||
// bookTask = this.bookTaskService.GetBookTaskDataById(bookTaskDetail[0].bookTaskId);
|
||
} else if (operateBookType == OperateBookType.UNDERBOOKTASK) {
|
||
let thisBookTaskDetail = this.bookTaskDetail.GetBookTaskDetailDataById(id);
|
||
if (thisBookTaskDetail == null) {
|
||
throw new Error("没有找到对应的数据")
|
||
}
|
||
// 获取批次的所有数据
|
||
bookTaskDetail = this.bookTaskDetail.GetBookTaskData({
|
||
bookTaskId: thisBookTaskDetail.bookTaskId
|
||
}).data
|
||
// bookTask = this.bookTaskService.GetBookTaskDataById(thisBookTaskDetail.bookTaskId);
|
||
bookTaskDetail = bookTaskDetail.filter((item) => item.no >= thisBookTaskDetail.no) // 需要包含自己
|
||
}
|
||
else {
|
||
throw new Error("MJOpt_AddGenerateImageTask,未知的操作类型")
|
||
}
|
||
|
||
// 将被锁定的数据过滤掉
|
||
bookTaskDetail = bookTaskDetail.filter((item) => item.imageLock == false)
|
||
if (bookTaskDetail.length <= 0) {
|
||
throw new Error("没有找到可以生成图片的分镜,可能是已经被锁定")
|
||
}
|
||
|
||
// 将任务添加到队列中
|
||
for (let i = 0; i < bookTaskDetail.length; i++) {
|
||
const element = bookTaskDetail[i];
|
||
let taskRes = await this.bookBackTaskList.AddBookBackTask(element.bookId, BookBackTaskType.MJ_IMAGE, TaskExecuteType.AUTO, element.bookTaskId, element.id
|
||
);
|
||
if (taskRes.code == 0) {
|
||
throw new Error(taskRes.message)
|
||
}
|
||
// 添加返回日志
|
||
await this.taskScheduler.AddLogToDB(element.bookId, BookBackTaskType.MJ_IMAGE, `添加 ${element.name} MJ生成视频任务成功`, element.bookTaskId, LoggerStatus.SUCCESS)
|
||
}
|
||
// 全部完毕
|
||
return successMessage(null, "MJ添加生成图片任务成功", "MJOpt_AddGenerateImageTask")
|
||
} catch (error) {
|
||
return errorMessage("MJ添加生成图片任务失败,错误信息如下:" + error.message, "MJOpt_AddGenerateImageTask")
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 循环请求数据,判断反推任务是不是完成,返回数据
|
||
* @param task
|
||
* @param reqRes
|
||
*/
|
||
async FetchImageTask(task: TaskModal.Task, reqRes: string, book: Book.SelectBook, bookTask: Book.SelectBookTask, bookTaskDetail: Book.SelectBookTaskDetail) {
|
||
while (true) {
|
||
try {
|
||
// 执行你的操作
|
||
let task_res = await this.mjApi.GetMJAPITaskById(reqRes, task.id);
|
||
task_res.id = task.bookTaskDetailId;
|
||
// 判断他的状态是不是成功
|
||
if (task_res.code == 0) {
|
||
// 生图失败
|
||
this.bookTaskDetail.UpdateBookTaskDetail(task.bookTaskDetailId, {
|
||
status: BookTaskStatus.IMAGE_FAIL,
|
||
});
|
||
this.bookTaskDetail.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
|
||
mjApiUrl: this.mjApi.imagineUrl,
|
||
progress: 0,
|
||
category: this.mjApi.mjSetting.type,
|
||
imageClick: task_res.image_click,
|
||
imageShow: task_res.image_show,
|
||
messageId: task_res.message_id,
|
||
action: MJAction.IMAGINE,
|
||
status: 'error',
|
||
message: task_res.message
|
||
})
|
||
this.bookBackTaskList.UpdateTaskStatus({
|
||
id: task.id,
|
||
status: BookBackTaskStatus.FAIL,
|
||
errorMessage: task_res.message
|
||
});
|
||
this.sendChangeMessage({
|
||
code: 0,
|
||
type: ResponseMessageType.MJ_IMAGE,
|
||
id: task.bookTaskDetailId,
|
||
data: {
|
||
...task_res,
|
||
status: "error"
|
||
},
|
||
message: task_res.message
|
||
});
|
||
return;
|
||
// throw new Error(`${task_res.message}`);
|
||
} else {
|
||
if (task_res.progress == 100) {
|
||
task_res.type == MJRespoonseType.FINISHED;
|
||
console.log(task.id, "22222")
|
||
this.bookBackTaskList.UpdateTaskStatus({
|
||
id: task.id,
|
||
status: BookBackTaskStatus.DONE
|
||
});
|
||
// 下载图片
|
||
let imagePath = path.join(book.bookFolderPath, `data\\MJOriginalImage\\${task_res.message_id}.png`);
|
||
await CheckFolderExistsOrCreate(path.dirname(imagePath))
|
||
await this.tools.downloadFileUrl(task_res.image_click, imagePath)
|
||
|
||
// 进行图片裁剪
|
||
let imageRes = await ImageSplit(imagePath, bookTaskDetail.name, path.join(book.bookFolderPath, 'data\\MJOriginalImage'));
|
||
if (imageRes && imageRes.length < 4) {
|
||
throw new Error("图片裁剪失败")
|
||
}
|
||
|
||
// 修改数据库数据,将图片保存到对应的文件夹中
|
||
let firstImage = imageRes[0];
|
||
if (book.type == BookType.ORIGINAL) {
|
||
await CopyFileOrFolder(firstImage, path.join(book.bookFolderPath, `tmp\\input\\${bookTaskDetail.name}.png`));
|
||
}
|
||
let out_file = path.join(bookTask.imageFolder, `${bookTaskDetail.name}.png`)
|
||
await CopyFileOrFolder(firstImage, out_file);
|
||
task_res.outImagePath = firstImage;
|
||
task_res.subImagePath = imageRes;
|
||
|
||
task_res.id = task.bookTaskDetailId;
|
||
// 修改分镜的数据
|
||
this.bookTaskDetail.UpdateBookTaskDetail(task.bookTaskDetailId, {
|
||
outImagePath: path.relative(define.project_path, out_file),
|
||
subImagePath: imageRes.map((item) => path.relative(define.project_path, item))
|
||
})
|
||
this.bookTaskDetail.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
|
||
mjApiUrl: this.mjApi.imagineUrl,
|
||
progress: 100,
|
||
category: this.mjApi.mjSetting.type,
|
||
imageClick: task_res.image_click,
|
||
imageShow: task_res.image_show,
|
||
messageId: task_res.message_id,
|
||
action: MJAction.IMAGINE,
|
||
status: task_res.status,
|
||
})
|
||
this.sendChangeMessage({
|
||
code: 1,
|
||
type: ResponseMessageType.MJ_IMAGE,
|
||
id: task.bookTaskDetailId,
|
||
data: task_res
|
||
});
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 这边也要修改数据
|
||
task_res.id = task.bookTaskDetailId;
|
||
this.bookTaskDetail.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
|
||
mjApiUrl: this.mjApi.imagineUrl,
|
||
progress: task_res.progress,
|
||
category: this.mjApi.mjSetting.type,
|
||
imageClick: task_res.image_click,
|
||
imageShow: task_res.image_show,
|
||
messageId: task_res.message_id,
|
||
action: MJAction.IMAGINE,
|
||
status: task_res.status,
|
||
message: task_res.message
|
||
})
|
||
task_res.outImagePath = task_res.image_path;
|
||
|
||
this.sendChangeMessage({
|
||
code: 1,
|
||
type: ResponseMessageType.MJ_IMAGE,
|
||
id: task.bookTaskDetailId,
|
||
data: task_res
|
||
});
|
||
// 当获取的图片的进度小于100的时候,等待5秒继续监听
|
||
await new Promise(resolve => setTimeout(resolve, 5000));
|
||
} catch (error) {
|
||
throw error;
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* MJ生成图片
|
||
* @param task
|
||
*/
|
||
async MJImagine(task: TaskModal.Task): Promise<GeneralResponse.SuccessItem | GeneralResponse.ErrorItem> {
|
||
try {
|
||
if (isEmpty(task.bookTaskDetailId)) {
|
||
throw new Error("MJ出图,没有找到对应的分镜信息")
|
||
}
|
||
await this.InitService()
|
||
let bookTaskDetail = this.bookTaskDetail.GetBookTaskDetailDataById(task.bookTaskDetailId);
|
||
if (bookTaskDetail == null) {
|
||
throw new Error("没有找到对应的分镜信息")
|
||
}
|
||
let book = this.bookService.GetBookDataById(bookTaskDetail.bookId)
|
||
if (book == null) {
|
||
throw new Error("没有找到对应的小说信息")
|
||
}
|
||
let bookTask = this.bookTaskService.GetBookTaskDataById(bookTaskDetail.bookTaskId)
|
||
if (bookTask == null) {
|
||
throw new Error("没有找到对应的任务信息")
|
||
}
|
||
let prompt = bookTaskDetail.prompt
|
||
if (isEmpty(prompt)) {
|
||
throw new Error(`${bookTaskDetail.name} 没有找到对应的提示词`)
|
||
}
|
||
// 这个就是任务ID
|
||
let reqRes = await this.mjApi.SubmitMJImagineAPI(task.id, prompt)
|
||
if (reqRes == '23') {
|
||
console.log(task.id, "33333")
|
||
// 任务队列过多,重新提交排队
|
||
this.bookBackTaskList.UpdateTaskStatus({
|
||
id: task.id,
|
||
status: BookBackTaskStatus.RECONNECT,
|
||
})
|
||
this.sendChangeMessage({
|
||
code: 1,
|
||
type: ResponseMessageType.MJ_IMAGE,
|
||
id: task.bookTaskDetailId,
|
||
data: {
|
||
code: 1,
|
||
type: MJRespoonseType.UPDATED,
|
||
mjType: MJAction.IMAGINE,
|
||
category: this.mjSetting.type,
|
||
message_id: '',
|
||
id: task.bookTaskDetailId,
|
||
progress: 0,
|
||
status: "re_connect"
|
||
} as MJ.MJResponseToFront
|
||
})
|
||
this.bookTaskDetail.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
|
||
mjApiUrl: this.mjApi.imagineUrl,
|
||
progress: 0,
|
||
category: this.mjApi.mjSetting.type,
|
||
imageClick: "",
|
||
imageShow: "",
|
||
messageId: "",
|
||
action: MJAction.IMAGINE,
|
||
status: "re_connect",
|
||
})
|
||
// throw new Error(`任务队列过多,${task.bookTaskDetailId} 重新提交排队`);
|
||
return;
|
||
}
|
||
|
||
this.bookTaskDetail.UpdateBookTaskDetail(task.bookTaskDetailId, {
|
||
status: BookTaskStatus.IMAGE
|
||
})
|
||
this.bookBackTaskList.UpdateTaskStatus({
|
||
id: task.id,
|
||
status: BookBackTaskStatus.RUNNING
|
||
})
|
||
this.sendChangeMessage({
|
||
code: 1,
|
||
type: ResponseMessageType.MJ_IMAGE,
|
||
id: task.bookTaskDetailId,
|
||
data: {
|
||
code: 1,
|
||
type: MJRespoonseType.UPDATED,
|
||
mjType: MJAction.IMAGINE,
|
||
category: this.mjSetting.type,
|
||
message_id: reqRes,
|
||
id: task.bookTaskDetailId,
|
||
progress: 0,
|
||
status: "submited"
|
||
} as MJ.MJResponseToFront
|
||
})
|
||
await this.FetchImageTask(task, reqRes, book, bookTask, bookTaskDetail);
|
||
|
||
} catch (error) {
|
||
console.log(error.toString())
|
||
let errorMsg = "MJ生图失败,失败信息如下:" + error.toString()
|
||
console.log(task.id, "44444")
|
||
this.bookBackTaskList.UpdateTaskStatus({
|
||
id: task.id,
|
||
status: BookBackTaskStatus.FAIL,
|
||
errorMessage: errorMsg
|
||
})
|
||
this.sendChangeMessage({
|
||
code: 0,
|
||
id: task.bookTaskDetailId,
|
||
type: ResponseMessageType.MJ_IMAGE,
|
||
dialogType: DialogType.NOTIFICATION,
|
||
message: errorMsg,
|
||
data: {
|
||
code: 0,
|
||
type: MJRespoonseType.UPDATED,
|
||
mjType: MJAction.IMAGINE,
|
||
category: this.mjSetting.type,
|
||
message_id: undefined,
|
||
id: task.bookTaskDetailId,
|
||
progress: 0,
|
||
message: error.toString(),
|
||
status: "error"
|
||
}
|
||
})
|
||
this.bookTaskDetail.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
|
||
mjApiUrl: this.mjApi.imagineUrl,
|
||
progress: 0,
|
||
category: this.mjApi.mjSetting.type,
|
||
imageClick: "",
|
||
imageShow: "",
|
||
messageId: "",
|
||
action: MJAction.IMAGINE,
|
||
status: "error",
|
||
message: error.toString()
|
||
})
|
||
return errorMessage(errorMsg, "MJReverse_MJImage2Text")
|
||
}
|
||
}
|
||
|
||
//#endregion
|
||
} |