799 lines
30 KiB
TypeScript
Raw Normal View History

2024-09-12 14:13:09 +08:00
import { isEmpty } from "lodash";
2024-08-03 12:46:12 +08:00
import { Book } from "../../../model/book";
import { checkStringValueAddPrefix, checkStringValueAddSuffix, errorMessage, successMessage } from "../../Public/generalTools";
import { CheckFolderExistsOrCreate, CopyFileOrFolder, JoinPath } from "../../../define/Tools/file";
import { define } from "../../../define/define"
2024-09-04 19:49:20 +08:00
import { CompressImageToSize, GetImageBase64, ImageSplit } from "../../../define/Tools/image";
2024-08-03 12:46:12 +08:00
import MJApi from "./mjApi"
2024-08-18 16:22:19 +08:00
import { BookBackTaskStatus, BookBackTaskType, BookTaskStatus, BookType, DialogType, MJAction, OperateBookType, TaskExecuteType } from "../../../define/enum/bookEnum";
2024-08-03 12:46:12 +08:00
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 { ImageStyle } from "../Book/imageStyle";
import { LogScheduler } from "../task/logScheduler";
2024-08-03 12:46:12 +08:00
import { Tools } from "../../../main/tools"
2024-08-18 16:22:19 +08:00
import { BookServiceBasic } from "../ServiceBasic/bookServiceBasic";
2024-09-12 14:13:09 +08:00
import { PresetService } from "../presetService";
import { SoftWareServiceBasic } from "../ServiceBasic/softwareServiceBasic";
2024-08-03 12:46:12 +08:00
import path from "path"
const { v4: uuidv4 } = require('uuid')
import fs from "fs"
const fspromise = fs.promises
export class MJOpt {
mjApi: MJApi;
mjSetting: MJSetting.MjSetting
imageStyle: ImageStyle;
logScheduler: LogScheduler;
2024-08-03 12:46:12 +08:00
tools: Tools;
2024-08-18 16:22:19 +08:00
bookServiceBasic: BookServiceBasic
2024-09-12 14:13:09 +08:00
presetService: PresetService
softWareServiceBasic: SoftWareServiceBasic
2024-08-03 12:46:12 +08:00
constructor() {
this.imageStyle = new ImageStyle()
this.logScheduler = new LogScheduler()
2024-08-03 12:46:12 +08:00
this.tools = new Tools()
2024-08-18 16:22:19 +08:00
this.bookServiceBasic = new BookServiceBasic();
2024-09-12 14:13:09 +08:00
this.presetService = new PresetService()
this.mjApi = new MJApi()
this.softWareServiceBasic = new SoftWareServiceBasic()
2024-08-03 12:46:12 +08:00
}
2024-09-12 14:13:09 +08:00
/**
* MJ设置
*/
async GetMJSetting() {
if (!this.mjSetting) {
this.mjSetting = await this.softWareServiceBasic.GetMjSetting()
2024-08-03 12:46:12 +08:00
}
}
2024-09-12 14:13:09 +08:00
2024-08-03 12:46:12 +08:00
/**
* MJ的数据到前端界面
* @param {*} data
*/
2024-09-12 14:13:09 +08:00
sendChangeMessage(data: GeneralResponse.MessageResponse, message_name: string = DEFINE_STRING.BOOK.MAIN_DATA_RETURN) {
if (!message_name) {
message_name = DEFINE_STRING.BOOK.MAIN_DATA_RETURN
}
2024-08-03 12:46:12 +08:00
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 {
2024-09-12 14:13:09 +08:00
await this.GetMJSetting()
let bookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailDataById(bookTaskDetailId)
2024-08-03 12:46:12 +08:00
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
// 开始修改
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateBookTaskDetail(bookTaskDetailId, {
2024-08-03 12:46:12 +08:00
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) {
// 反推失败
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateBookTaskDetail(task.bookTaskDetailId, {
2024-08-03 12:46:12 +08:00
status: BookTaskStatus.REVERSE_FAIL
});
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateTaskStatus({
2024-08-03 12:46:12 +08:00
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;
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateTaskStatus({
2024-08-03 12:46:12 +08:00
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
};
});
}
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateBookTaskDetail(task.bookTaskDetailId, {
2024-08-03 12:46:12 +08:00
status: BookTaskStatus.REVERSE_DONE,
2024-08-18 16:22:19 +08:00
reversePrompt: reversePrompt,
gptPrompt: undefined
2024-08-03 12:46:12 +08:00
});
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
2024-09-12 14:13:09 +08:00
}, task.messageName);
2024-08-03 12:46:12 +08:00
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
2024-09-12 14:13:09 +08:00
}, task.messageName);
2024-08-03 12:46:12 +08:00
} 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反推没有找到对应的分镜信息")
}
2024-09-12 14:13:09 +08:00
await this.GetMJSetting()
let bookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailDataById(task.bookTaskDetailId);
2024-08-03 12:46:12 +08:00
let oldImagePath = bookTaskDetail.oldImage
if (isEmpty(oldImagePath)) {
throw new Error(`${bookTaskDetail.name} 没有需要反推的图片`);
}
oldImagePath = JoinPath(define.project_path, oldImagePath)
2024-09-04 19:49:20 +08:00
// let imageBase64 = await GetImageBase64(oldImagePath)
// 每次执行前压缩图片
let newImageBase64 = await CompressImageToSize(oldImagePath, 500000);
// 将buffer转换为base64
let imageBase64 = newImageBase64.toString('base64');
2024-08-03 12:46:12 +08:00
// 这个就是任务ID
let reqRes = await this.mjApi.SubmitMJDescribe({
2024-09-04 19:49:20 +08:00
image: 'data:image/png;base64,' + imageBase64,
2024-08-03 12:46:12 +08:00
taskId: task.id
})
if (reqRes == '23') {
// 任务队列过多,重新提交排队
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateTaskStatus({
2024-08-03 12:46:12 +08:00
id: task.id,
status: BookBackTaskStatus.RECONNECT,
})
// throw new Error(`任务队列过多,${task.bookTaskDetailId} 重新提交排队`);
return;
}
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateBookTaskDetail(task.bookTaskDetailId, {
2024-08-03 12:46:12 +08:00
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,
2024-09-12 14:13:09 +08:00
messageId: reqRes,
2024-08-03 12:46:12 +08:00
id: task.bookTaskDetailId,
progress: 0,
status: "success"
} as MJ.MJResponseToFront
2024-09-12 14:13:09 +08:00
}, task.messageName)
2024-08-03 12:46:12 +08:00
await this.fetchWithRetry(task, reqRes);
} catch (error) {
console.log(error.toString())
let errorMsg = "MJ反推失败失败信息如下" + error.toString()
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateTaskStatus({
2024-08-03 12:46:12 +08:00
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,
2024-09-12 14:13:09 +08:00
messageId: undefined,
2024-08-03 12:46:12 +08:00
id: task.bookTaskDetailId,
progress: 0,
message: error.toString(),
status: "failure"
}
2024-09-12 14:13:09 +08:00
}, task.messageName)
2024-08-03 12:46:12 +08:00
return errorMessage(errorMsg, "MJReverse_MJImage2Text")
}
}
//#endregion
//#region 合并提示词相关
2024-09-12 14:13:09 +08:00
/**
*
* @param ids IDs
* @returns
*/
async GetScenePresetStringByIds(ids: string[]): Promise<string> {
let sceneString = ''
for (let i = 0; i < ids.length; i++) {
const id = ids[i];
let scene = await this.presetService.GetScenePresetDetailById(id)
if (scene.code == 0) {
throw new Error(scene.message)
}
if (scene.data) {
2024-09-12 14:13:09 +08:00
// 这边开始拼接
sceneString += scene.data.prompt + ', '
}
}
return sceneString
}
/**
*
* @param ids IDs
* @returns
*/
async GetCharacterPresetStringByIds(ids: string[]): Promise<{ characterString: string, characterUrl: string }> {
let characterString = ''
let characterUrl = ''
let crefCw = undefined
for (let i = 0; i < ids.length; i++) {
const element = ids[i];
let character = await this.presetService.GetCharacterPresetDetailById(element)
if (character.code == 0) {
throw new Error(character.message)
}
if (character.data) {
2024-09-12 14:13:09 +08:00
characterString += character.data.prompt + ', '
if (character.data.image_url && character.data.image_url != '' && character.data.cref_cw) {
characterUrl += ` ${character.data.image_url} `
crefCw = character.data.cref_cw
}
}
}
//这边坐下合并s
if (characterUrl != '') {
characterUrl = ` --cref ${characterUrl} --cw ${crefCw}`
}
return { characterString, characterUrl }
}
2024-08-03 12:46:12 +08:00
/**
* MJ
* @param id ID
* @param mergeType
*/
2024-08-18 16:22:19 +08:00
async MergePrompt(id: string, operateBookType: OperateBookType): Promise<GeneralResponse.ErrorItem | GeneralResponse.SuccessItem> {
2024-08-03 12:46:12 +08:00
try {
let bookTaskDetail = undefined as Book.SelectBookTaskDetail[];
let bookTask = undefined as Book.SelectBookTask;
2024-09-12 14:13:09 +08:00
await this.GetMJSetting()
2024-08-18 16:22:19 +08:00
if (operateBookType == OperateBookType.BOOKTASK) {
2024-09-12 14:13:09 +08:00
bookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailData({
2024-08-03 12:46:12 +08:00
bookTaskId: id
2024-09-12 14:13:09 +08:00
})
bookTask = await this.bookServiceBasic.GetBookTaskDataById(id);
2024-08-18 16:22:19 +08:00
// 判断是不是有为空的
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) {
2024-08-21 11:47:05 +08:00
throw new Error(`${emptyName.join('')} 的提示词为空,请先推理`)
2024-08-18 16:22:19 +08:00
}
} else if (operateBookType == OperateBookType.BOOKTASKDETAIL) {
let tempBookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailDataById(id);
if (isEmpty(tempBookTaskDetail.gptPrompt)) {
throw new Error("当前分镜没有推理提示词,请先生成")
}
bookTaskDetail = [tempBookTaskDetail]
2024-09-12 14:13:09 +08:00
bookTask = await this.bookServiceBasic.GetBookTaskDataById(bookTaskDetail[0].bookTaskId);
2024-08-03 12:46:12 +08:00
} else {
throw new Error("未知的合并类型")
}
2024-09-12 14:13:09 +08:00
if (bookTaskDetail.length <= 0) {
throw new Error("没有找到对应的需要合并的分镜数据")
}
let book = await this.bookServiceBasic.GetBookDataById(bookTask.bookId);
2024-08-03 12:46:12 +08:00
// 获取合并的排序
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 ; // 没有就直接报错
2024-09-12 14:13:09 +08:00
let mjSettingDb = await this.softWareServiceBasic.GetMjSetting()
let suffixParam = mjSettingDb.imageSuffix
2024-08-03 12:46:12 +08:00
// 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];
2024-09-12 14:13:09 +08:00
// 没有推理提示词,直接跳过
if (isEmpty(element.gptPrompt)) {
continue;
}
2024-08-03 12:46:12 +08:00
let promptStr = '';
for (let i = 0; i < promptSort.length; i++) {
const element = promptSort[i];
promptStr += `${'${' + element.value + '}'} `
}
// TODO 后面需要完善人物和场景的提示词
let characterString = '' // 人物
2024-09-12 14:13:09 +08:00
let characterUrl = ''
2024-08-03 12:46:12 +08:00
let sceneString = "" // 场景
2024-08-03 12:46:12 +08:00
// 获取当前的自定义风格的垫图字符串
2024-09-12 14:13:09 +08:00
if (book.type == BookType.ORIGINAL) {
let sceneIds = element.sceneTags ? element.sceneTags : []
let characterIds = element.characterTags ? element.characterTags : []
if (sceneIds && sceneIds.length > 0) {
sceneString = await this.GetScenePresetStringByIds(sceneIds)
}
if (characterIds && characterIds.length > 0) {
let res = await this.GetCharacterPresetStringByIds(characterIds)
characterString = res.characterString
characterUrl = res.characterUrl
}
}
2024-08-03 12:46:12 +08:00
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
}
2024-09-04 19:49:20 +08:00
if (bookTask.suffixPrompt) {
promptStr = checkStringValueAddSuffix(promptStr, ',') + bookTask.suffixPrompt
2024-08-03 12:46:12 +08:00
}
promptStr = ' ' + promptStr;
2024-09-12 14:13:09 +08:00
promptStr += ` ${characterUrl} ${style_url}${suffixParam}`
2024-08-03 12:46:12 +08:00
// 修改数据库数据
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateBookTaskDetail(element.id, {
2024-08-03 12:46:12 +08:00
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
*/
2024-09-12 14:13:09 +08:00
async AddMJGenerateImageTask(id: string, operateBookType: OperateBookType, responseMessageName: string = null, coverData: boolean = true): Promise<GeneralResponse.ErrorItem | GeneralResponse.SuccessItem> {
2024-08-03 12:46:12 +08:00
try {
let bookTaskDetail = undefined as Book.SelectBookTaskDetail[];
// let bookTask = undefined as Book.SelectBookTask;
if (operateBookType == OperateBookType.BOOKTASK) {
2024-09-12 14:13:09 +08:00
bookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailData({
2024-08-03 12:46:12 +08:00
bookTaskId: id
2024-09-12 14:13:09 +08:00
})
if (!coverData) {
// 过滤掉已经生成的数据
bookTaskDetail = bookTaskDetail.filter((item) => !item.mjMessage)
}
2024-08-03 12:46:12 +08:00
// bookTask = this.bookTaskService.GetBookTaskDataById(id);
} else if (operateBookType == OperateBookType.BOOKTASKDETAIL) {
2024-09-12 14:13:09 +08:00
let bookTaskDetailRes = await this.bookServiceBasic.GetBookTaskDetailDataById(id)
bookTaskDetail = [bookTaskDetailRes]
2024-08-03 12:46:12 +08:00
// bookTask = this.bookTaskService.GetBookTaskDataById(bookTaskDetail[0].bookTaskId);
} else if (operateBookType == OperateBookType.UNDERBOOKTASK) {
2024-09-12 14:13:09 +08:00
let thisBookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailDataById(id);
2024-08-03 12:46:12 +08:00
if (thisBookTaskDetail == null) {
throw new Error("没有找到对应的数据")
}
// 获取批次的所有数据
2024-09-12 14:13:09 +08:00
bookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailData({
2024-08-03 12:46:12 +08:00
bookTaskId: thisBookTaskDetail.bookTaskId
2024-09-12 14:13:09 +08:00
})
2024-08-03 12:46:12 +08:00
// 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];
2024-09-12 14:13:09 +08:00
let taskRes = await this.bookServiceBasic.AddBookBackTask(element.bookId, BookBackTaskType.MJ_IMAGE, TaskExecuteType.AUTO, element.bookTaskId, element.id, responseMessageName
2024-08-03 12:46:12 +08:00
);
// 添加返回日志
await this.logScheduler.AddLogToDB(element.bookId, BookBackTaskType.MJ_IMAGE, `添加 ${element.name} MJ生成任务成功`, element.bookTaskId, LoggerStatus.SUCCESS)
2024-08-03 12:46:12 +08:00
}
// 全部完毕
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 {
2024-09-12 14:13:09 +08:00
await this.GetMJSetting()
2024-08-03 12:46:12 +08:00
// 执行你的操作
let task_res = await this.mjApi.GetMJAPITaskById(reqRes, task.id);
task_res.id = task.bookTaskDetailId;
// 判断他的状态是不是成功
if (task_res.code == 0) {
// 生图失败
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateBookTaskDetail(task.bookTaskDetailId, {
2024-08-03 12:46:12 +08:00
status: BookTaskStatus.IMAGE_FAIL,
});
2024-09-12 14:13:09 +08:00
let errorMsg = `MJ生成图片失败失败信息如下${task_res.message}`
await this.bookServiceBasic.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
2024-08-03 12:46:12 +08:00
mjApiUrl: this.mjApi.imagineUrl,
2024-09-12 14:13:09 +08:00
progress: 100,
2024-08-03 12:46:12 +08:00
category: this.mjApi.mjSetting.type,
2024-09-12 14:13:09 +08:00
imageClick: task_res.imageClick,
imageShow: task_res.imageShow,
messageId: task_res.messageId,
2024-08-03 12:46:12 +08:00
action: MJAction.IMAGINE,
status: 'error',
2024-09-12 14:13:09 +08:00
message: errorMsg
2024-08-03 12:46:12 +08:00
})
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateTaskStatus({
2024-08-03 12:46:12 +08:00
id: task.id,
status: BookBackTaskStatus.FAIL,
2024-09-12 14:13:09 +08:00
errorMessage: errorMsg
2024-08-03 12:46:12 +08:00
});
this.sendChangeMessage({
code: 0,
type: ResponseMessageType.MJ_IMAGE,
id: task.bookTaskDetailId,
data: {
...task_res,
2024-09-12 14:13:09 +08:00
status: "error",
message: errorMsg
2024-08-03 12:46:12 +08:00
},
2024-09-12 14:13:09 +08:00
message: errorMsg
}, task.messageName);
2024-08-03 12:46:12 +08:00
return;
// throw new Error(`${task_res.message}`);
} else {
if (task_res.progress == 100) {
task_res.type == MJRespoonseType.FINISHED;
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateTaskStatus({
2024-08-03 12:46:12 +08:00
id: task.id,
status: BookBackTaskStatus.DONE
});
// 下载图片
2024-09-12 14:13:09 +08:00
let imagePath = path.join(book.bookFolderPath, `data\\MJOriginalImage\\${task_res.messageId}.png`);
2024-08-03 12:46:12 +08:00
await CheckFolderExistsOrCreate(path.dirname(imagePath))
2024-09-12 14:13:09 +08:00
await this.tools.downloadFileUrl(task_res.imageClick, imagePath)
2024-08-03 12:46:12 +08:00
// 进行图片裁剪
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 && bookTask.name == "output_00001") {
2024-08-03 12:46:12 +08:00
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 = out_file;
2024-08-03 12:46:12 +08:00
task_res.subImagePath = imageRes;
task_res.id = task.bookTaskDetailId;
// 修改分镜的数据
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateBookTaskDetail(task.bookTaskDetailId, {
2024-08-03 12:46:12 +08:00
outImagePath: path.relative(define.project_path, out_file),
subImagePath: imageRes.map((item) => path.relative(define.project_path, item))
})
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
2024-08-03 12:46:12 +08:00
mjApiUrl: this.mjApi.imagineUrl,
progress: 100,
category: this.mjApi.mjSetting.type,
2024-09-12 14:13:09 +08:00
imageClick: task_res.imageClick,
imageShow: task_res.imageShow,
messageId: task_res.messageId,
2024-08-03 12:46:12 +08:00
action: MJAction.IMAGINE,
status: task_res.status,
})
this.sendChangeMessage({
code: 1,
type: ResponseMessageType.MJ_IMAGE,
id: task.bookTaskDetailId,
data: task_res
2024-09-12 14:13:09 +08:00
}, task.messageName);
2024-08-03 12:46:12 +08:00
break;
}
}
// 这边也要修改数据
task_res.id = task.bookTaskDetailId;
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
2024-08-03 12:46:12 +08:00
mjApiUrl: this.mjApi.imagineUrl,
progress: task_res.progress,
category: this.mjApi.mjSetting.type,
2024-09-12 14:13:09 +08:00
imageClick: task_res.imageClick,
imageShow: task_res.imageShow,
messageId: task_res.messageId,
2024-08-03 12:46:12 +08:00
action: MJAction.IMAGINE,
status: task_res.status,
message: task_res.message
})
2024-09-12 14:13:09 +08:00
task_res.outImagePath = task_res.imagePath;
2024-08-03 12:46:12 +08:00
this.sendChangeMessage({
code: 1,
type: ResponseMessageType.MJ_IMAGE,
id: task.bookTaskDetailId,
data: task_res
2024-09-12 14:13:09 +08:00
}, task.messageName);
2024-08-03 12:46:12 +08:00
// 当获取的图片的进度小于100的时候等待5秒继续监听
await new Promise(resolve => setTimeout(resolve, 9000));
2024-08-03 12:46:12 +08:00
} 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出图没有找到对应的分镜信息")
}
2024-09-12 14:13:09 +08:00
await this.GetMJSetting()
let bookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailDataById(task.bookTaskDetailId);
2024-08-03 12:46:12 +08:00
if (bookTaskDetail == null) {
throw new Error("没有找到对应的分镜信息")
}
2024-09-12 14:13:09 +08:00
let book = await this.bookServiceBasic.GetBookDataById(bookTaskDetail.bookId)
2024-08-03 12:46:12 +08:00
if (book == null) {
throw new Error("没有找到对应的小说信息")
}
2024-09-12 14:13:09 +08:00
let bookTask = await this.bookServiceBasic.GetBookTaskDataById(bookTaskDetail.bookTaskId)
2024-08-03 12:46:12 +08:00
if (bookTask == null) {
throw new Error("没有找到对应的任务信息")
}
let prompt = bookTaskDetail.prompt
if (isEmpty(prompt)) {
throw new Error(`${bookTaskDetail.name} 没有找到对应的提示词`)
}
// 这个就是任务ID
2024-09-12 14:13:09 +08:00
let reqRes = await this.mjApi.SubmitMJImagine(task.id, prompt)
2024-08-03 12:46:12 +08:00
if (reqRes == '23') {
console.log(task.id, "33333")
// 任务队列过多,重新提交排队
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateTaskStatus({
2024-08-03 12:46:12 +08:00
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
2024-09-12 14:13:09 +08:00
}, task.messageName)
await this.bookServiceBasic.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
2024-08-03 12:46:12 +08:00
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;
}
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateBookTaskDetail(task.bookTaskDetailId, {
2024-08-03 12:46:12 +08:00
status: BookTaskStatus.IMAGE
})
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateTaskStatus({
2024-08-03 12:46:12 +08:00
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
2024-09-12 14:13:09 +08:00
}, task.messageName)
2024-08-03 12:46:12 +08:00
await this.FetchImageTask(task, reqRes, book, bookTask, bookTaskDetail);
} catch (error) {
console.log(error.toString())
let errorMsg = "MJ生图失败失败信息如下" + error.toString()
2024-09-12 14:13:09 +08:00
await this.bookServiceBasic.UpdateTaskStatus({
2024-08-03 12:46:12 +08:00
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,
2024-09-12 14:13:09 +08:00
messageId: undefined,
2024-08-03 12:46:12 +08:00
id: task.bookTaskDetailId,
progress: 0,
2024-09-14 09:56:10 +08:00
message: errorMsg,
2024-08-03 12:46:12 +08:00
status: "error"
}
2024-09-12 14:13:09 +08:00
}, task.messageName)
await this.bookServiceBasic.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
2024-08-03 12:46:12 +08:00
mjApiUrl: this.mjApi.imagineUrl,
progress: 0,
category: this.mjApi.mjSetting.type,
imageClick: "",
imageShow: "",
messageId: "",
action: MJAction.IMAGINE,
status: "error",
2024-09-14 09:56:10 +08:00
message: errorMsg
2024-08-03 12:46:12 +08:00
})
return errorMessage(errorMsg, "MJReverse_MJImage2Text")
}
}
//#endregion
}