Compare commits
2 Commits
b0eb7795e4
...
03d3ff7e9d
| Author | SHA1 | Date | |
|---|---|---|---|
| 03d3ff7e9d | |||
| 6cf1e7df5b |
2
package-lock.json
generated
2
package-lock.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "laitool",
|
"name": "laitool",
|
||||||
"version": "3.2.3",
|
"version": "3.2.4",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "laitool",
|
"name": "laitool",
|
||||||
"version": "3.2.3",
|
"version": "3.2.4",
|
||||||
"description": "An AI tool for image processing, video processing, and other functions.",
|
"description": "An AI tool for image processing, video processing, and other functions.",
|
||||||
"main": "./out/main/index.js",
|
"main": "./out/main/index.js",
|
||||||
"author": "laitool.cn",
|
"author": "laitool.cn",
|
||||||
@ -92,7 +92,12 @@
|
|||||||
"resources/tmp/**",
|
"resources/tmp/**",
|
||||||
"resources/icon.ico"
|
"resources/icon.ico"
|
||||||
],
|
],
|
||||||
|
"nsis": {
|
||||||
|
"oneClick": false,
|
||||||
|
"allowToChangeInstallationDirectory": true
|
||||||
|
},
|
||||||
"win": {
|
"win": {
|
||||||
|
"target": "nsis",
|
||||||
"icon": "./resources/icon.ico"
|
"icon": "./resources/icon.ico"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -12,7 +12,22 @@ let apiUrl = [
|
|||||||
d3_url: {
|
d3_url: {
|
||||||
image: 'https://api.laitool.cc/v1/images/generations'
|
image: 'https://api.laitool.cc/v1/images/generations'
|
||||||
},
|
},
|
||||||
buy_url: 'https://api.laitool.cc/register?aff=Zmdu'
|
buy_url: 'https://api.laitool.cc/login'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'LAI API - 美国',
|
||||||
|
value: '2b443f53-ba12-42b3-a57c-e4df92685c73',
|
||||||
|
gpt_url: 'https://laitool.net/v1/chat/completions',
|
||||||
|
mj_url: {
|
||||||
|
imagine: 'https://laitool.net/mj/submit/imagine',
|
||||||
|
describe: 'https://laitool.net/mj/submit/describe',
|
||||||
|
update_file: 'https://laitool.net/mj/submit/upload-discord-images',
|
||||||
|
once_get_task: 'https://laitool.net/mj/task/${id}/fetch'
|
||||||
|
},
|
||||||
|
d3_url: {
|
||||||
|
image: 'https://laitool.net/v1/images/generations'
|
||||||
|
},
|
||||||
|
buy_url: 'https://laitool.net/login'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'openai-hk',
|
label: 'openai-hk',
|
||||||
@ -60,7 +60,7 @@ export class BookTaskModel extends Realm.Object<BookTaskModel> {
|
|||||||
status: BookTaskStatus
|
status: BookTaskStatus
|
||||||
errorMsg: string | null
|
errorMsg: string | null
|
||||||
isAuto: boolean // 是否自动
|
isAuto: boolean // 是否自动
|
||||||
openVideoGenerate: boolean // 是否开启视频生成
|
openVideoGenerate: boolean | null // 是否开启视频生成
|
||||||
updateTime: Date
|
updateTime: Date
|
||||||
createTime: Date
|
createTime: Date
|
||||||
imageCategory: BookImageCategory // 图片出图方式
|
imageCategory: BookImageCategory // 图片出图方式
|
||||||
@ -90,7 +90,7 @@ export class BookTaskModel extends Realm.Object<BookTaskModel> {
|
|||||||
prefixPrompt: "string?",
|
prefixPrompt: "string?",
|
||||||
suffixPrompt: "string?",
|
suffixPrompt: "string?",
|
||||||
status: 'string',
|
status: 'string',
|
||||||
openVideoGenerate: 'bool',
|
openVideoGenerate: 'bool?',
|
||||||
errorMsg: 'string?',
|
errorMsg: 'string?',
|
||||||
isAuto: 'bool',
|
isAuto: 'bool',
|
||||||
updateTime: 'date',
|
updateTime: 'date',
|
||||||
|
|||||||
@ -291,7 +291,7 @@ export class BaseRealmService extends BaseService {
|
|||||||
VideoMessage
|
VideoMessage
|
||||||
],
|
],
|
||||||
path: this.dbpath,
|
path: this.dbpath,
|
||||||
schemaVersion: 37,
|
schemaVersion: 39,
|
||||||
migration: migration
|
migration: migration
|
||||||
}
|
}
|
||||||
this.realm = await Realm.open(config)
|
this.realm = await Realm.open(config)
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
const path = require('path')
|
|
||||||
const { app } = require('electron')
|
|
||||||
let define = {}
|
let define = {}
|
||||||
if (!app.isPackaged) {
|
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined'
|
||||||
|
|
||||||
|
if (!isBrowser) {
|
||||||
|
const path = require('path')
|
||||||
|
const { app } = require('electron')
|
||||||
|
if (!app.isPackaged) {
|
||||||
define = {
|
define = {
|
||||||
discordScript: path.join(__dirname, '../../src/main/discord/discordScript.js'),
|
discordScript: path.join(__dirname, '../../src/main/discord/discordScript.js'),
|
||||||
zhanwei_image: path.join(__dirname, '../../resources/image/zhanwei.png'),
|
zhanwei_image: path.join(__dirname, '../../resources/image/zhanwei.png'),
|
||||||
@ -71,7 +74,7 @@ if (!app.isPackaged) {
|
|||||||
),
|
),
|
||||||
add_keyframe_tmp_path: path.join(__dirname, '../../resources/tmp/Clip/keyframe_tmp.json')
|
add_keyframe_tmp_path: path.join(__dirname, '../../resources/tmp/Clip/keyframe_tmp.json')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
define = {
|
define = {
|
||||||
zhanwei_image: path.join(__dirname, '../../../resources/image/zhanwei.png'),
|
zhanwei_image: path.join(__dirname, '../../../resources/image/zhanwei.png'),
|
||||||
config_path: path.join(__dirname, '../../../resources/config/global_setting.json'),
|
config_path: path.join(__dirname, '../../../resources/config/global_setting.json'),
|
||||||
@ -141,6 +144,7 @@ if (!app.isPackaged) {
|
|||||||
),
|
),
|
||||||
add_keyframe_tmp_path: path.join(__dirname, '../../../resources/tmp/Clip/keyframe_tmp.json')
|
add_keyframe_tmp_path: path.join(__dirname, '../../../resources/tmp/Clip/keyframe_tmp.json')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
define['remotemj_api'] = 'https://api.laitool.net/'
|
define['remotemj_api'] = 'https://api.laitool.net/'
|
||||||
@ -155,4 +159,5 @@ define['API'] = 'f85d39ed5a40fd09966f13f12b6cf0f0'
|
|||||||
|
|
||||||
define['lms'] = 'https://lms.laitool.cn'
|
define['lms'] = 'https://lms.laitool.cn'
|
||||||
|
|
||||||
|
|
||||||
export { define }
|
export { define }
|
||||||
|
|||||||
@ -1,15 +1,4 @@
|
|||||||
|
|
||||||
/**
|
|
||||||
* Flux 调用API时候的 生图模型
|
|
||||||
*/
|
|
||||||
export enum FLxuAPIImageType {
|
|
||||||
FLUX = "flux",
|
|
||||||
FLUX_PRO = "flux-pro",
|
|
||||||
FLUX_DEV = "flux-dev",
|
|
||||||
FLUX_SCHNELL = "flux-schnell",
|
|
||||||
FLUX_PRO_MAX = "flux-pro-max"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export enum PresetType {
|
export enum PresetType {
|
||||||
// 角色
|
// 角色
|
||||||
|
|||||||
@ -35,10 +35,10 @@ export enum MJRobotType {
|
|||||||
|
|
||||||
export enum MJSpeed {
|
export enum MJSpeed {
|
||||||
// 快速
|
// 快速
|
||||||
FAST = 'fast',
|
FAST = 'FAST',
|
||||||
|
|
||||||
// 休闲
|
// 休闲
|
||||||
RELAX = 'relaxed'
|
RELAX = 'RELAXED'
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum MJRespoonseType {
|
export enum MJRespoonseType {
|
||||||
|
|||||||
@ -36,5 +36,25 @@ export enum OptionKeyName {
|
|||||||
*/
|
*/
|
||||||
TTS_GlobalSetting = 'TTS_GlobalSetting',
|
TTS_GlobalSetting = 'TTS_GlobalSetting',
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
|
||||||
|
//#region MJ
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MJ 基础设置
|
||||||
|
*/
|
||||||
|
MJ_GlobalSetting = 'MJ_GlobalSetting',
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region FLUX
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FLUX API 模型列表
|
||||||
|
*/
|
||||||
|
FLUX_APIModelList = 'FLUX_APIModelList',
|
||||||
|
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
}
|
}
|
||||||
25
src/define/response/ForwardResponse.ts
Normal file
25
src/define/response/ForwardResponse.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { ValidateJson } from "../Tools/validate";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取转发请求的数据,序列化后返回
|
||||||
|
* @param response
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function GetForwardResponseData(response: any) {
|
||||||
|
if (response.status != 200) {
|
||||||
|
throw new Error("转发请求失败")
|
||||||
|
}
|
||||||
|
if (response.data.code != 1) {
|
||||||
|
throw new Error(response.data.message)
|
||||||
|
}
|
||||||
|
if (!ValidateJson(response.data.data)) {
|
||||||
|
throw new Error(response.data.data)
|
||||||
|
}
|
||||||
|
return JSON.parse(response.data.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
let ForwardResponse = {
|
||||||
|
GetForwardResponseData,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ForwardResponse;
|
||||||
@ -60,7 +60,6 @@ function MjIpc() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 获取MJ生图的方式
|
// 获取MJ生图的方式
|
||||||
// GetMJGenerateCategory: async (callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_MJ_GENERATE_CATEGORY)),
|
|
||||||
ipcMain.handle(
|
ipcMain.handle(
|
||||||
DEFINE_STRING.MJ.GET_MJ_GENERATE_CATEGORY,
|
DEFINE_STRING.MJ.GET_MJ_GENERATE_CATEGORY,
|
||||||
async (event) => await mjSimple.GetMJGenerateCategory()
|
async (event) => await mjSimple.GetMJGenerateCategory()
|
||||||
|
|||||||
@ -10,7 +10,7 @@ function OptionsIpc() {
|
|||||||
*/
|
*/
|
||||||
ipcMain.handle(
|
ipcMain.handle(
|
||||||
DEFINE_STRING.OPTIONS.GET_OPTION_BY_KEY,
|
DEFINE_STRING.OPTIONS.GET_OPTION_BY_KEY,
|
||||||
async (_, key: string) => await OptionHandle.GetOptionByKey(key)
|
async (_, key: string | string[]) => await OptionHandle.GetOptionByKey(key)
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import { DEFINE_STRING } from '../../define/define_string'
|
|||||||
import { define } from '../../define/define'
|
import { define } from '../../define/define'
|
||||||
let fspromises = require('fs').promises
|
let fspromises = require('fs').promises
|
||||||
import { gptDefine } from '../../define/gptDefine'
|
import { gptDefine } from '../../define/gptDefine'
|
||||||
import { apiUrl } from '../../define/api/apiUrlDefine'
|
|
||||||
import { successMessage } from '../Public/generalTools'
|
import { successMessage } from '../Public/generalTools'
|
||||||
import { RetryWithBackoff } from '../../define/Tools/common'
|
import { RetryWithBackoff } from '../../define/Tools/common'
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,8 @@ import { Base64ToFile, GetImageBase64 } from '../../../define/Tools/image';
|
|||||||
import { BookBackTaskStatus } from '../../../define/enum/bookEnum';
|
import { BookBackTaskStatus } from '../../../define/enum/bookEnum';
|
||||||
import { MJAction, MJImageType } from '../../../define/enum/mjEnum';
|
import { MJAction, MJImageType } from '../../../define/enum/mjEnum';
|
||||||
import { GptService } from '../GPT/gpt';
|
import { GptService } from '../GPT/gpt';
|
||||||
|
import { TaskModal } from '@/model/task';
|
||||||
|
import { ValidateJson } from '@/define/Tools/validate';
|
||||||
|
|
||||||
export class FluxOpt {
|
export class FluxOpt {
|
||||||
gptService: GptService
|
gptService: GptService
|
||||||
@ -203,18 +205,55 @@ export class FluxOpt {
|
|||||||
* @param body 请求的请求体
|
* @param body 请求的请求体
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async FluxAPIImageRequest(url: string, key: string, body: { model: string; prompt: string; size: string; }): Promise<string> {
|
async FluxAPIImageRequest(url: string, key: string, body: { model: string; prompt: string; size: string; }, useTransfer: boolean): Promise<string> {
|
||||||
let response = await axios.post(url, { ...body, n: 1 }, {
|
|
||||||
|
let data = {
|
||||||
|
...body,
|
||||||
|
n: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
let resData: any = [];
|
||||||
|
|
||||||
|
if (useTransfer) {
|
||||||
|
let transferUrl = define.lms + "/lms/Forward/SimpleTransfer";
|
||||||
|
let transferConfig = {
|
||||||
|
method: 'post',
|
||||||
|
url: transferUrl,
|
||||||
|
maxBodyLength: Infinity,
|
||||||
|
timeout: 600000, // 600 seconds timeout
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data: JSON.stringify({
|
||||||
|
url: url,
|
||||||
|
apiKey: key,
|
||||||
|
dataString: JSON.stringify(data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let response = await axios(transferConfig)
|
||||||
|
if (response.status != 200) {
|
||||||
|
throw new Error("转发请求失败")
|
||||||
|
}
|
||||||
|
if (response.data.code != 1) {
|
||||||
|
throw new Error(response.data.message)
|
||||||
|
}
|
||||||
|
if (!ValidateJson(response.data.data)) {
|
||||||
|
throw new Error(response.data.data)
|
||||||
|
}
|
||||||
|
let re = JSON.parse(response.data.data);
|
||||||
|
resData = re.data
|
||||||
|
} else {
|
||||||
|
let response = await axios.post(url, data, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: 'Bearer ' + key
|
Authorization: 'Bearer ' + key
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
resData = response.data.data
|
||||||
if (response.data && response.data.data && response.data.data.length > 0) {
|
|
||||||
return response.data.data[0].url
|
|
||||||
} else {
|
|
||||||
return undefined
|
|
||||||
}
|
}
|
||||||
|
if (!Array.isArray(resData) || resData.length == 0) {
|
||||||
|
throw new Error("FLUX API 返回数据异常")
|
||||||
|
}
|
||||||
|
return resData[0].url
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -239,7 +278,11 @@ export class FluxOpt {
|
|||||||
prompt = sdSetting.webui.prompt + ', ' + prompt
|
prompt = sdSetting.webui.prompt + ', ' + prompt
|
||||||
}
|
}
|
||||||
let size = `${sdSetting.webui.width}x${sdSetting.webui.height}`
|
let size = `${sdSetting.webui.width}x${sdSetting.webui.height}`
|
||||||
|
if (!sdSetting.flux.model) {
|
||||||
|
throw new Error('FLUX API 模型为空,请先设置!')
|
||||||
|
}
|
||||||
let model = sdSetting.flux.model
|
let model = sdSetting.flux.model
|
||||||
|
let useTransfer = sdSetting.flux.useTransfer
|
||||||
// 一次请求生成一张 多个请求
|
// 一次请求生成一张 多个请求
|
||||||
|
|
||||||
let SdOriginalImage = path.join(book.bookFolderPath, 'data/SdOriginalImage');
|
let SdOriginalImage = path.join(book.bookFolderPath, 'data/SdOriginalImage');
|
||||||
@ -259,7 +302,7 @@ export class FluxOpt {
|
|||||||
model: model,
|
model: model,
|
||||||
prompt: prompt,
|
prompt: prompt,
|
||||||
size: size
|
size: size
|
||||||
})
|
}, useTransfer)
|
||||||
// 这边开始处理返回的数据
|
// 这边开始处理返回的数据
|
||||||
if (isEmpty(imageUrl)) {
|
if (isEmpty(imageUrl)) {
|
||||||
throw new Error('FLUX 生图返回的图片地址为空')
|
throw new Error('FLUX 生图返回的图片地址为空')
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import { BookBackTaskStatus, BookBackTaskType, BookTaskStatus, BookType, DialogT
|
|||||||
import { DEFINE_STRING } from "../../../define/define_string";
|
import { DEFINE_STRING } from "../../../define/define_string";
|
||||||
import { MJ } from "../../../model/mj";
|
import { MJ } from "../../../model/mj";
|
||||||
import { MJRespoonseType } from "../../../define/enum/mjEnum";
|
import { MJRespoonseType } from "../../../define/enum/mjEnum";
|
||||||
import { MJSetting } from "../../../model/Setting/mjSetting";
|
import { MJSettingModel } from "../../../model/Setting/mjSetting";
|
||||||
import { GeneralResponse } from "../../../model/generalResponse"
|
import { GeneralResponse } from "../../../model/generalResponse"
|
||||||
import { LoggerStatus, ResponseMessageType } from "../../../define/enum/softwareEnum";
|
import { LoggerStatus, ResponseMessageType } from "../../../define/enum/softwareEnum";
|
||||||
import { ImageStyle } from "../Book/imageStyle";
|
import { ImageStyle } from "../Book/imageStyle";
|
||||||
@ -27,7 +27,7 @@ const fspromise = fs.promises
|
|||||||
|
|
||||||
export class MJOpt {
|
export class MJOpt {
|
||||||
mjApi: MJApi;
|
mjApi: MJApi;
|
||||||
mjSetting: MJSetting.MjSetting
|
mjSimpleSetting: MJSettingModel.MjSimpleSettingModel;
|
||||||
imageStyle: ImageStyle;
|
imageStyle: ImageStyle;
|
||||||
logScheduler: LogScheduler;
|
logScheduler: LogScheduler;
|
||||||
tools: Tools;
|
tools: Tools;
|
||||||
@ -48,8 +48,8 @@ export class MJOpt {
|
|||||||
* 获取MJ设置
|
* 获取MJ设置
|
||||||
*/
|
*/
|
||||||
async GetMJSetting() {
|
async GetMJSetting() {
|
||||||
if (!this.mjSetting) {
|
if (!this.mjSimpleSetting) {
|
||||||
this.mjSetting = await this.softWareServiceBasic.GetMjSetting()
|
this.mjSimpleSetting = await this.softWareServiceBasic.GetMjSetting()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +231,7 @@ export class MJOpt {
|
|||||||
code: 1,
|
code: 1,
|
||||||
type: MJRespoonseType.UPDATED,
|
type: MJRespoonseType.UPDATED,
|
||||||
mjType: MJAction.DESCRIBE,
|
mjType: MJAction.DESCRIBE,
|
||||||
category: this.mjSetting.type,
|
category: this.mjSimpleSetting.type,
|
||||||
messageId: reqRes,
|
messageId: reqRes,
|
||||||
id: task.bookTaskDetailId,
|
id: task.bookTaskDetailId,
|
||||||
progress: 0,
|
progress: 0,
|
||||||
@ -258,7 +258,7 @@ export class MJOpt {
|
|||||||
code: 0,
|
code: 0,
|
||||||
type: MJRespoonseType.UPDATED,
|
type: MJRespoonseType.UPDATED,
|
||||||
mjType: MJAction.DESCRIBE,
|
mjType: MJAction.DESCRIBE,
|
||||||
category: this.mjSetting.type,
|
category: this.mjSimpleSetting.type,
|
||||||
messageId: undefined,
|
messageId: undefined,
|
||||||
id: task.bookTaskDetailId,
|
id: task.bookTaskDetailId,
|
||||||
progress: 0,
|
progress: 0,
|
||||||
@ -560,7 +560,7 @@ export class MJOpt {
|
|||||||
await this.bookServiceBasic.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
|
await this.bookServiceBasic.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
|
||||||
mjApiUrl: this.mjApi.imagineUrl,
|
mjApiUrl: this.mjApi.imagineUrl,
|
||||||
progress: 100,
|
progress: 100,
|
||||||
category: this.mjApi.mjSetting.type,
|
category: this.mjApi.mjSimpleSetting.type,
|
||||||
imageClick: task_res.imageClick,
|
imageClick: task_res.imageClick,
|
||||||
imageShow: task_res.imageShow,
|
imageShow: task_res.imageShow,
|
||||||
messageId: task_res.messageId,
|
messageId: task_res.messageId,
|
||||||
@ -622,7 +622,7 @@ export class MJOpt {
|
|||||||
await this.bookServiceBasic.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
|
await this.bookServiceBasic.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
|
||||||
mjApiUrl: this.mjApi.imagineUrl,
|
mjApiUrl: this.mjApi.imagineUrl,
|
||||||
progress: 100,
|
progress: 100,
|
||||||
category: this.mjApi.mjSetting.type,
|
category: this.mjApi.mjSimpleSetting.type,
|
||||||
imageClick: task_res.imageClick,
|
imageClick: task_res.imageClick,
|
||||||
imageShow: task_res.imageShow,
|
imageShow: task_res.imageShow,
|
||||||
messageId: task_res.messageId,
|
messageId: task_res.messageId,
|
||||||
@ -644,7 +644,7 @@ export class MJOpt {
|
|||||||
await this.bookServiceBasic.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
|
await this.bookServiceBasic.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
|
||||||
mjApiUrl: this.mjApi.imagineUrl,
|
mjApiUrl: this.mjApi.imagineUrl,
|
||||||
progress: task_res.progress,
|
progress: task_res.progress,
|
||||||
category: this.mjApi.mjSetting.type,
|
category: this.mjApi.mjSimpleSetting.type,
|
||||||
imageClick: task_res.imageClick,
|
imageClick: task_res.imageClick,
|
||||||
imageShow: task_res.imageShow,
|
imageShow: task_res.imageShow,
|
||||||
messageId: task_res.messageId,
|
messageId: task_res.messageId,
|
||||||
@ -697,7 +697,6 @@ export class MJOpt {
|
|||||||
// 这个就是任务ID
|
// 这个就是任务ID
|
||||||
let reqRes = await this.mjApi.SubmitMJImagine(task.id, prompt)
|
let reqRes = await this.mjApi.SubmitMJImagine(task.id, prompt)
|
||||||
if (reqRes == '23') {
|
if (reqRes == '23') {
|
||||||
console.log(task.id, "33333")
|
|
||||||
// 任务队列过多,重新提交排队
|
// 任务队列过多,重新提交排队
|
||||||
await this.bookServiceBasic.UpdateTaskStatus({
|
await this.bookServiceBasic.UpdateTaskStatus({
|
||||||
id: task.id,
|
id: task.id,
|
||||||
@ -711,7 +710,7 @@ export class MJOpt {
|
|||||||
code: 1,
|
code: 1,
|
||||||
type: MJRespoonseType.UPDATED,
|
type: MJRespoonseType.UPDATED,
|
||||||
mjType: MJAction.IMAGINE,
|
mjType: MJAction.IMAGINE,
|
||||||
category: this.mjSetting.type,
|
category: this.mjSimpleSetting.type,
|
||||||
message_id: '',
|
message_id: '',
|
||||||
id: task.bookTaskDetailId,
|
id: task.bookTaskDetailId,
|
||||||
progress: 0,
|
progress: 0,
|
||||||
@ -721,7 +720,7 @@ export class MJOpt {
|
|||||||
await this.bookServiceBasic.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
|
await this.bookServiceBasic.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
|
||||||
mjApiUrl: this.mjApi.imagineUrl,
|
mjApiUrl: this.mjApi.imagineUrl,
|
||||||
progress: 0,
|
progress: 0,
|
||||||
category: this.mjApi.mjSetting.type,
|
category: this.mjApi.mjSimpleSetting.type,
|
||||||
imageClick: "",
|
imageClick: "",
|
||||||
imageShow: "",
|
imageShow: "",
|
||||||
messageId: "",
|
messageId: "",
|
||||||
@ -747,7 +746,7 @@ export class MJOpt {
|
|||||||
code: 1,
|
code: 1,
|
||||||
type: MJRespoonseType.UPDATED,
|
type: MJRespoonseType.UPDATED,
|
||||||
mjType: MJAction.IMAGINE,
|
mjType: MJAction.IMAGINE,
|
||||||
category: this.mjSetting.type,
|
category: this.mjSimpleSetting.type,
|
||||||
message_id: reqRes,
|
message_id: reqRes,
|
||||||
id: task.bookTaskDetailId,
|
id: task.bookTaskDetailId,
|
||||||
progress: 0,
|
progress: 0,
|
||||||
@ -773,7 +772,7 @@ export class MJOpt {
|
|||||||
code: 0,
|
code: 0,
|
||||||
type: MJRespoonseType.UPDATED,
|
type: MJRespoonseType.UPDATED,
|
||||||
mjType: MJAction.IMAGINE,
|
mjType: MJAction.IMAGINE,
|
||||||
category: this.mjSetting.type,
|
category: this.mjSimpleSetting.type,
|
||||||
messageId: undefined,
|
messageId: undefined,
|
||||||
id: task.bookTaskDetailId,
|
id: task.bookTaskDetailId,
|
||||||
progress: 0,
|
progress: 0,
|
||||||
@ -784,7 +783,7 @@ export class MJOpt {
|
|||||||
await this.bookServiceBasic.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
|
await this.bookServiceBasic.UpdateBookTaskDetailMjMessage(task.bookTaskDetailId, {
|
||||||
mjApiUrl: this.mjApi.imagineUrl,
|
mjApiUrl: this.mjApi.imagineUrl,
|
||||||
progress: 0,
|
progress: 0,
|
||||||
category: this.mjApi.mjSetting.type,
|
category: this.mjApi.mjSimpleSetting.type,
|
||||||
imageClick: "",
|
imageClick: "",
|
||||||
imageShow: "",
|
imageShow: "",
|
||||||
messageId: "",
|
messageId: "",
|
||||||
|
|||||||
@ -1,65 +1,83 @@
|
|||||||
import axios from "axios"
|
import axios from "axios"
|
||||||
import { define } from "../../../define/define"
|
import { define } from "../../../define/define"
|
||||||
import { GetImageBase64 } from "../../../define/Tools/image"
|
import { MJImageType, MJRespoonseType, MJRobotType, MJSpeed } from "../../../define/enum/mjEnum"
|
||||||
import { MJImageType, MJRespoonseType, MJSpeed } from "../../../define/enum/mjEnum"
|
|
||||||
import { MJSettingService } from "../../../define/db/service/SoftWare/mjSettingService"
|
import { MJSettingService } from "../../../define/db/service/SoftWare/mjSettingService"
|
||||||
import { BookBackTaskListService } from "../../../define/db/service/Book/bookBackTaskListService"
|
import { BookBackTaskListService } from "../../../define/db/service/Book/bookBackTaskListService"
|
||||||
import { BookBackTaskStatus } from "../../../define/enum/bookEnum"
|
import { BookBackTaskStatus } from "../../../define/enum/bookEnum"
|
||||||
import { MJSetting } from "../../../model/Setting/mjSetting"
|
import { MJSettingModel } from "../../../model/Setting/mjSetting"
|
||||||
import { GPT } from "../../Public/GPT"
|
|
||||||
import { MJ } from "../../../model/mj"
|
import { MJ } from "../../../model/mj"
|
||||||
import { LaiAPIType } from "../../../define/enum/softwareEnum"
|
|
||||||
import { isEmpty } from "lodash"
|
import { isEmpty } from "lodash"
|
||||||
|
import { OptionServices } from "../Options/optionServices"
|
||||||
|
import { OptionKeyName } from "@/define/enum/option"
|
||||||
|
import { ValidateJson } from "@/define/Tools/validate"
|
||||||
|
import { apiUrl } from "@/define/api/apiUrlDefine"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 调用MJ的API类
|
* 调用MJ的API类
|
||||||
*/
|
*/
|
||||||
class MJApi {
|
class MJApi {
|
||||||
mjSetting: MJSetting.MjSetting
|
mjSimpleSetting: MJSettingModel.MjSimpleSettingModel
|
||||||
bootType: string
|
bootType: string
|
||||||
imagineUrl: string
|
imagineUrl: string
|
||||||
fetchTaskUrl: string
|
fetchTaskUrl: string
|
||||||
describeUrl: string
|
describeUrl: string
|
||||||
|
|
||||||
|
optionServices: OptionServices
|
||||||
|
|
||||||
|
mj_globalSetting: MJSettingModel.MJ_GlobalSettingModel
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.bootType = "MID_JOURNEY"
|
this.bootType = "MID_JOURNEY"
|
||||||
|
this.optionServices = new OptionServices()
|
||||||
}
|
}
|
||||||
|
|
||||||
async InitMJSetting(): Promise<MJSetting.MjSetting> {
|
/**
|
||||||
|
* 初始化MJ设置
|
||||||
|
*/
|
||||||
|
async InitMJSetting(): Promise<void> {
|
||||||
// 获取MJ配置,从数据库中
|
// 获取MJ配置,从数据库中
|
||||||
let _mjSettingService = await MJSettingService.getInstance()
|
let _mjSettingService = await MJSettingService.getInstance()
|
||||||
let mjSettings = _mjSettingService.GetMJSettingTreeData()
|
let mjSettings = _mjSettingService.GetMJSettingTreeData()
|
||||||
if (mjSettings.code == 0) {
|
if (mjSettings.code == 0) {
|
||||||
throw new Error(mjSettings.message)
|
throw new Error(mjSettings.message)
|
||||||
}
|
}
|
||||||
this.mjSetting = mjSettings.data
|
|
||||||
this.bootType = this.mjSetting.selectRobot == "niji" ? "NIJI_JOURNEY" : "MID_JOURNEY"
|
|
||||||
if (this.mjSetting.type == MJImageType.REMOTE_MJ) {
|
let mjSettingData = await this.optionServices.GetOptionByKey(OptionKeyName.MJ_GlobalSetting);
|
||||||
|
if (mjSettingData.code == 0) {
|
||||||
|
throw new Error("加载MJ设置失败,失败原因如下:" + mjSettingData.message)
|
||||||
|
}
|
||||||
|
if (mjSettingData.data == null) {
|
||||||
|
throw new Error("加载MJ设置失败,失败原因如下:没有找到对应的MJ设置,请先去MJ设置中设置")
|
||||||
|
}
|
||||||
|
if (!ValidateJson(mjSettingData.data.value)) {
|
||||||
|
throw new Error("MJ设置的数据格式不正确,请检查数据格式")
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mj_globalSetting = JSON.parse(mjSettingData.data.value) as MJSettingModel.MJ_GlobalSettingModel
|
||||||
|
this.mjSimpleSetting = this.mj_globalSetting.mj_simpleSetting
|
||||||
|
|
||||||
|
this.bootType = this.mjSimpleSetting.selectRobot == MJRobotType.NIJI ? "NIJI_JOURNEY" : "MID_JOURNEY"
|
||||||
|
if (this.mjSimpleSetting.type == MJImageType.REMOTE_MJ) {
|
||||||
this.imagineUrl = define.remotemj_api + 'mj/submit/imagine'
|
this.imagineUrl = define.remotemj_api + 'mj/submit/imagine'
|
||||||
this.describeUrl = define.remotemj_api + 'mj/submit/describe'
|
this.describeUrl = define.remotemj_api + 'mj/submit/describe'
|
||||||
this.fetchTaskUrl = define.remotemj_api + 'mj/task/${id}/fetch'
|
this.fetchTaskUrl = define.remotemj_api + 'mj/task/${id}/fetch'
|
||||||
} else {
|
} else {
|
||||||
if (global.config.laiApiSelect == LaiAPIType.HK_PROXY) {
|
|
||||||
this.imagineUrl = define.hkServerUrl + 'mj/submit/imagine'
|
let apiUrlIndex = apiUrl.findIndex(item => item.value == this.mj_globalSetting.mj_apiSetting.mjApiUrl);
|
||||||
this.describeUrl = define.hkServerUrl + 'mj/submit/describe'
|
if (apiUrlIndex == -1) {
|
||||||
this.fetchTaskUrl = define.hkServerUrl + 'mj/task/${id}/fetch'
|
throw new Error('没有找到MJ API对应的请求URL,请检查配置');
|
||||||
} else if (global.config.laiApiSelect == LaiAPIType.BAK_MAIN) {
|
|
||||||
this.imagineUrl = define.bakServerUrl + 'mj/submit/imagine'
|
|
||||||
this.describeUrl = define.bakServerUrl + 'mj/submit/describe'
|
|
||||||
this.fetchTaskUrl = define.bakServerUrl + 'mj/task/${id}/fetch'
|
|
||||||
} else {
|
|
||||||
let gpt = new GPT()
|
|
||||||
let mj_api = (await gpt.GetGPTBusinessOption('all', (value) => value.mj_url)).data
|
|
||||||
let mj_api_url_index = mj_api.findIndex((item) => item.value == this.mjSetting.apiSetting.mjApiUrl)
|
|
||||||
if (mj_api_url_index == -1) {
|
|
||||||
throw new Error('没有找到对应的MJ API的配置,请先检查配置')
|
|
||||||
}
|
}
|
||||||
this.imagineUrl = mj_api[mj_api_url_index].mj_url.imagine;
|
|
||||||
this.fetchTaskUrl = mj_api[mj_api_url_index].mj_url.once_get_task;
|
let apiUrlItem = apiUrl[apiUrlIndex];
|
||||||
this.describeUrl = mj_api[mj_api_url_index].mj_url.imagine.replace("imagine", "describe");
|
if (apiUrlItem.mj_url == null) {
|
||||||
|
throw new Error('没有找到MJ API对应的请求URL,请检查配置');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.imagineUrl = apiUrlItem.mj_url.imagine
|
||||||
|
this.describeUrl = apiUrlItem.mj_url.describe
|
||||||
|
this.fetchTaskUrl = apiUrlItem.mj_url.once_get_task
|
||||||
}
|
}
|
||||||
return mjSettings.data
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region 获取对应的任务,通过ID
|
//#region 获取对应的任务,通过ID
|
||||||
@ -71,27 +89,66 @@ class MJApi {
|
|||||||
async GetMJAPITaskById(taskId: string, backTaskId: string) {
|
async GetMJAPITaskById(taskId: string, backTaskId: string) {
|
||||||
try {
|
try {
|
||||||
await this.InitMJSetting();
|
await this.InitMJSetting();
|
||||||
let url = this.fetchTaskUrl.replace("${id}", taskId)
|
let APIDescribeUrl = this.fetchTaskUrl.replace("${id}", taskId)
|
||||||
let headers = undefined
|
let headers = undefined
|
||||||
if (this.mjSetting.type == MJImageType.REMOTE_MJ) {
|
let useTransfer = false
|
||||||
|
|
||||||
|
if (this.mjSimpleSetting.type == MJImageType.REMOTE_MJ) {
|
||||||
headers = {
|
headers = {
|
||||||
'mj-api-secret': define.API
|
'mj-api-secret': define.API
|
||||||
}
|
}
|
||||||
|
useTransfer = this.mj_globalSetting.mj_remoteSimpleSetting.useTransfer
|
||||||
} else {
|
} else {
|
||||||
headers = {
|
headers = {
|
||||||
Authorization: this.mjSetting.apiSetting.apiKey
|
Authorization: this.mj_globalSetting.mj_apiSetting.apiKey
|
||||||
}
|
}
|
||||||
|
useTransfer = this.mj_globalSetting.mj_apiSetting.useTransfer
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = await axios.get(url, {
|
let resData = undefined
|
||||||
|
if (useTransfer) {
|
||||||
|
|
||||||
|
let url = define.lms + "/lms/Forward/GetTransfer";
|
||||||
|
let config = {
|
||||||
|
method: 'post',
|
||||||
|
url: url,
|
||||||
|
maxBodyLength: Infinity,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data: JSON.stringify({
|
||||||
|
url: APIDescribeUrl,
|
||||||
|
apiKey: this.mjSimpleSetting.type == MJImageType.REMOTE_MJ ?
|
||||||
|
define.API :
|
||||||
|
headers.Authorization,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = await axios.request(config);
|
||||||
|
if (res.status != 200) {
|
||||||
|
throw new Error("转发请求失败")
|
||||||
|
}
|
||||||
|
if (res.data.code != 1) {
|
||||||
|
throw new Error(res.data.message)
|
||||||
|
}
|
||||||
|
if (!ValidateJson(res.data.data)) {
|
||||||
|
throw new Error(res.data.data)
|
||||||
|
}
|
||||||
|
resData = JSON.parse(res.data.data);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
let res = await axios.get(APIDescribeUrl, {
|
||||||
headers: headers
|
headers: headers
|
||||||
})
|
})
|
||||||
|
resData = res.data
|
||||||
|
}
|
||||||
|
|
||||||
let progress = res.data.progress && res.data.progress.length > 0
|
|
||||||
? parseInt(res.data.progress.slice(0, -1))
|
let progress = resData.progress && resData.progress.length > 0
|
||||||
|
? parseInt(resData.progress.slice(0, -1))
|
||||||
: 0
|
: 0
|
||||||
|
|
||||||
let status = res.data.status.toLowerCase()
|
let status = resData.status.toLowerCase()
|
||||||
let code = status == 'failure' || status == 'cancel' ? 0 : 1
|
let code = status == 'failure' || status == 'cancel' ? 0 : 1
|
||||||
|
|
||||||
let _bookBackTaskListService = await BookBackTaskListService.getInstance()
|
let _bookBackTaskListService = await BookBackTaskListService.getInstance()
|
||||||
@ -101,22 +158,22 @@ class MJApi {
|
|||||||
_bookBackTaskListService.UpdateTaskStatus({
|
_bookBackTaskListService.UpdateTaskStatus({
|
||||||
id: backTaskId,
|
id: backTaskId,
|
||||||
status: BookBackTaskStatus.FAIL,
|
status: BookBackTaskStatus.FAIL,
|
||||||
errorMessage: res.data.message
|
errorMessage: resData.message
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let resObj = {
|
let resObj = {
|
||||||
type: MJRespoonseType.UPDATED,
|
type: MJRespoonseType.UPDATED,
|
||||||
progress: isNaN(progress) ? 0 : progress,
|
progress: isNaN(progress) ? 0 : progress,
|
||||||
category: this.mjSetting.type,
|
category: this.mjSimpleSetting.type,
|
||||||
imageClick: res.data.imageUrl,
|
imageClick: resData.imageUrl,
|
||||||
imageShow: res.data.imageUrl,
|
imageShow: resData.imageUrl,
|
||||||
imagePath: res.data.imageUrl,
|
imagePath: resData.imageUrl,
|
||||||
messageId: taskId,
|
messageId: taskId,
|
||||||
status: status,
|
status: status,
|
||||||
code: code,
|
code: code,
|
||||||
prompt: res.data.prompt == "" ? res.data.promptEn : res.data.prompt,
|
prompt: resData.prompt == "" ? resData.promptEn : resData.prompt,
|
||||||
message: res.data.failReason,
|
message: resData.failReason,
|
||||||
mjApiUrl: this.fetchTaskUrl,
|
mjApiUrl: this.fetchTaskUrl,
|
||||||
} as MJ.MJResponseToFront
|
} as MJ.MJResponseToFront
|
||||||
return resObj
|
return resObj
|
||||||
@ -135,7 +192,7 @@ class MJApi {
|
|||||||
async SubmitMJDescribe(param: MJ.APIDescribeParams): Promise<string> {
|
async SubmitMJDescribe(param: MJ.APIDescribeParams): Promise<string> {
|
||||||
await this.InitMJSetting()
|
await this.InitMJSetting()
|
||||||
let res = undefined
|
let res = undefined
|
||||||
switch (this.mjSetting.type) {
|
switch (this.mjSimpleSetting.type) {
|
||||||
case MJImageType.REMOTE_MJ:
|
case MJImageType.REMOTE_MJ:
|
||||||
case MJImageType.API_MJ:
|
case MJImageType.API_MJ:
|
||||||
res = await this.SubmitMJDescribeAPI(param)
|
res = await this.SubmitMJDescribeAPI(param)
|
||||||
@ -157,7 +214,7 @@ class MJApi {
|
|||||||
botType: this.bootType,
|
botType: this.bootType,
|
||||||
base64: param.image,
|
base64: param.image,
|
||||||
accountFilter: {
|
accountFilter: {
|
||||||
modes: [this.mjSetting.apiSetting.mjSpeed == MJSpeed.FAST ? "FAST" : "RELAX"],
|
modes: [this.mj_globalSetting.mj_apiSetting.mjSpeed == MJSpeed.FAST ? "FAST" : "RELAX"],
|
||||||
remark: global.machineId
|
remark: global.machineId
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -168,11 +225,12 @@ class MJApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.mjSetting.type == MJImageType.REMOTE_MJ) {
|
if (this.mjSimpleSetting.type == MJImageType.REMOTE_MJ) {
|
||||||
config.headers["mj-api-secret"] = define.API;
|
config.headers["mj-api-secret"] = define.API;
|
||||||
|
delete data.accountFilter.modes;
|
||||||
} else {
|
} else {
|
||||||
delete data.accountFilter.remark
|
delete data.accountFilter.remark
|
||||||
config.headers["Authorization"] = this.mjSetting.apiSetting.apiKey;
|
config.headers["Authorization"] = this.mj_globalSetting.mj_apiSetting.apiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 开始请求
|
// 开始请求
|
||||||
@ -215,7 +273,7 @@ class MJApi {
|
|||||||
async SubmitMJImagine(taskId: string, prompt: string): Promise<string> {
|
async SubmitMJImagine(taskId: string, prompt: string): Promise<string> {
|
||||||
await this.InitMJSetting()
|
await this.InitMJSetting()
|
||||||
let res = undefined
|
let res = undefined
|
||||||
switch (this.mjSetting.type) {
|
switch (this.mjSimpleSetting.type) {
|
||||||
case MJImageType.REMOTE_MJ:
|
case MJImageType.REMOTE_MJ:
|
||||||
case MJImageType.API_MJ:
|
case MJImageType.API_MJ:
|
||||||
res = await this.SubmitMJImagineAPI(taskId, prompt)
|
res = await this.SubmitMJImagineAPI(taskId, prompt)
|
||||||
@ -233,12 +291,13 @@ class MJApi {
|
|||||||
async SubmitMJImagineAPI(taskId: string, prompt: string): Promise<string> {
|
async SubmitMJImagineAPI(taskId: string, prompt: string): Promise<string> {
|
||||||
|
|
||||||
let _bookBackTaskListService = await BookBackTaskListService.getInstance()
|
let _bookBackTaskListService = await BookBackTaskListService.getInstance()
|
||||||
|
|
||||||
// 提交API的出图任务
|
// 提交API的出图任务
|
||||||
let data = {
|
let data = {
|
||||||
botType: this.bootType,
|
botType: this.bootType,
|
||||||
prompt: prompt,
|
prompt: prompt,
|
||||||
accountFilter: {
|
accountFilter: {
|
||||||
modes: [this.mjSetting.apiSetting.mjSpeed == MJSpeed.FAST ? "FAST" : "RELAX"],
|
modes: [this.mj_globalSetting.mj_apiSetting.mjSpeed == MJSpeed.FAST ? "FAST" : "RELAX"],
|
||||||
remark: global.machineId
|
remark: global.machineId
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -249,18 +308,59 @@ class MJApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.mjSetting.type == MJImageType.REMOTE_MJ) {
|
let useTransfer = false;
|
||||||
|
|
||||||
|
if (this.mjSimpleSetting.type == MJImageType.REMOTE_MJ) {
|
||||||
config.headers["mj-api-secret"] = define.API;
|
config.headers["mj-api-secret"] = define.API;
|
||||||
|
delete data.accountFilter.modes;
|
||||||
|
useTransfer = this.mj_globalSetting.mj_remoteSimpleSetting.useTransfer
|
||||||
} else {
|
} else {
|
||||||
delete data.accountFilter.remark
|
delete data.accountFilter.remark
|
||||||
config.headers["Authorization"] = this.mjSetting.apiSetting.apiKey;
|
config.headers["Authorization"] = this.mj_globalSetting.mj_apiSetting.apiKey;
|
||||||
|
useTransfer = this.mj_globalSetting.mj_apiSetting.useTransfer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let resData: any = undefined;
|
||||||
|
if (useTransfer) {
|
||||||
|
|
||||||
|
let url = define.lms + "/lms/Forward/SimpleTransfer"
|
||||||
|
let transferConfig = {
|
||||||
|
method: 'post',
|
||||||
|
url: url,
|
||||||
|
maxBodyLength: Infinity,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data: JSON.stringify({
|
||||||
|
url: this.imagineUrl,
|
||||||
|
apiKey: this.mjSimpleSetting.type == MJImageType.REMOTE_MJ ? define.API : this.mj_globalSetting.mj_apiSetting.apiKey,
|
||||||
|
dataString: JSON.stringify(data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let res = await axios.request(transferConfig);
|
||||||
|
if (res.status != 200) {
|
||||||
|
throw new Error("转发请求失败")
|
||||||
|
}
|
||||||
|
if (res.data.code != 1) {
|
||||||
|
throw new Error(res.data.message)
|
||||||
|
}
|
||||||
|
if (!ValidateJson(res.data.data)) {
|
||||||
|
throw new Error(res.data.data)
|
||||||
|
}
|
||||||
|
let re = JSON.parse(res.data.data);
|
||||||
|
resData = re
|
||||||
|
} else {
|
||||||
|
|
||||||
// 开始请求
|
// 开始请求
|
||||||
let res = await axios.post(this.imagineUrl, data, config)
|
let res = await axios.post(this.imagineUrl, data, config)
|
||||||
|
resData = res.data
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resData == null) {
|
||||||
|
throw new Error("返回的数据为空")
|
||||||
|
}
|
||||||
// 某些API的返回的code为23,表示队列已满,需要重新请求
|
// 某些API的返回的code为23,表示队列已满,需要重新请求
|
||||||
if (res.data.code == 23) {
|
if (resData.code == 23) {
|
||||||
_bookBackTaskListService.UpdateTaskStatus({
|
_bookBackTaskListService.UpdateTaskStatus({
|
||||||
id: taskId,
|
id: taskId,
|
||||||
status: BookBackTaskStatus.RECONNECT
|
status: BookBackTaskStatus.RECONNECT
|
||||||
@ -268,13 +368,13 @@ class MJApi {
|
|||||||
return '23'
|
return '23'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.data.code != 1 && res.data.code != 22) {
|
if (resData.code != 1 && resData.code != 22) {
|
||||||
_bookBackTaskListService.UpdateTaskStatus({
|
_bookBackTaskListService.UpdateTaskStatus({
|
||||||
id: taskId,
|
id: taskId,
|
||||||
status: BookBackTaskStatus.FAIL,
|
status: BookBackTaskStatus.FAIL,
|
||||||
errorMessage: res.data.description
|
errorMessage: resData.description
|
||||||
})
|
})
|
||||||
throw new Error(res.data.description)
|
throw new Error(resData.description)
|
||||||
}
|
}
|
||||||
|
|
||||||
_bookBackTaskListService.UpdateTaskStatus({
|
_bookBackTaskListService.UpdateTaskStatus({
|
||||||
@ -282,7 +382,7 @@ class MJApi {
|
|||||||
status: BookBackTaskStatus.RUNNING
|
status: BookBackTaskStatus.RUNNING
|
||||||
})
|
})
|
||||||
|
|
||||||
return res.data.result as string
|
return resData.result as string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
169
src/main/Service/MJ/mjDefine.ts
Normal file
169
src/main/Service/MJ/mjDefine.ts
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
import { apiUrl } from "@/define/api/apiUrlDefine"
|
||||||
|
import { MJRobotType, MJSpeed } from "@/define/enum/mjEnum"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取MJ的请求模式列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function GetMJRequestModelOptions() {
|
||||||
|
let mjRequstModel = [{
|
||||||
|
label: "本地MJ(待开发)",
|
||||||
|
value: "local_mj",
|
||||||
|
disable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "代理MJ(token)",
|
||||||
|
value: "remote_mj",
|
||||||
|
disable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "浏览器模式",
|
||||||
|
value: "browser_mj",
|
||||||
|
disable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "API模式",
|
||||||
|
value: "api_mj",
|
||||||
|
disable: false
|
||||||
|
}]
|
||||||
|
return mjRequstModel.filter(item => !item.disable)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取MJ的机器人列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function GetMJRobotOptions() {
|
||||||
|
return [{
|
||||||
|
label: 'MJ',
|
||||||
|
value: MJRobotType.MJ
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'NIJI',
|
||||||
|
value: MJRobotType.NIJI
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取机器人对应的出图模型
|
||||||
|
*/
|
||||||
|
function GetMJRobotModelOptions(mjRobot?: MJRobotType) {
|
||||||
|
let allRobotModel = [
|
||||||
|
{
|
||||||
|
label: "MJ V6.0",
|
||||||
|
text: "v 6",
|
||||||
|
type: MJRobotType.MJ,
|
||||||
|
value: "3e6473ab-9a64-4574-9a38-f5c75af552b6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "MJ V5.2",
|
||||||
|
text: "v 5.2",
|
||||||
|
type: MJRobotType.MJ,
|
||||||
|
value: "27a0d30e-f46c-4684-96c8-d91334deb94f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "MJ V5.1",
|
||||||
|
text: "v 5.1",
|
||||||
|
type: MJRobotType.MJ,
|
||||||
|
value: "e1226715-e969-44c4-b18b-f2ad5dae5d2f"
|
||||||
|
}, {
|
||||||
|
label: "MJ V5.0",
|
||||||
|
text: "v 5",
|
||||||
|
type: MJRobotType.MJ,
|
||||||
|
value: "afb7bea1-4eda-46ea-8165-34701b4566bf"
|
||||||
|
}, {
|
||||||
|
label: "MJ V4.0",
|
||||||
|
text: "v 4",
|
||||||
|
type: MJRobotType.MJ,
|
||||||
|
value: "d05b8497-7f4a-4890-8fac-89f1803984d2"
|
||||||
|
}, {
|
||||||
|
label: "NIJI V6",
|
||||||
|
text: "niji 6",
|
||||||
|
type: MJRobotType.NIJI,
|
||||||
|
value: "99377cad-c103-4cee-a958-86a104879328"
|
||||||
|
}, {
|
||||||
|
label: "NIJI V5",
|
||||||
|
text: "niji 5",
|
||||||
|
type: MJRobotType.NIJI,
|
||||||
|
value: "53cec077-9885-4635-ab18-e021066b2c4c"
|
||||||
|
}, {
|
||||||
|
label: "NIJI V4",
|
||||||
|
text: "niji 4",
|
||||||
|
type: MJRobotType.NIJI,
|
||||||
|
value: "6a7199fe-6e0d-40a9-9772-b5eb3d2e2e66"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
switch (mjRobot) {
|
||||||
|
case MJRobotType.MJ:
|
||||||
|
return allRobotModel.filter(item => item.type == MJRobotType.MJ)
|
||||||
|
case MJRobotType.NIJI:
|
||||||
|
return allRobotModel.filter(item => item.type == MJRobotType.NIJI)
|
||||||
|
default:
|
||||||
|
return allRobotModel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取MJ出图的比例Options
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function GetMJImageScaleOptions() {
|
||||||
|
return [{
|
||||||
|
label: "1:1",
|
||||||
|
text: "1:1",
|
||||||
|
value: "3e2772f2-041c-49c6-ba13-d0ed120310b8"
|
||||||
|
}, {
|
||||||
|
label: "4:3",
|
||||||
|
text: "4:3",
|
||||||
|
value: "fcef555c-1958-4082-88fe-434782aa8151"
|
||||||
|
}, {
|
||||||
|
label: "3:4",
|
||||||
|
text: "3:4",
|
||||||
|
value: "13f71d53-73a3-4c9b-9c1e-6e7e939aee73"
|
||||||
|
}, {
|
||||||
|
label: "16:9",
|
||||||
|
text: "16:9",
|
||||||
|
value: "bf33ce1a-15cd-4901-b38e-89543cf14a1f"
|
||||||
|
}, {
|
||||||
|
label: "9:16",
|
||||||
|
text: "9:16",
|
||||||
|
value: "fd4641e2-97f4-4a86-8616-4965e05f3348"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取MJ API 可用的URL Options
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function GetMJAPIUrlOptions() {
|
||||||
|
return apiUrl.filter((item) => item.mj_url)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取MJ的速度Options
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function GetMJSpeedOptions() {
|
||||||
|
return [{
|
||||||
|
label: "FAST",
|
||||||
|
value: MJSpeed.FAST
|
||||||
|
}, {
|
||||||
|
label: "RELAXED",
|
||||||
|
value: MJSpeed.RELAX
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MJ的一些数据的定义
|
||||||
|
*/
|
||||||
|
let MJDefine = {
|
||||||
|
GetMJRequestModelOptions,
|
||||||
|
GetMJRobotOptions,
|
||||||
|
GetMJRobotModelOptions,
|
||||||
|
GetMJImageScaleOptions,
|
||||||
|
GetMJAPIUrlOptions,
|
||||||
|
GetMJSpeedOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MJDefine
|
||||||
@ -13,7 +13,7 @@ class OptionHandle {
|
|||||||
* @param key 指定的Key的值
|
* @param key 指定的Key的值
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
GetOptionByKey = async (key: string) => await this.optionServices.GetOptionByKey(key)
|
GetOptionByKey = async (key: string | string[]) => await this.optionServices.GetOptionByKey(key)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改指定的Option,通过key,不存在则创建
|
* 修改指定的Option,通过key,不存在则创建
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { OptionKeyName, OptionType } from '@/define/enum/option'
|
|||||||
import { ValidateJson } from '@/define/Tools/validate'
|
import { ValidateJson } from '@/define/Tools/validate'
|
||||||
import { errorMessage, successMessage } from '@/main/Public/generalTools'
|
import { errorMessage, successMessage } from '@/main/Public/generalTools'
|
||||||
import { ErrorItem, GeneralResponse, SuccessItem } from '@/model/generalResponse'
|
import { ErrorItem, GeneralResponse, SuccessItem } from '@/model/generalResponse'
|
||||||
|
import { OptionModel } from '@/model/option/option'
|
||||||
export class OptionServices {
|
export class OptionServices {
|
||||||
optionRealmService!: OptionRealmService
|
optionRealmService!: OptionRealmService
|
||||||
constructor() { }
|
constructor() { }
|
||||||
@ -19,10 +20,26 @@ export class OptionServices {
|
|||||||
* @param key
|
* @param key
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public async GetOptionByKey(key: string): Promise<GeneralResponse.ErrorItem | SuccessItem> {
|
public async GetOptionByKey(key: string | string[]): Promise<GeneralResponse.ErrorItem | SuccessItem> {
|
||||||
try {
|
try {
|
||||||
await this.InitService()
|
await this.InitService()
|
||||||
let res = this.optionRealmService.GetOptionByKey(key)
|
let res: Array<OptionModel.OptionItem> | OptionModel.OptionItem;
|
||||||
|
if (Array.isArray(key)) {
|
||||||
|
if (key.length <= 0) {
|
||||||
|
throw new Error('Key不能为空')
|
||||||
|
}
|
||||||
|
let temp = []
|
||||||
|
for (let i = 0; i < key.length; i++) {
|
||||||
|
const element = key[i];
|
||||||
|
let resItem = this.optionRealmService.GetOptionByKey(element)
|
||||||
|
if (resItem != null) {
|
||||||
|
temp.push(resItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res = temp;
|
||||||
|
} else {
|
||||||
|
res = this.optionRealmService.GetOptionByKey(key)
|
||||||
|
}
|
||||||
return successMessage(res, '获取成功 OptionKey: ' + key, 'OptionOptions.GetOptionByKey')
|
return successMessage(res, '获取成功 OptionKey: ' + key, 'OptionOptions.GetOptionByKey')
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
return errorMessage(
|
return errorMessage(
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { SoftwareService } from '../../../define/db/service/SoftWare/softwareService';
|
import { SoftwareService } from '../../../define/db/service/SoftWare/softwareService';
|
||||||
import { MJSettingService } from '../../../define/db/service/SoftWare/mjSettingService';
|
import { MJSettingService } from '../../../define/db/service/SoftWare/mjSettingService';
|
||||||
import { MJSetting } from '../../../model/Setting/mjSetting';
|
import { MJSettingModel } from '../../../model/Setting/mjSetting';
|
||||||
|
|
||||||
|
|
||||||
export class SoftWareServiceBasic {
|
export class SoftWareServiceBasic {
|
||||||
@ -85,7 +85,7 @@ export class SoftWareServiceBasic {
|
|||||||
* 获取MJ的设置信息
|
* 获取MJ的设置信息
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async GetMjSetting(): Promise<MJSetting.MjSetting> {
|
async GetMjSetting(): Promise<MJSettingModel.MjSimpleSettingModel> {
|
||||||
await this.InitService();
|
await this.InitService();
|
||||||
let mjSetting = this.mjSettingService.GetMjSetting({})
|
let mjSetting = this.mjSettingService.GetMjSetting({})
|
||||||
if (mjSetting.code == 1) {
|
if (mjSetting.code == 1) {
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import { D3Opt } from '../d3'
|
|||||||
import { FluxOpt } from '../Flux/flux'
|
import { FluxOpt } from '../Flux/flux'
|
||||||
import { AsyncQueue } from '../../quene'
|
import { AsyncQueue } from '../../quene'
|
||||||
import { SoftWareServiceBasic } from '../ServiceBasic/softwareServiceBasic'
|
import { SoftWareServiceBasic } from '../ServiceBasic/softwareServiceBasic'
|
||||||
import { MJSetting } from '../../../model/Setting/mjSetting'
|
import { MJSettingModel } from '../../../model/Setting/mjSetting'
|
||||||
import { BookVideo } from '../Book/bookVideo'
|
import { BookVideo } from '../Book/bookVideo'
|
||||||
import { BookServiceBasic } from '../ServiceBasic/bookServiceBasic'
|
import { BookServiceBasic } from '../ServiceBasic/bookServiceBasic'
|
||||||
import { TaskModal } from '@/model/task'
|
import { TaskModal } from '@/model/task'
|
||||||
@ -32,7 +32,7 @@ export class TaskManager {
|
|||||||
bookServiceBasic: BookServiceBasic
|
bookServiceBasic: BookServiceBasic
|
||||||
videoGlobal: VideoGlobal
|
videoGlobal: VideoGlobal
|
||||||
|
|
||||||
mjSetting: MJSetting.MjSetting
|
mjSimpleSetting: MJSettingModel.MjSimpleSettingModel
|
||||||
spaceTime: number = 5000;
|
spaceTime: number = 5000;
|
||||||
count = 0;
|
count = 0;
|
||||||
isListening = false;
|
isListening = false;
|
||||||
@ -65,7 +65,7 @@ export class TaskManager {
|
|||||||
}
|
}
|
||||||
if (getMJsetting) {
|
if (getMJsetting) {
|
||||||
// 初始化MJ设置
|
// 初始化MJ设置
|
||||||
this.mjSetting = await this.softWareServiceBasic.GetMjSetting()
|
this.mjSimpleSetting = await this.softWareServiceBasic.GetMjSetting()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,8 +141,8 @@ export class TaskManager {
|
|||||||
if (element.type == BookBackTaskType.MJ_IMAGE || element.type == BookBackTaskType.MJ_REVERSE) {
|
if (element.type == BookBackTaskType.MJ_IMAGE || element.type == BookBackTaskType.MJ_REVERSE) {
|
||||||
// 判断任务数量是不是又修改
|
// 判断任务数量是不是又修改
|
||||||
let taskNumber = global.mjQueue.getConcurrencyLimit();
|
let taskNumber = global.mjQueue.getConcurrencyLimit();
|
||||||
if (taskNumber != this.mjSetting.taskCount) {
|
if (taskNumber != this.mjSimpleSetting.taskCount) {
|
||||||
global.mjQueue.concurrencyLimit = this.mjSetting.taskCount // 重置并发执行的数量
|
global.mjQueue.concurrencyLimit = this.mjSimpleSetting.taskCount // 重置并发执行的数量
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global.mjQueue.getWaitingQueue() > 10) {
|
if (global.mjQueue.getWaitingQueue() > 10) {
|
||||||
|
|||||||
@ -7,11 +7,12 @@ import { cloneDeep, isEmpty } from "lodash";
|
|||||||
import { GetBaseUrl } from "@/define/Tools/common";
|
import { GetBaseUrl } from "@/define/Tools/common";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { Book } from "@/model/book/book";
|
import { Book } from "@/model/book/book";
|
||||||
import { c } from "naive-ui";
|
|
||||||
import { VideoStatus } from "@/define/enum/video";
|
import { VideoStatus } from "@/define/enum/video";
|
||||||
import { SendMessageToRenderer } from "../globalService";
|
import { SendMessageToRenderer } from "../globalService";
|
||||||
import { ResponseMessageType } from "@/define/enum/softwareEnum";
|
import { ResponseMessageType } from "@/define/enum/softwareEnum";
|
||||||
import { BookBackTaskStatus, BookTaskStatus } from "@/define/enum/bookEnum";
|
import { BookBackTaskStatus, BookTaskStatus } from "@/define/enum/bookEnum";
|
||||||
|
import { define } from "@/define/define"
|
||||||
|
import ForwardResponse from "@/define/response/ForwardResponse";
|
||||||
|
|
||||||
export class KlingService {
|
export class KlingService {
|
||||||
bookServiceBasic: BookServiceBasic
|
bookServiceBasic: BookServiceBasic
|
||||||
@ -25,7 +26,7 @@ export class KlingService {
|
|||||||
* @param gptUrl GPT地址
|
* @param gptUrl GPT地址
|
||||||
* @param gptApiKey GPTAPIKey
|
* @param gptApiKey GPTAPIKey
|
||||||
*/
|
*/
|
||||||
async KlingImageToVideo(task: TaskModal.Task, gptUrl: string, gptApiKey: string): Promise<void> {
|
async KlingImageToVideo(task: TaskModal.Task, gptUrl: string, gptApiKey: string, useTransfer: boolean = false): Promise<void> {
|
||||||
try {
|
try {
|
||||||
let bookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailDataById(task.bookTaskDetailId);
|
let bookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailDataById(task.bookTaskDetailId);
|
||||||
let klingOptionsString = bookTaskDetail.videoMessage.klingOptions;
|
let klingOptionsString = bookTaskDetail.videoMessage.klingOptions;
|
||||||
@ -76,10 +77,31 @@ export class KlingService {
|
|||||||
if (klingOptions.hasOwnProperty("callback_url")) {
|
if (klingOptions.hasOwnProperty("callback_url")) {
|
||||||
data.callback_url = klingOptions.callback_url;
|
data.callback_url = klingOptions.callback_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 开始请求
|
// 开始请求
|
||||||
let baseUrl = GetBaseUrl(gptUrl);
|
let baseUrl = GetBaseUrl(gptUrl);
|
||||||
let url = baseUrl + "/kling/v1/videos/image2video";
|
let url = baseUrl + "/kling/v1/videos/image2video";
|
||||||
|
|
||||||
|
let resData: any = undefined;
|
||||||
|
if (useTransfer) {
|
||||||
|
let transferUrl = define.lms + "/lms/Forward/SimpleTransfer";
|
||||||
|
let transferConfig = {
|
||||||
|
method: 'post',
|
||||||
|
url: transferUrl,
|
||||||
|
maxBodyLength: Infinity,
|
||||||
|
timeout: 600000, // 600 seconds timeout
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data: JSON.stringify({
|
||||||
|
url: url,
|
||||||
|
apiKey: gptApiKey,
|
||||||
|
dataString: JSON.stringify(data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let response = await axios(transferConfig)
|
||||||
|
resData = ForwardResponse.GetForwardResponseData(response)
|
||||||
|
|
||||||
|
} else {
|
||||||
let res = await axios.post(url, data, {
|
let res = await axios.post(url, data, {
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": gptApiKey
|
"Authorization": gptApiKey
|
||||||
@ -87,7 +109,9 @@ export class KlingService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// console.log("kling合成视频结果", res);
|
// console.log("kling合成视频结果", res);
|
||||||
let resData = res.data;
|
resData = res.data;
|
||||||
|
}
|
||||||
|
|
||||||
let id = resData.data.task_id;
|
let id = resData.data.task_id;
|
||||||
|
|
||||||
// 修改数据
|
// 修改数据
|
||||||
@ -107,38 +131,60 @@ export class KlingService {
|
|||||||
data: JSON.stringify(resData)
|
data: JSON.stringify(resData)
|
||||||
}, task.messageName);
|
}, task.messageName);
|
||||||
|
|
||||||
await this.FetchKlingVideoResult(bookTaskDetail, task, resData.data.task_id, baseUrl, gptApiKey);
|
await this.FetchKlingVideoResult(bookTaskDetail, task, resData.data.task_id, baseUrl, gptApiKey, useTransfer);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error("可灵合成视频失败,失败信息如下:" + error.toString());
|
throw new Error("可灵合成视频失败,失败信息如下:" + error.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
async FetchKlingVideoResult(bookTaskDetail: Book.SelectBookTaskDetail, task: TaskModal.Task, taskId: string, baseUrl: string, gptApiKey: string) {
|
async FetchKlingVideoResult(bookTaskDetail: Book.SelectBookTaskDetail, task: TaskModal.Task, taskId: string, baseUrl: string, gptApiKey: string, useTransfer: boolean = false) {
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
let url = baseUrl + "/kling/v1/videos/image2video/" + taskId;
|
let url = baseUrl + "/kling/v1/videos/image2video/" + taskId;
|
||||||
|
let resData: any = undefined;
|
||||||
|
if (useTransfer) {
|
||||||
|
let transferUrl = define.lms + "/lms/Forward/GetTransfer";
|
||||||
|
let transferConfig = {
|
||||||
|
method: 'post',
|
||||||
|
url: transferUrl,
|
||||||
|
maxBodyLength: Infinity,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data: JSON.stringify({
|
||||||
|
url: url,
|
||||||
|
apiKey: gptApiKey,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let res = await axios.request(transferConfig);
|
||||||
|
resData = ForwardResponse.GetForwardResponseData(res)
|
||||||
|
} else {
|
||||||
let res = await axios.get(url, {
|
let res = await axios.get(url, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: gptApiKey
|
Authorization: gptApiKey
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// console.log("kling合成视频结果", res.data);
|
resData = res.data;
|
||||||
let data = res.data.data;
|
}
|
||||||
if (data.task_status == "submitted") {
|
if (!resData) {
|
||||||
|
throw new Error("获取可灵合成视频结果失败")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resData.data.task_status == "submitted") {
|
||||||
SendMessageToRenderer({
|
SendMessageToRenderer({
|
||||||
code: 1,
|
code: 1,
|
||||||
id: bookTaskDetail.id,
|
id: bookTaskDetail.id,
|
||||||
message: "可灵合成任务提交成功,正在合成中",
|
message: "可灵合成任务提交成功,正在合成中",
|
||||||
type: ResponseMessageType.KLING_VIDEO,
|
type: ResponseMessageType.KLING_VIDEO,
|
||||||
data: JSON.stringify(data)
|
data: JSON.stringify(resData.data)
|
||||||
}, task.messageName);
|
}, task.messageName);
|
||||||
} else if (data.task_status == "processing") {
|
} else if (resData.data.task_status == "processing") {
|
||||||
|
|
||||||
let videoMessage = cloneDeep(bookTaskDetail.videoMessage);
|
let videoMessage = cloneDeep(bookTaskDetail.videoMessage);
|
||||||
delete videoMessage.id;
|
delete videoMessage.id;
|
||||||
videoMessage.status = VideoStatus.PROCESSING;
|
videoMessage.status = VideoStatus.PROCESSING;
|
||||||
videoMessage.taskId = taskId;
|
videoMessage.taskId = taskId;
|
||||||
videoMessage.messageData = JSON.stringify(data);
|
videoMessage.messageData = JSON.stringify(resData.data);
|
||||||
await this.bookServiceBasic.UpdateBookTaskDetailVideoMessage(task.bookTaskDetailId, videoMessage);
|
await this.bookServiceBasic.UpdateBookTaskDetailVideoMessage(task.bookTaskDetailId, videoMessage);
|
||||||
|
|
||||||
SendMessageToRenderer({
|
SendMessageToRenderer({
|
||||||
@ -146,16 +192,16 @@ export class KlingService {
|
|||||||
id: bookTaskDetail.id,
|
id: bookTaskDetail.id,
|
||||||
message: "可灵合成任务正在合成中",
|
message: "可灵合成任务正在合成中",
|
||||||
type: ResponseMessageType.KLING_VIDEO,
|
type: ResponseMessageType.KLING_VIDEO,
|
||||||
data: JSON.stringify(data)
|
data: JSON.stringify(resData.data)
|
||||||
}, task.messageName);
|
}, task.messageName);
|
||||||
} else if (data.task_status == "succeed") {
|
} else if (resData.data.task_status == "succeed") {
|
||||||
// 完成
|
// 完成
|
||||||
let videoMessage = cloneDeep(bookTaskDetail.videoMessage);
|
let videoMessage = cloneDeep(bookTaskDetail.videoMessage);
|
||||||
delete videoMessage.id;
|
delete videoMessage.id;
|
||||||
videoMessage.status = VideoStatus.SUCCESS;
|
videoMessage.status = VideoStatus.SUCCESS;
|
||||||
videoMessage.taskId = taskId;
|
videoMessage.taskId = taskId;
|
||||||
videoMessage.videoUrl = data.task_result.videos[0].url;
|
videoMessage.videoUrl = resData.data.task_result.videos[0].url;
|
||||||
videoMessage.messageData = JSON.stringify(data);
|
videoMessage.messageData = JSON.stringify(resData.data);
|
||||||
await this.bookServiceBasic.UpdateBookTaskDetailVideoMessage(task.bookTaskDetailId, videoMessage);
|
await this.bookServiceBasic.UpdateBookTaskDetailVideoMessage(task.bookTaskDetailId, videoMessage);
|
||||||
await this.bookServiceBasic.UpdetedBookTaskData(task.bookTaskId, {
|
await this.bookServiceBasic.UpdetedBookTaskData(task.bookTaskId, {
|
||||||
status: BookTaskStatus.IMAGE_TO_VIDEO_SUCCESS,
|
status: BookTaskStatus.IMAGE_TO_VIDEO_SUCCESS,
|
||||||
@ -169,7 +215,7 @@ export class KlingService {
|
|||||||
id: bookTaskDetail.id,
|
id: bookTaskDetail.id,
|
||||||
message: "可灵合成视频完成",
|
message: "可灵合成视频完成",
|
||||||
type: ResponseMessageType.KLING_VIDEO,
|
type: ResponseMessageType.KLING_VIDEO,
|
||||||
data: JSON.stringify(data.data)
|
data: JSON.stringify(resData.data.data)
|
||||||
}, task.messageName);
|
}, task.messageName);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@ -177,18 +223,18 @@ export class KlingService {
|
|||||||
let videoMessage = cloneDeep(bookTaskDetail.videoMessage);
|
let videoMessage = cloneDeep(bookTaskDetail.videoMessage);
|
||||||
delete videoMessage.id;
|
delete videoMessage.id;
|
||||||
videoMessage.status = VideoStatus.FAIL;
|
videoMessage.status = VideoStatus.FAIL;
|
||||||
videoMessage.msg = res.data.message;
|
videoMessage.msg = resData.message;
|
||||||
videoMessage.taskId = taskId;
|
videoMessage.taskId = taskId;
|
||||||
videoMessage.messageData = JSON.stringify(data);
|
videoMessage.messageData = JSON.stringify(resData.data);
|
||||||
await this.bookServiceBasic.UpdateBookTaskDetailVideoMessage(bookTaskDetail.id, videoMessage);
|
await this.bookServiceBasic.UpdateBookTaskDetailVideoMessage(bookTaskDetail.id, videoMessage);
|
||||||
SendMessageToRenderer({
|
SendMessageToRenderer({
|
||||||
code: 0,
|
code: 0,
|
||||||
id: bookTaskDetail.id,
|
id: bookTaskDetail.id,
|
||||||
message: "runway合成视频失败,错误信息如下:" + res.data.message,
|
message: "runway合成视频失败,错误信息如下:" + resData.data.message,
|
||||||
type: ResponseMessageType.KLING_VIDEO,
|
type: ResponseMessageType.KLING_VIDEO,
|
||||||
data: JSON.stringify(data)
|
data: JSON.stringify(resData.data)
|
||||||
}, task.messageName);
|
}, task.messageName);
|
||||||
throw new Error("可灵合成视频失败,失败信息如下:" + res.data.message);
|
throw new Error("可灵合成视频失败,失败信息如下:" + resData.message);
|
||||||
}
|
}
|
||||||
// 等待20秒后再次请求
|
// 等待20秒后再次请求
|
||||||
await new Promise(resolve => setTimeout(resolve, 20000));
|
await new Promise(resolve => setTimeout(resolve, 20000));
|
||||||
|
|||||||
@ -11,14 +11,25 @@ import { SendMessageToRenderer } from "../globalService";
|
|||||||
import { ResponseMessageType } from "@/define/enum/softwareEnum";
|
import { ResponseMessageType } from "@/define/enum/softwareEnum";
|
||||||
import { Book } from "@/model/book/book";
|
import { Book } from "@/model/book/book";
|
||||||
import { BookBackTaskStatus, BookTaskStatus } from "@/define/enum/bookEnum";
|
import { BookBackTaskStatus, BookTaskStatus } from "@/define/enum/bookEnum";
|
||||||
|
import { define } from "@/define/define"
|
||||||
|
import ForwardResponse from "@/define/response/ForwardResponse";
|
||||||
|
|
||||||
export class LumaService {
|
export class LumaService {
|
||||||
bookServiceBasic: BookServiceBasic
|
bookServiceBasic: BookServiceBasic
|
||||||
|
requestModel: string
|
||||||
constructor() {
|
constructor() {
|
||||||
this.bookServiceBasic = new BookServiceBasic();
|
this.bookServiceBasic = new BookServiceBasic();
|
||||||
|
this.requestModel = "fast"
|
||||||
}
|
}
|
||||||
|
|
||||||
async LumaImageToVideo(task: TaskModal.Task, gptUrl: string, gptApiKey: string): Promise<void> {
|
/**
|
||||||
|
* LUMA 合成视频
|
||||||
|
* @param task
|
||||||
|
* @param gptUrl
|
||||||
|
* @param gptApiKey
|
||||||
|
* @param useTransfer
|
||||||
|
*/
|
||||||
|
async LumaImageToVideo(task: TaskModal.Task, gptUrl: string, gptApiKey: string, useTransfer: boolean = false): Promise<void> {
|
||||||
try {
|
try {
|
||||||
let bookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailDataById(task.bookTaskDetailId);
|
let bookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailDataById(task.bookTaskDetailId);
|
||||||
let lumaOptionsString = bookTaskDetail.videoMessage.lumaOptions;
|
let lumaOptionsString = bookTaskDetail.videoMessage.lumaOptions;
|
||||||
@ -27,6 +38,7 @@ export class LumaService {
|
|||||||
}
|
}
|
||||||
let lumaOptions: BookTaskDetail.lumaOptions = JSON.parse(lumaOptionsString);
|
let lumaOptions: BookTaskDetail.lumaOptions = JSON.parse(lumaOptionsString);
|
||||||
// console.log("lumaOptions", lumaOptions, "gptUrl", gptUrl, "gptApiKey", gptApiKey);
|
// console.log("lumaOptions", lumaOptions, "gptUrl", gptUrl, "gptApiKey", gptApiKey);
|
||||||
|
this.requestModel = lumaOptions.request_model == null ? "fast" : lumaOptions.request_model;
|
||||||
|
|
||||||
let data: BookTaskDetail.lumaOptions = {
|
let data: BookTaskDetail.lumaOptions = {
|
||||||
user_prompt: lumaOptions.user_prompt,
|
user_prompt: lumaOptions.user_prompt,
|
||||||
@ -59,16 +71,39 @@ export class LumaService {
|
|||||||
// 开始请求
|
// 开始请求
|
||||||
let baseUrl = GetBaseUrl(gptUrl);
|
let baseUrl = GetBaseUrl(gptUrl);
|
||||||
let url = baseUrl + "/luma/generations";
|
let url = baseUrl + "/luma/generations";
|
||||||
|
if (this.requestModel == 'relax') {
|
||||||
|
url = baseUrl + "/luma-relax/luma/generations";
|
||||||
|
}
|
||||||
|
|
||||||
|
let returnData: any = undefined
|
||||||
|
// 是否国内转发
|
||||||
|
if (useTransfer) {
|
||||||
|
|
||||||
|
let transferUrl = define.lms + "/lms/Forward/SimpleTransfer";
|
||||||
|
let transferConfig = {
|
||||||
|
method: 'post',
|
||||||
|
url: transferUrl,
|
||||||
|
maxBodyLength: Infinity,
|
||||||
|
timeout: 600000, // 600 seconds timeout
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data: JSON.stringify({
|
||||||
|
url: url,
|
||||||
|
apiKey: gptApiKey,
|
||||||
|
dataString: JSON.stringify(data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let response = await axios(transferConfig)
|
||||||
|
returnData = ForwardResponse.GetForwardResponseData(response)
|
||||||
|
} else {
|
||||||
let res = await axios.post(url, data, {
|
let res = await axios.post(url, data, {
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": gptApiKey
|
"Authorization": gptApiKey
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
returnData = res.data;
|
||||||
// console.log("luma合成视频结果", res);
|
}
|
||||||
|
|
||||||
let returnData = res.data;
|
|
||||||
// console.log("luma合成视频结果", returnData);
|
|
||||||
let id = returnData.id;
|
let id = returnData.id;
|
||||||
|
|
||||||
// 修改数据
|
// 修改数据
|
||||||
@ -88,7 +123,7 @@ export class LumaService {
|
|||||||
data: JSON.stringify(returnData)
|
data: JSON.stringify(returnData)
|
||||||
}, task.messageName);
|
}, task.messageName);
|
||||||
|
|
||||||
await this.FetchLumaVideoResult(bookTaskDetail, task, id, baseUrl, gptApiKey);
|
await this.FetchLumaVideoResult(bookTaskDetail, task, id, baseUrl, gptApiKey, useTransfer);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error("Luma合成视频失败,错误信息如下:" + error.toString());
|
throw new Error("Luma合成视频失败,错误信息如下:" + error.toString());
|
||||||
}
|
}
|
||||||
@ -101,14 +136,38 @@ export class LumaService {
|
|||||||
* @param gptApiKey Key
|
* @param gptApiKey Key
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async GetVideoUri(taskId: string, baseUrl: string, gptApiKey: string): Promise<string> {
|
async GetVideoUri(taskId: string, baseUrl: string, gptApiKey: string, useTransfer: boolean = false): Promise<string> {
|
||||||
let url = baseUrl + "/luma/generations/" + taskId + "/download_video_url";
|
let url = baseUrl + "/luma/generations/" + taskId + "/download_video_url";
|
||||||
|
|
||||||
|
if (this.requestModel == "relax") {
|
||||||
|
url = baseUrl + "/luma-relax/luma/generations/" + taskId + "/download_video_url";
|
||||||
|
}
|
||||||
|
|
||||||
|
let resData: any = undefined;
|
||||||
|
if (useTransfer) {
|
||||||
|
let transferUrl = define.lms + "/lms/Forward/GetTransfer";
|
||||||
|
let transferConfig = {
|
||||||
|
method: 'post',
|
||||||
|
url: transferUrl,
|
||||||
|
maxBodyLength: Infinity,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data: JSON.stringify({
|
||||||
|
url: url,
|
||||||
|
apiKey: gptApiKey,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let res = await axios.request(transferConfig);
|
||||||
|
resData = ForwardResponse.GetForwardResponseData(res)
|
||||||
|
} else {
|
||||||
let res = await axios.get(url, {
|
let res = await axios.get(url, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: gptApiKey
|
Authorization: gptApiKey
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let resData = res.data;
|
resData = res.data;
|
||||||
|
}
|
||||||
// console.log("luma获取视频地址", resData);
|
// console.log("luma获取视频地址", resData);
|
||||||
return resData.url;
|
return resData.url;
|
||||||
}
|
}
|
||||||
@ -121,24 +180,45 @@ export class LumaService {
|
|||||||
* @param baseUrl 请求的网址
|
* @param baseUrl 请求的网址
|
||||||
* @param gptApiKey APIKey
|
* @param gptApiKey APIKey
|
||||||
*/
|
*/
|
||||||
async FetchLumaVideoResult(bookTaskDetail: Book.SelectBookTaskDetail, task: TaskModal.Task, taskId: string, baseUrl: string, gptApiKey: string) {
|
async FetchLumaVideoResult(bookTaskDetail: Book.SelectBookTaskDetail, task: TaskModal.Task, taskId: string, baseUrl: string, gptApiKey: string, useTransfer: boolean = false): Promise<void> {
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
let url = baseUrl + "/luma/generations/" + taskId;
|
let url = baseUrl + "/luma/generations/" + taskId;
|
||||||
|
if (this.requestModel == 'relax') {
|
||||||
|
url = baseUrl + "/luma-relax/luma/generations/" + taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
let resData: any = undefined
|
||||||
|
if (useTransfer) {
|
||||||
|
let transferUrl = define.lms + "/lms/Forward/GetTransfer";
|
||||||
|
let transferConfig = {
|
||||||
|
method: 'post',
|
||||||
|
url: transferUrl,
|
||||||
|
maxBodyLength: Infinity,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data: JSON.stringify({
|
||||||
|
url: url,
|
||||||
|
apiKey: gptApiKey,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let res = await axios.request(transferConfig);
|
||||||
|
resData = ForwardResponse.GetForwardResponseData(res)
|
||||||
|
} else {
|
||||||
let res = await axios.get(url, {
|
let res = await axios.get(url, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: gptApiKey
|
Authorization: gptApiKey
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// console.log("luma合成视频结果", res.data);
|
resData = res.data;
|
||||||
let resData = res.data;
|
}
|
||||||
if (resData.state == "completed") {
|
if (resData.state == "completed") {
|
||||||
|
|
||||||
let video_url = resData.video.download_url;
|
let video_url = resData.video.download_url;
|
||||||
if (isEmpty(video_url)) {
|
if (isEmpty(video_url)) {
|
||||||
// 完成
|
// 完成
|
||||||
let vr = await this.GetVideoUri(taskId, baseUrl, gptApiKey);
|
let vr = await this.GetVideoUri(taskId, baseUrl, gptApiKey, useTransfer);
|
||||||
// console.log("luma合成视频结果", vr);
|
|
||||||
video_url = vr;
|
video_url = vr;
|
||||||
}
|
}
|
||||||
// 保存数据
|
// 保存数据
|
||||||
|
|||||||
@ -11,6 +11,8 @@ import { SendMessageToRenderer } from "../globalService";
|
|||||||
import { ResponseMessageType } from "@/define/enum/softwareEnum";
|
import { ResponseMessageType } from "@/define/enum/softwareEnum";
|
||||||
import { Book } from "@/model/book/book";
|
import { Book } from "@/model/book/book";
|
||||||
import { BookBackTaskStatus, BookTaskStatus } from "@/define/enum/bookEnum";
|
import { BookBackTaskStatus, BookTaskStatus } from "@/define/enum/bookEnum";
|
||||||
|
import { define } from "@/define/define"
|
||||||
|
import ForwardResponse from "@/define/response/ForwardResponse";
|
||||||
|
|
||||||
export class RunwayService {
|
export class RunwayService {
|
||||||
bookServiceBasic: BookServiceBasic
|
bookServiceBasic: BookServiceBasic
|
||||||
@ -24,7 +26,7 @@ export class RunwayService {
|
|||||||
* @param gptUrl 调用地址
|
* @param gptUrl 调用地址
|
||||||
* @param gptApiKey Key
|
* @param gptApiKey Key
|
||||||
*/
|
*/
|
||||||
async ImageToVideo(task: TaskModal.Task, gptUrl: string, gptApiKey: string) {
|
async ImageToVideo(task: TaskModal.Task, gptUrl: string, gptApiKey: string, useTransfer: boolean = false) {
|
||||||
try {
|
try {
|
||||||
let bookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailDataById(task.bookTaskDetailId);
|
let bookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailDataById(task.bookTaskDetailId);
|
||||||
|
|
||||||
@ -77,16 +79,42 @@ export class RunwayService {
|
|||||||
}
|
}
|
||||||
// 开始请求
|
// 开始请求
|
||||||
let baseUrl = GetBaseUrl(gptUrl);
|
let baseUrl = GetBaseUrl(gptUrl);
|
||||||
let res = await axios.post(baseUrl + "/runway/pro/generate", data, {
|
let url = baseUrl + "/runway/pro/generate"
|
||||||
|
|
||||||
|
let resData: any = undefined
|
||||||
|
|
||||||
|
if (useTransfer) {
|
||||||
|
|
||||||
|
let transferUrl = define.lms + "/lms/Forward/SimpleTransfer";
|
||||||
|
let transferConfig = {
|
||||||
|
method: 'post',
|
||||||
|
url: transferUrl,
|
||||||
|
maxBodyLength: Infinity,
|
||||||
|
timeout: 600000, // 600 seconds timeout
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data: JSON.stringify({
|
||||||
|
url: url,
|
||||||
|
apiKey: gptApiKey,
|
||||||
|
dataString: JSON.stringify(data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let response = await axios(transferConfig)
|
||||||
|
resData = ForwardResponse.GetForwardResponseData(response)
|
||||||
|
} else {
|
||||||
|
let res = await axios.post(url, data, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: gptApiKey
|
Authorization: gptApiKey
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// console.log("runway合成视频结果", res.data);
|
// console.log("runway合成视频结果", res.data);
|
||||||
let resData = res.data;
|
resData = res.data;
|
||||||
if (resData.code != 200) {
|
|
||||||
throw new Error(res.data.msg);
|
|
||||||
}
|
}
|
||||||
|
if (resData.code != 200) {
|
||||||
|
throw new Error(resData.msg);
|
||||||
|
}
|
||||||
|
|
||||||
// 修改数据
|
// 修改数据
|
||||||
let videoMessage = cloneDeep(bookTaskDetail.videoMessage);
|
let videoMessage = cloneDeep(bookTaskDetail.videoMessage);
|
||||||
videoMessage.taskId = resData.data.task_id;
|
videoMessage.taskId = resData.data.task_id;
|
||||||
@ -104,16 +132,40 @@ export class RunwayService {
|
|||||||
type: ResponseMessageType.RUNWAY_VIDEO,
|
type: ResponseMessageType.RUNWAY_VIDEO,
|
||||||
data: JSON.stringify(resData.data)
|
data: JSON.stringify(resData.data)
|
||||||
}, task.messageName);
|
}, task.messageName);
|
||||||
await this.FetchRunwayVideoResult(bookTaskDetail, task, resData.data.task_id, baseUrl, gptApiKey);
|
await this.FetchRunwayVideoResult(bookTaskDetail, task, resData.data.task_id, baseUrl, gptApiKey, useTransfer);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error("runway合成视频失败,错误信息如下:" + error.toString());
|
throw new Error("runway合成视频失败,错误信息如下:" + error.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async FetchRunwayVideoResult(bookTaskDetail: Book.SelectBookTaskDetail, task: TaskModal.Task, taskId: string, baseUrl: string, gptApiKey: string) {
|
async FetchRunwayVideoResult(bookTaskDetail: Book.SelectBookTaskDetail, task: TaskModal.Task, taskId: string, baseUrl: string, gptApiKey: string, useTransfer: boolean = false) {
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
let url = baseUrl + "/runway/feed";
|
let url = baseUrl + "/runway/feed";
|
||||||
|
|
||||||
|
let resData: any = undefined
|
||||||
|
|
||||||
|
if (useTransfer) {
|
||||||
|
let transferUrl = define.lms + "/lms/Forward/SimpleTransfer";
|
||||||
|
let transferConfig = {
|
||||||
|
method: 'post',
|
||||||
|
url: transferUrl,
|
||||||
|
maxBodyLength: Infinity,
|
||||||
|
timeout: 600000, // 600 seconds timeout
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
data: JSON.stringify({
|
||||||
|
url: url,
|
||||||
|
apiKey: gptApiKey,
|
||||||
|
dataString: JSON.stringify({
|
||||||
|
"task_id": taskId
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let response = await axios(transferConfig)
|
||||||
|
resData = ForwardResponse.GetForwardResponseData(response)
|
||||||
|
} else {
|
||||||
let res = await axios.post(url, {
|
let res = await axios.post(url, {
|
||||||
"task_id": taskId
|
"task_id": taskId
|
||||||
}, {
|
}, {
|
||||||
@ -122,19 +174,20 @@ export class RunwayService {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let data = res.data;
|
resData = res.data;
|
||||||
if (data.code != 200) {
|
}
|
||||||
throw new Error(data.msg);
|
if (resData.code != 200) {
|
||||||
|
throw new Error(resData.msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.data.status == '3') {
|
if (resData.data.status == '3') {
|
||||||
// 完成
|
// 完成
|
||||||
let videoMessage = cloneDeep(bookTaskDetail.videoMessage);
|
let videoMessage = cloneDeep(bookTaskDetail.videoMessage);
|
||||||
delete videoMessage.id;
|
delete videoMessage.id;
|
||||||
videoMessage.status = VideoStatus.SUCCESS;
|
videoMessage.status = VideoStatus.SUCCESS;
|
||||||
videoMessage.taskId = taskId;
|
videoMessage.taskId = taskId;
|
||||||
videoMessage.videoUrl = data.data.video_url;
|
videoMessage.videoUrl = resData.data.video_url;
|
||||||
videoMessage.messageData = JSON.stringify(data.data);
|
videoMessage.messageData = JSON.stringify(resData.data);
|
||||||
await this.bookServiceBasic.UpdateBookTaskDetailVideoMessage(task.bookTaskDetailId, videoMessage);
|
await this.bookServiceBasic.UpdateBookTaskDetailVideoMessage(task.bookTaskDetailId, videoMessage);
|
||||||
await this.bookServiceBasic.UpdetedBookTaskData(task.bookTaskId, {
|
await this.bookServiceBasic.UpdetedBookTaskData(task.bookTaskId, {
|
||||||
status: BookTaskStatus.IMAGE_TO_VIDEO_SUCCESS,
|
status: BookTaskStatus.IMAGE_TO_VIDEO_SUCCESS,
|
||||||
@ -149,37 +202,37 @@ export class RunwayService {
|
|||||||
id: bookTaskDetail.id,
|
id: bookTaskDetail.id,
|
||||||
message: "runway合成视频完成",
|
message: "runway合成视频完成",
|
||||||
type: ResponseMessageType.RUNWAY_VIDEO,
|
type: ResponseMessageType.RUNWAY_VIDEO,
|
||||||
data: JSON.stringify(data.data)
|
data: JSON.stringify(resData.data)
|
||||||
}, task.messageName);
|
}, task.messageName);
|
||||||
break;
|
break;
|
||||||
} else if (data.data.status == '1') {
|
} else if (resData.data.status == '1') {
|
||||||
// 处理中
|
// 处理中
|
||||||
SendMessageToRenderer({
|
SendMessageToRenderer({
|
||||||
code: 1,
|
code: 1,
|
||||||
id: bookTaskDetail.id,
|
id: bookTaskDetail.id,
|
||||||
message: "runway合成视频处理中",
|
message: "runway合成视频处理中",
|
||||||
type: ResponseMessageType.RUNWAY_VIDEO,
|
type: ResponseMessageType.RUNWAY_VIDEO,
|
||||||
data: JSON.stringify(data.data)
|
data: JSON.stringify(resData.data)
|
||||||
}, task.messageName);
|
}, task.messageName);
|
||||||
} else {
|
} else {
|
||||||
// 没有完成
|
// 没有完成
|
||||||
if (data.data.status == '2') {
|
if (resData.data.status == '2') {
|
||||||
// 有报错信息直接返回错误
|
// 有报错信息直接返回错误
|
||||||
let videoMessage = cloneDeep(bookTaskDetail.videoMessage);
|
let videoMessage = cloneDeep(bookTaskDetail.videoMessage);
|
||||||
delete videoMessage.id;
|
delete videoMessage.id;
|
||||||
videoMessage.status = VideoStatus.FAIL;
|
videoMessage.status = VideoStatus.FAIL;
|
||||||
videoMessage.msg = data.data.msg;
|
videoMessage.msg = resData.data.msg;
|
||||||
videoMessage.taskId = taskId;
|
videoMessage.taskId = taskId;
|
||||||
videoMessage.messageData = JSON.stringify(data.data);
|
videoMessage.messageData = JSON.stringify(resData.data);
|
||||||
await this.bookServiceBasic.UpdateBookTaskDetailVideoMessage(bookTaskDetail.id, videoMessage);
|
await this.bookServiceBasic.UpdateBookTaskDetailVideoMessage(bookTaskDetail.id, videoMessage);
|
||||||
SendMessageToRenderer({
|
SendMessageToRenderer({
|
||||||
code: 0,
|
code: 0,
|
||||||
id: bookTaskDetail.id,
|
id: bookTaskDetail.id,
|
||||||
message: "runway合成视频失败,错误信息如下:" + data.data.msg,
|
message: "runway合成视频失败,错误信息如下:" + resData.data.msg,
|
||||||
type: ResponseMessageType.RUNWAY_VIDEO,
|
type: ResponseMessageType.RUNWAY_VIDEO,
|
||||||
data: JSON.stringify(data.data)
|
data: JSON.stringify(resData.data)
|
||||||
}, task.messageName);
|
}, task.messageName);
|
||||||
throw new Error(data.data.msg);
|
throw new Error(resData.data.msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 等待20秒后再次请求
|
// 等待20秒后再次请求
|
||||||
|
|||||||
@ -128,17 +128,17 @@ export class VideoGlobal {
|
|||||||
|
|
||||||
async ImageToVideo(task: TaskModal.Task): Promise<GeneralResponse.ErrorItem | GeneralResponse.SuccessItem> {
|
async ImageToVideo(task: TaskModal.Task): Promise<GeneralResponse.ErrorItem | GeneralResponse.SuccessItem> {
|
||||||
try {
|
try {
|
||||||
let { gptUrl, gptApiKey } = await this.gptService.RefreshGptSetting();
|
let { gptUrl, gptApiKey, useTransfer } = await this.gptService.RefreshGptSetting();
|
||||||
switch (task.type) {
|
switch (task.type) {
|
||||||
case BookBackTaskType.RUNWAY_VIDEO:
|
case BookBackTaskType.RUNWAY_VIDEO:
|
||||||
await this.runwayService.ImageToVideo(task, gptUrl, gptApiKey);
|
await this.runwayService.ImageToVideo(task, gptUrl, gptApiKey, useTransfer);
|
||||||
break;
|
break;
|
||||||
case BookBackTaskType.LUMA_VIDEO:
|
case BookBackTaskType.LUMA_VIDEO:
|
||||||
await this.lumaService.LumaImageToVideo(task, gptUrl, gptApiKey);
|
await this.lumaService.LumaImageToVideo(task, gptUrl, gptApiKey, useTransfer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BookBackTaskType.KLING_VIDEO:
|
case BookBackTaskType.KLING_VIDEO:
|
||||||
await this.klingService.KlingImageToVideo(task, gptUrl, gptApiKey);
|
await this.klingService.KlingImageToVideo(task, gptUrl, gptApiKey, useTransfer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -16,7 +16,6 @@ import { PublicMethod } from './Public/publicMethod'
|
|||||||
import { ImageStyleDefine } from '../define/iamgeStyleDefine'
|
import { ImageStyleDefine } from '../define/iamgeStyleDefine'
|
||||||
let tools = new Tools()
|
let tools = new Tools()
|
||||||
let pm = new PublicMethod(global)
|
let pm = new PublicMethod(global)
|
||||||
import { FLxuAPIImageType } from '../define/enum/image'
|
|
||||||
import JianyingService from './Service/jianying/jianyingService'
|
import JianyingService from './Service/jianying/jianyingService'
|
||||||
import VideoHandle from './Service/videoService/videoHandle'
|
import VideoHandle from './Service/videoService/videoHandle'
|
||||||
import { successMessage } from './Public/generalTools'
|
import { successMessage } from './Public/generalTools'
|
||||||
@ -691,11 +690,13 @@ async function SaveSDConfig(value) {
|
|||||||
|
|
||||||
if (!sd_config.flux) {
|
if (!sd_config.flux) {
|
||||||
let model = {
|
let model = {
|
||||||
model: value.flux_model ? value.flux_model : FLxuAPIImageType.FLUX
|
model: value.flux_model ? value.flux_model : 'flux',
|
||||||
|
useTransfer: value.useTransfer == null ? false : value.useTransfer
|
||||||
}
|
}
|
||||||
sd_config.flux = model
|
sd_config.flux = model
|
||||||
} else {
|
} else {
|
||||||
sd_config.flux.model = value.flux_model ? value.flux_model : FLxuAPIImageType.FLUX
|
sd_config.flux.model = value.flux_model ? value.flux_model : sd_config.flux.model
|
||||||
|
sd_config.flux.useTransfer = value.useTransfer == null ? false : value.useTransfer
|
||||||
}
|
}
|
||||||
|
|
||||||
await fspromises.writeFile(define.sd_setting, JSON.stringify(sd_config))
|
await fspromises.writeFile(define.sd_setting, JSON.stringify(sd_config))
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import { TagDefine } from '../../define/tagDefine'
|
|||||||
import { errorMessage } from '../Public/generalTools'
|
import { errorMessage } from '../Public/generalTools'
|
||||||
import { TaskManager } from '../Service/task/taskManage'
|
import { TaskManager } from '../Service/task/taskManage'
|
||||||
import { SoftWareServiceBasic } from '../Service/ServiceBasic/softwareServiceBasic'
|
import { SoftWareServiceBasic } from '../Service/ServiceBasic/softwareServiceBasic'
|
||||||
import { FLxuAPIImageType } from '../../define/enum/image'
|
|
||||||
|
|
||||||
let tagDefine = new TagDefine(global)
|
let tagDefine = new TagDefine(global)
|
||||||
export class Setting {
|
export class Setting {
|
||||||
@ -176,7 +175,9 @@ export class Setting {
|
|||||||
sd_model: sd_config.sd_model,
|
sd_model: sd_config.sd_model,
|
||||||
lora: sd_config.lora,
|
lora: sd_config.lora,
|
||||||
sampler: sd_config.sampler,
|
sampler: sd_config.sampler,
|
||||||
flux_model: sd_config.flux?.model ? sd_config.flux.model : FLxuAPIImageType.FLUX
|
flux_model: sd_config.flux?.model,
|
||||||
|
useTransfer:
|
||||||
|
sd_config.flux.useTransfer == undefined ? false : sd_config.flux.useTransfer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
96
src/model/Setting/mjSetting.d.ts
vendored
96
src/model/Setting/mjSetting.d.ts
vendored
@ -1,7 +1,10 @@
|
|||||||
import { MJImageType, MJRobotType } from "../../define/enum/mjEnum"
|
import { MJImageType, MJRobotType, MJSpeed } from "../../define/enum/mjEnum"
|
||||||
|
|
||||||
declare namespace MJSetting {
|
declare namespace MJSettingModel {
|
||||||
type ActionRemoteMJSetting = {
|
/**
|
||||||
|
* 代理模式配置数据模型
|
||||||
|
*/
|
||||||
|
type ActionRemoteMJSettingModel = {
|
||||||
id?: string
|
id?: string
|
||||||
accountId?: string
|
accountId?: string
|
||||||
channelId?: string
|
channelId?: string
|
||||||
@ -19,22 +22,10 @@ declare namespace MJSetting {
|
|||||||
updateTime?: Date
|
updateTime?: Date
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
type BrowserMJ = {
|
* 代理模式配置数据模型
|
||||||
id: string
|
*/
|
||||||
serviceId: string
|
type RemoteMJSettingModel = {
|
||||||
channelId: string
|
|
||||||
mjBotId: string
|
|
||||||
nijBotId: string
|
|
||||||
token: string
|
|
||||||
userAgent: string
|
|
||||||
userAgentCustom: boolean
|
|
||||||
createTime: Date
|
|
||||||
updateTime: Date
|
|
||||||
version: string
|
|
||||||
}
|
|
||||||
|
|
||||||
type RemoteMJ = {
|
|
||||||
id: string
|
id: string
|
||||||
accountId: string | null
|
accountId: string | null
|
||||||
channelId: string
|
channelId: string
|
||||||
@ -49,23 +40,47 @@ declare namespace MJSetting {
|
|||||||
timeoutMinutes: number
|
timeoutMinutes: number
|
||||||
userAgent: string
|
userAgent: string
|
||||||
userToken: string
|
userToken: string
|
||||||
createTime: Date
|
createTime?: Date
|
||||||
updateTime: Date
|
updateTime?: Date
|
||||||
version: string
|
version?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type APIMj = {
|
/**
|
||||||
|
* 浏览器模式配置数据模型
|
||||||
|
*/
|
||||||
|
type BrowserMJSettingModel = {
|
||||||
|
id: string
|
||||||
|
serviceId: string
|
||||||
|
channelId: string
|
||||||
|
mjBotId: string
|
||||||
|
nijBotId: string
|
||||||
|
token: string
|
||||||
|
userAgent: string
|
||||||
|
userAgentCustom: boolean
|
||||||
|
createTime?: Date
|
||||||
|
updateTime?: Date
|
||||||
|
version?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MJ API 设置
|
||||||
|
*/
|
||||||
|
type MJAPISettingModel = {
|
||||||
id: string
|
id: string
|
||||||
mjApiUrl: string
|
mjApiUrl: string
|
||||||
mjSpeed: string // MJ出图的速度模式
|
mjSpeed: MJSpeed // MJ出图的速度模式
|
||||||
apiKey: string
|
apiKey: string
|
||||||
createTime: Date
|
useTransfer: boolean // 是否国内转发
|
||||||
updateTime: Date
|
createTime?: Date
|
||||||
version: string
|
updateTime?: Date
|
||||||
|
version?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type MjSetting = {
|
/**
|
||||||
id: string
|
* MJ 基础设置
|
||||||
|
*/
|
||||||
|
type MjSimpleSettingModel = {
|
||||||
type: MJImageType
|
type: MJImageType
|
||||||
requestModel: MJImageType
|
requestModel: MJImageType
|
||||||
selectRobot: MJRobotType
|
selectRobot: MJRobotType
|
||||||
@ -74,11 +89,22 @@ declare namespace MJSetting {
|
|||||||
imageSuffix: string
|
imageSuffix: string
|
||||||
taskCount: number
|
taskCount: number
|
||||||
spaceTime: number
|
spaceTime: number
|
||||||
createTime: Date
|
}
|
||||||
updateTime: Date
|
|
||||||
version: string
|
/**
|
||||||
apiSetting: APIMj
|
* MJ 代理设置模型
|
||||||
remoteSetting: RemoteMJ
|
*/
|
||||||
browserSetting: BrowserMJ
|
type MJRemoteSimpleSettingModel = {
|
||||||
|
useTransfer: boolean // 是否国内转发
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MJ 全局设置
|
||||||
|
*/
|
||||||
|
type MJ_GlobalSettingModel = {
|
||||||
|
mj_simpleSetting: MjSimpleSettingModel
|
||||||
|
mj_apiSetting: MJAPISettingModel
|
||||||
|
mj_browserSetting: BrowserMJSettingModel
|
||||||
|
mj_remoteSimpleSetting: MJRemoteSimpleSettingModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
src/model/book/bookTaskDetail.d.ts
vendored
1
src/model/book/bookTaskDetail.d.ts
vendored
@ -56,6 +56,7 @@ declare namespace BookTaskDetail {
|
|||||||
image_url?: string; // 图片地址(参考图,支持第三方图片地址、Base64)
|
image_url?: string; // 图片地址(参考图,支持第三方图片地址、Base64)
|
||||||
image_end_url?: string; // 尾帧图片地址(支持第三方图片地址、Base64)
|
image_end_url?: string; // 尾帧图片地址(支持第三方图片地址、Base64)
|
||||||
notify_hook?: string; // 回调地址
|
notify_hook?: string; // 回调地址
|
||||||
|
request_model?: string; // 请求的模型,快速还是慢速
|
||||||
}
|
}
|
||||||
|
|
||||||
type klingOptions = {
|
type klingOptions = {
|
||||||
|
|||||||
1
src/model/option/option.d.ts
vendored
1
src/model/option/option.d.ts
vendored
@ -1,3 +1,4 @@
|
|||||||
|
import { MJImageType, MJRobotType } from "@/define/enum/mjEnum"
|
||||||
import { OptionType } from "@/define/enum/option"
|
import { OptionType } from "@/define/enum/option"
|
||||||
|
|
||||||
declare namespace OptionModel {
|
declare namespace OptionModel {
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { OptionType } from '@/define/enum/option'
|
|||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
/** 通过Key获取指定的option */
|
/** 通过Key获取指定的option */
|
||||||
GetOptionByKey: async (key: string) =>
|
GetOptionByKey: async (key: string | string[]) =>
|
||||||
await ipcRenderer.invoke(DEFINE_STRING.OPTIONS.GET_OPTION_BY_KEY, key),
|
await ipcRenderer.invoke(DEFINE_STRING.OPTIONS.GET_OPTION_BY_KEY, key),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
30
src/renderer/src/common/SDFluxCommon.ts
Normal file
30
src/renderer/src/common/SDFluxCommon.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { define } from "@/define/define"
|
||||||
|
import { OptionKeyName } from "@/define/enum/option";
|
||||||
|
import { ValidateJson } from "@/define/Tools/validate";
|
||||||
|
import axios from "axios";
|
||||||
|
import { isEmpty } from "lodash";
|
||||||
|
/**
|
||||||
|
* 远程的FLUX模型列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async function GetRemoteFluxModelList() {
|
||||||
|
debugger
|
||||||
|
let res = await axios.get(define.lms + `/lms/LaitoolOptions/GetSimpleOptions/LaitoolFluxApiModelList`);
|
||||||
|
if (res.data.code != 1) {
|
||||||
|
throw new Error(res.data.message)
|
||||||
|
}
|
||||||
|
let data = res.data.data.filter(item => item.key == "LaitoolFluxApiModelList")
|
||||||
|
if (data.length != 1) {
|
||||||
|
throw new Error("获取远程FLUX API模型列表失败")
|
||||||
|
}
|
||||||
|
if (isEmpty(data[0].value) || !ValidateJson(data[0].value)) {
|
||||||
|
throw new Error("FLUX API模型列表数据异常,请联系管理员!")
|
||||||
|
}
|
||||||
|
return JSON.parse(data[0].value)
|
||||||
|
}
|
||||||
|
|
||||||
|
let SDFluxCommon = {
|
||||||
|
GetRemoteFluxModelList
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SDFluxCommon
|
||||||
@ -1,6 +1,7 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import { OptionKeyName, OptionType } from '@/define/enum/option'
|
import { OptionKeyName, OptionType } from '@/define/enum/option'
|
||||||
import { useOptionStore } from '@/stores/option'
|
import { useOptionStore } from '@/stores/option'
|
||||||
|
import SDFluxCommon from './SDFluxCommon'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化特殊字符数据,用于文案的相关处理
|
* 初始化特殊字符数据,用于文案的相关处理
|
||||||
@ -90,8 +91,54 @@ async function InitTTSGlobalSetting() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化模型列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async function InitFluxModelList(isMust: boolean = false): Promise<Array<{ label: string, value: string }>> {
|
||||||
|
debugger
|
||||||
|
let initData = []
|
||||||
|
if (!isMust) {
|
||||||
|
let FLUX_APIModelListData = await window.options.GetOptionByKey(OptionKeyName.FLUX_APIModelList);
|
||||||
|
if (FLUX_APIModelListData.code == 0) {
|
||||||
|
window.api.showGlobalMessageDialog(FLUX_APIModelListData);
|
||||||
|
return initData;
|
||||||
|
}
|
||||||
|
if (FLUX_APIModelListData.data == null) {
|
||||||
|
initData = await SDFluxCommon.GetRemoteFluxModelList()
|
||||||
|
let saveRes = await window.options.ModifyOptionByKey(
|
||||||
|
OptionKeyName.FLUX_APIModelList,
|
||||||
|
JSON.stringify(initData),
|
||||||
|
OptionType.JOSN
|
||||||
|
)
|
||||||
|
if (saveRes.code == 0) {
|
||||||
|
window.api.showGlobalMessageDialog(saveRes)
|
||||||
|
return initData
|
||||||
|
} else {
|
||||||
|
return initData
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return JSON.parse(FLUX_APIModelListData.data.value)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
initData = await SDFluxCommon.GetRemoteFluxModelList()
|
||||||
|
let saveRes = await window.options.ModifyOptionByKey(
|
||||||
|
OptionKeyName.FLUX_APIModelList,
|
||||||
|
JSON.stringify(initData),
|
||||||
|
OptionType.JOSN
|
||||||
|
)
|
||||||
|
if (saveRes.code == 0) {
|
||||||
|
window.api.showGlobalMessageDialog(saveRes)
|
||||||
|
return initData
|
||||||
|
} else {
|
||||||
|
return initData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let InitCommon = {
|
let InitCommon = {
|
||||||
InitSpecialCharacters,
|
InitSpecialCharacters,
|
||||||
InitTTSGlobalSetting
|
InitTTSGlobalSetting,
|
||||||
|
InitFluxModelList
|
||||||
}
|
}
|
||||||
export default InitCommon
|
export default InitCommon
|
||||||
|
|||||||
@ -95,6 +95,8 @@ async function GetBookTaskDetailOption() {
|
|||||||
}
|
}
|
||||||
if (ValidateJson(videoMessage.value.lumaOptions)) {
|
if (ValidateJson(videoMessage.value.lumaOptions)) {
|
||||||
lumaOptions.value = JSON.parse(videoMessage.value.lumaOptions)
|
lumaOptions.value = JSON.parse(videoMessage.value.lumaOptions)
|
||||||
|
lumaOptions.value.request_model =
|
||||||
|
lumaOptions.value.request_model == null ? 'fast' : lumaOptions.value.request_model
|
||||||
lumaOptions.value.image_url = videoMessage.value.imageUrl
|
lumaOptions.value.image_url = videoMessage.value.imageUrl
|
||||||
}
|
}
|
||||||
if (ValidateJson(videoMessage.value.klingOptions)) {
|
if (ValidateJson(videoMessage.value.klingOptions)) {
|
||||||
|
|||||||
@ -30,6 +30,16 @@
|
|||||||
<n-form-item-gi :span="12">
|
<n-form-item-gi :span="12">
|
||||||
<n-image width="100" :src="lumaOptions.image_end_url"></n-image>
|
<n-image width="100" :src="lumaOptions.image_end_url"></n-image>
|
||||||
</n-form-item-gi>
|
</n-form-item-gi>
|
||||||
|
<n-form-item-gi :span="4" label="速度模式">
|
||||||
|
<n-select
|
||||||
|
v-model:value="lumaOptions.request_model"
|
||||||
|
:options="[
|
||||||
|
{ label: 'FAST', value: 'fast' },
|
||||||
|
{ label: 'RELAX', value: 'relax' }
|
||||||
|
]"
|
||||||
|
placeholder="请选择速度"
|
||||||
|
></n-select>
|
||||||
|
</n-form-item-gi>
|
||||||
</n-grid>
|
</n-grid>
|
||||||
</n-form>
|
</n-form>
|
||||||
</div>
|
</div>
|
||||||
@ -37,7 +47,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { NForm, NImage, NGrid, NFormItemGi, NInput, NCheckbox } from 'naive-ui'
|
import { NForm, NImage, NSelect, NGrid, NFormItemGi, NInput, NCheckbox } from 'naive-ui'
|
||||||
|
|
||||||
let props = defineProps({
|
let props = defineProps({
|
||||||
lumaOptions: undefined
|
lumaOptions: undefined
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
pane-wrapper-style="margin: 0 -4px"
|
pane-wrapper-style="margin: 0 -4px"
|
||||||
pane-style="padding-left: 4px; padding-right: 4px; box-sizing: border-box;"
|
pane-style="padding-left: 4px; padding-right: 4px; box-sizing: border-box;"
|
||||||
>
|
>
|
||||||
<n-tab-pane name="mj_setting" tab="MJ设置"> <MJSetting /> </n-tab-pane>
|
<n-tab-pane name="mj_setting" tab="MJ设置"> <MJSettingHome /> </n-tab-pane>
|
||||||
<n-tab-pane name="sd_setting" tab="SD设置"> <SDSetting /> </n-tab-pane>
|
<n-tab-pane name="sd_setting" tab="SD设置"> <SDSetting /> </n-tab-pane>
|
||||||
<n-tab-pane name="export_video_setting" tab="导出视频设置">
|
<n-tab-pane name="export_video_setting" tab="导出视频设置">
|
||||||
<VideoGenerateSetting />
|
<VideoGenerateSetting />
|
||||||
@ -28,7 +28,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||||
import { useMessage, NTabPane, NTabs, NCard } from 'naive-ui'
|
import { useMessage, NTabPane, NTabs, NCard } from 'naive-ui'
|
||||||
import MJSetting from '../../Setting/MJSetting.vue'
|
import MJSettingHome from '../../Setting/MJSetting/MJSettingHome.vue'
|
||||||
import SDSetting from '../../Setting/SDSetting.vue'
|
import SDSetting from '../../Setting/SDSetting.vue'
|
||||||
import VideoGenerateSetting from '../../Setting/VideoGenerateSetting.vue'
|
import VideoGenerateSetting from '../../Setting/VideoGenerateSetting.vue'
|
||||||
import WatermarkSetting from '../../Setting/WatermarkSetting.vue'
|
import WatermarkSetting from '../../Setting/WatermarkSetting.vue'
|
||||||
@ -39,7 +39,7 @@ export default defineComponent({
|
|||||||
NTabPane,
|
NTabPane,
|
||||||
NTabs,
|
NTabs,
|
||||||
NCard,
|
NCard,
|
||||||
MJSetting,
|
MJSettingHome,
|
||||||
SDSetting,
|
SDSetting,
|
||||||
VideoGenerateSetting,
|
VideoGenerateSetting,
|
||||||
WatermarkSetting,
|
WatermarkSetting,
|
||||||
|
|||||||
@ -1,522 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div style="overflow: auto; height: 100%">
|
|
||||||
<n-card title="基础设置" size="medium" hoverable style="min-width: 850px">
|
|
||||||
<n-form :model="mjSetting" ref="sampleRef" :rules="sampleRules">
|
|
||||||
<div style="display: flex; align-items: center">
|
|
||||||
<n-form-item label="出图模式" style="width: 150px" path="requestModel">
|
|
||||||
<n-select
|
|
||||||
:options="request_model_options"
|
|
||||||
v-model:value="mjSetting.requestModel"
|
|
||||||
placeholder="请选择出图模式"
|
|
||||||
></n-select>
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item
|
|
||||||
label="选择生图机器人"
|
|
||||||
path="selectRobot"
|
|
||||||
style="width: 120px; margin-left: 10px"
|
|
||||||
>
|
|
||||||
<n-select
|
|
||||||
:options="select_robot_options"
|
|
||||||
v-model:value="mjSetting.selectRobot"
|
|
||||||
@update:value="UpdateSelectRobot"
|
|
||||||
></n-select>
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item label="机器人模型" style="width: 120px; margin-left: 10px" path="imageModel">
|
|
||||||
<n-select
|
|
||||||
placeholder="请选择机器人模型"
|
|
||||||
:options="image_model_options"
|
|
||||||
v-model:value="mjSetting.imageModel"
|
|
||||||
></n-select>
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item label="生图尺寸" style="width: 120px; margin-left: 10px" path="imageScale">
|
|
||||||
<n-select
|
|
||||||
placeholder="请选择生图尺寸"
|
|
||||||
:options="image_scale_options"
|
|
||||||
v-model:value="mjSetting.imageScale"
|
|
||||||
></n-select>
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item label="命令后缀" style="width: 160px; margin-left: 10px" path="imageSuffix">
|
|
||||||
<n-input v-model:value="mjSetting.imageSuffix" placeholder="请输入后缀命令"></n-input>
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item label="生图任务量" style="width: 100px; margin-left: 10px" path="taskCount">
|
|
||||||
<n-input-number
|
|
||||||
v-model:value="mjSetting.taskCount"
|
|
||||||
:show-button="false"
|
|
||||||
placeholder="MJ并发出图数量"
|
|
||||||
:min="1"
|
|
||||||
:max="20"
|
|
||||||
></n-input-number>
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item label="间隔时间(s)" style="width: 100px; margin-left: 10px" path="spaceTime">
|
|
||||||
<n-input-number
|
|
||||||
v-model:value="mjSetting.spaceTime"
|
|
||||||
:show-button="false"
|
|
||||||
placeholder="请输入间隔时间(s)"
|
|
||||||
:min="1"
|
|
||||||
:max="30"
|
|
||||||
></n-input-number>
|
|
||||||
</n-form-item>
|
|
||||||
</div>
|
|
||||||
</n-form>
|
|
||||||
</n-card>
|
|
||||||
<n-card title="API模式设置" hoverable style="margin-top: 10px; min-width: 850px" size="medium">
|
|
||||||
<n-form :model="mjSetting.apiSetting">
|
|
||||||
<div style="display: flex">
|
|
||||||
<n-form-item
|
|
||||||
label="选择出图的API"
|
|
||||||
style="width: 160px; margin-left: 10px"
|
|
||||||
path="mjApiUrl"
|
|
||||||
>
|
|
||||||
<n-select
|
|
||||||
:options="mj_api_options"
|
|
||||||
v-model:value="mjSetting.apiSetting.mjApiUrl"
|
|
||||||
placeholder="选择出图的中转API"
|
|
||||||
/>
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item style="margin-left: 10px" path="mj_api_url">
|
|
||||||
<n-button type="success" @click="openGptBuyUrl">购买</n-button>
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item
|
|
||||||
label="选择出图速度模式"
|
|
||||||
style="width: 160px; margin-left: 10px"
|
|
||||||
path="mjSpeed"
|
|
||||||
>
|
|
||||||
<n-select
|
|
||||||
:options="mj_speed_options"
|
|
||||||
v-model:value="mjSetting.apiSetting.mjSpeed"
|
|
||||||
placeholder="选择出图速度模式"
|
|
||||||
/>
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item label="输入API密钥" style="width: 160px; margin-left: 10px" path="apiKey">
|
|
||||||
<n-input
|
|
||||||
type="password"
|
|
||||||
placeholder="请输入密钥"
|
|
||||||
show-password-on="mousedown"
|
|
||||||
v-model:value="mjSetting.apiSetting.apiKey"
|
|
||||||
></n-input>
|
|
||||||
</n-form-item>
|
|
||||||
</div>
|
|
||||||
</n-form>
|
|
||||||
</n-card>
|
|
||||||
|
|
||||||
<n-card title="代理模式设置" hoverable style="margin-top: 10px; min-width: 850px">
|
|
||||||
<n-button type="info" @click="AddMultiMjAccount()">账号管理</n-button>
|
|
||||||
</n-card>
|
|
||||||
|
|
||||||
<n-card title="浏览器模式设置" hoverable style="margin-top: 10px; min-width: 850px">
|
|
||||||
<n-form :model="mjSetting.browserSetting">
|
|
||||||
<div style="display: flex; margin-top: 10px">
|
|
||||||
<n-form-item>
|
|
||||||
<n-button type="info" @click="OpenDiscordWindow">打开登录MJ</n-button>
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item label="服务器ID" style="width: 200px; margin-left: 5px" path="serviceId">
|
|
||||||
<n-input
|
|
||||||
v-model:value="mjSetting.browserSetting.serviceId"
|
|
||||||
placeholder="登录MJ后切换服务器自动获取"
|
|
||||||
/>
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item label="频道ID" style="width: 200px; margin-left: 10px" path="channelId">
|
|
||||||
<n-input
|
|
||||||
v-model:value="mjSetting.browserSetting.channelId"
|
|
||||||
placeholder="登录MJ后切换频道自动获取"
|
|
||||||
/>
|
|
||||||
</n-form-item>
|
|
||||||
<n-form-item label="用户token" style="width: 300px; margin-left: 10px" path="token">
|
|
||||||
<n-input
|
|
||||||
v-model:value="mjSetting.browserSetting.token"
|
|
||||||
placeholder="登录MJ后切换服务器自动获取"
|
|
||||||
/>
|
|
||||||
</n-form-item>
|
|
||||||
</div>
|
|
||||||
<n-form-item label="用户Agent" style="width: 810px" path="userAgent">
|
|
||||||
<n-input
|
|
||||||
v-model:value="mjSetting.browserSetting.userAgent"
|
|
||||||
placeholder="登录MJ后切换服务器自动获取(可自定义)"
|
|
||||||
style="margin-right: 10px"
|
|
||||||
/>
|
|
||||||
<n-tooltip trigger="hover" style="background-color: aliceblue; color: black">
|
|
||||||
<template #trigger>
|
|
||||||
<n-checkbox
|
|
||||||
v-model:checked="mjSetting.browserSetting.userAgentCustom"
|
|
||||||
style="width: 100px"
|
|
||||||
>
|
|
||||||
自定义
|
|
||||||
</n-checkbox>
|
|
||||||
</template>
|
|
||||||
开启自定义需要手动填写userAgent。可以填入浏览器的userAgent
|
|
||||||
</n-tooltip>
|
|
||||||
</n-form-item>
|
|
||||||
</n-form>
|
|
||||||
</n-card>
|
|
||||||
<n-button type="info" round @click="SaveMjSetting" style="margin-top: 10px"
|
|
||||||
>保存MJ配置</n-button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { defineComponent, ref, onMounted, computed, toRaw, h } from 'vue'
|
|
||||||
import {
|
|
||||||
NButton,
|
|
||||||
useMessage,
|
|
||||||
useDialog,
|
|
||||||
NDataTable,
|
|
||||||
NForm,
|
|
||||||
NFormItem,
|
|
||||||
NInput,
|
|
||||||
NDivider,
|
|
||||||
NCheckbox,
|
|
||||||
NSelect,
|
|
||||||
NTooltip,
|
|
||||||
NIcon,
|
|
||||||
NInputNumber,
|
|
||||||
NCard,
|
|
||||||
NSpin
|
|
||||||
} from 'naive-ui'
|
|
||||||
import { DEFINE_STRING } from '../../../../define/define_string'
|
|
||||||
import { Reload } from '@vicons/ionicons5'
|
|
||||||
import { isEmpty, max, min } from 'lodash'
|
|
||||||
import { MJImageType } from '../../../../define/enum/mjEnum'
|
|
||||||
import AddMultiRemoteMj from './Components/AddMultiRemoteMj.vue'
|
|
||||||
|
|
||||||
let message = useMessage()
|
|
||||||
let dialog = useDialog()
|
|
||||||
let sampleRef = ref(null)
|
|
||||||
let select_robot_options = ref([
|
|
||||||
{
|
|
||||||
label: 'MJ',
|
|
||||||
value: 'mj'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'NIJI',
|
|
||||||
value: 'niji'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
let mj_speed_options = ref([
|
|
||||||
{
|
|
||||||
label: 'RELAXED',
|
|
||||||
value: 'relaxed'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'FAST',
|
|
||||||
value: 'fast'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
let mjSetting = ref({
|
|
||||||
id: null,
|
|
||||||
imageModel: null,
|
|
||||||
imageScale: null,
|
|
||||||
imageSuffix: null,
|
|
||||||
requestModel: null,
|
|
||||||
type: null,
|
|
||||||
selectRobot: null,
|
|
||||||
spaceTime: 6,
|
|
||||||
taskCount: 3,
|
|
||||||
createTime: null,
|
|
||||||
updateTime: null,
|
|
||||||
version: null,
|
|
||||||
remoteSetting: {
|
|
||||||
accountId: null,
|
|
||||||
channelId: null,
|
|
||||||
coreSize: 3,
|
|
||||||
guildId: null,
|
|
||||||
mjBotChannelId: null,
|
|
||||||
nijiBotChannelId: null,
|
|
||||||
queueSize: 6,
|
|
||||||
remark: null, // 机器码
|
|
||||||
remixAutoSubmit: false,
|
|
||||||
timeoutMinutes: 6,
|
|
||||||
userAgent: null,
|
|
||||||
userToken: null
|
|
||||||
},
|
|
||||||
apiSetting: {
|
|
||||||
id: null,
|
|
||||||
mjApiUrl: null,
|
|
||||||
mjSpeed: null,
|
|
||||||
apiKey: null
|
|
||||||
},
|
|
||||||
browserSetting: {
|
|
||||||
id: null,
|
|
||||||
serviceId: null,
|
|
||||||
channelId: null,
|
|
||||||
mjBotId: null,
|
|
||||||
nijBotId: null,
|
|
||||||
token: null,
|
|
||||||
userAgent: null,
|
|
||||||
userAgentCustom: false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
let image_scale_options = ref([])
|
|
||||||
let image_model_options = ref([])
|
|
||||||
let tmp_image_model_options = []
|
|
||||||
let request_model_options = ref([])
|
|
||||||
let mj_api_options = ref([])
|
|
||||||
|
|
||||||
let computedSuffix = () => {
|
|
||||||
let text = image_model_options.value.findIndex((item) => {
|
|
||||||
return item.value == mjSetting.value.imageModel
|
|
||||||
})
|
|
||||||
if (text == -1) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let sc = image_scale_options.value.findIndex((item) => {
|
|
||||||
return item.value == mjSetting.value.imageScale
|
|
||||||
})
|
|
||||||
let dd = ` --${image_model_options.value[text].text} --ar ${image_scale_options.value[sc].text}`
|
|
||||||
mjSetting.value.imageSuffix = dd
|
|
||||||
return dd
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化现在设置的数据
|
|
||||||
async function InitData() {
|
|
||||||
// 获取到的是当前的配置信息
|
|
||||||
let res = await window.setting.GetMJSettingTreeData()
|
|
||||||
if (res.code == 0) {
|
|
||||||
message.error(res.message)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!res.data.apiSetting) {
|
|
||||||
delete res.data.apiSetting
|
|
||||||
}
|
|
||||||
if (!res.data.remoteSetting) {
|
|
||||||
delete res.data.remoteSetting
|
|
||||||
}
|
|
||||||
if (!res.data.browserSetting) {
|
|
||||||
delete res.data.browserSetting
|
|
||||||
}
|
|
||||||
|
|
||||||
mjSetting.value = Object.assign(mjSetting.value, res.data)
|
|
||||||
|
|
||||||
console.log(res)
|
|
||||||
|
|
||||||
await window.mj.GetMJImageScale((value) => {
|
|
||||||
if (value.code == 0) {
|
|
||||||
message.error(value.message)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
image_scale_options.value = value.data
|
|
||||||
if (image_scale_options.value.length > 0 && mjSetting.value.imageScale == null) {
|
|
||||||
mjSetting.value.imageScale = image_scale_options.value[0].value
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
await window.mj.GetMJImageRobotModel((value) => {
|
|
||||||
if (value.code == 0) {
|
|
||||||
message.error(value.message)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
image_model_options.value = value.data
|
|
||||||
tmp_image_model_options = value.data
|
|
||||||
if (image_model_options.value.length > 0 && mjSetting.value.imageModel == null) {
|
|
||||||
mjSetting.value.imageModel = image_model_options.value[0].value
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
await window.mj.GetMJGenerateCategory((value) => {
|
|
||||||
if (value.code == 0) {
|
|
||||||
message.error(value.message)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
request_model_options.value = value.data.filter((item) => !item.disable)
|
|
||||||
if (request_model_options.value.length > 0 && mjSetting.value.requestModel == null) {
|
|
||||||
mjSetting.value.requestModel = request_model_options.value[0].value
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
await window.api.getGptBusinessOption('all', (value) => {
|
|
||||||
if (value.code == 0) {
|
|
||||||
message.error(value.message)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mj_api_options.value = value.data.filter((item) => item.mj_url)
|
|
||||||
if (mj_api_options.value.length > 0 && mjSetting.value.apiSetting.mjApiUrl == null) {
|
|
||||||
mjSetting.value.apiSetting.mjApiUrl = mj_api_options.value[0].value
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
// 监听浏览器设置的中信息
|
|
||||||
window.api.setEventListen([DEFINE_STRING.DISCORD.OPERATE_REFRASH_DISCORD_URL], (value) => {
|
|
||||||
if (value.code == 0) {
|
|
||||||
message.error(value.message)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 保存数据
|
|
||||||
console.log(value)
|
|
||||||
if (value.type == DEFINE_STRING.DISCORD_SIMPLE_DATA_TYPE.URL) {
|
|
||||||
mjSetting.value.browserSetting.serviceId = value.data.serviceID
|
|
||||||
mjSetting.value.browserSetting.channelId = value.data.channelID
|
|
||||||
} else if (value.type == DEFINE_STRING.DISCORD_SIMPLE_DATA_TYPE.TOKEN) {
|
|
||||||
mjSetting.value.browserSetting.token = value.data.authorization
|
|
||||||
if (!mjSetting.value.browserSetting.userAgentCustom) {
|
|
||||||
mjSetting.value.browserSetting.userAgent = value.data.userAgent
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
message.error('未知的数据类型')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
await InitData()
|
|
||||||
|
|
||||||
if (mjSetting.value.apiSetting.mjSpeed == null) {
|
|
||||||
mjSetting.value.apiSetting.mjSpeed = mj_speed_options.value[0].value
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开discord窗口
|
|
||||||
*/
|
|
||||||
async function OpenDiscordWindow() {
|
|
||||||
await window.api.OpenDiscordWindow((value) => {
|
|
||||||
if (value.code == 0) {
|
|
||||||
message.error(value.message)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 基础配置的必填检测
|
|
||||||
let sampleRules = {
|
|
||||||
imageModel: [{ required: true, message: '请选择机器人模型', trigger: 'blur' }],
|
|
||||||
imageScale: [{ required: true, message: '请选择生图尺寸', trigger: 'blur' }],
|
|
||||||
requestModel: [{ required: true, message: '请选择出图模式', trigger: 'blur' }],
|
|
||||||
selectRobot: [{ required: true, message: '请选择生图机器人', trigger: 'blur' }]
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存MJ配置
|
|
||||||
*/
|
|
||||||
async function SaveMjSetting(e) {
|
|
||||||
// 在保存的时候要进行数据保存
|
|
||||||
|
|
||||||
e.preventDefault()
|
|
||||||
sampleRef.value?.validate(async (errors) => {
|
|
||||||
if (errors) {
|
|
||||||
message.error('请检查必填字段')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// mjSetting.value.imageSuffix = image_suffix.value
|
|
||||||
|
|
||||||
// 通过选择的请求模式判断哪些是要校验的
|
|
||||||
let request_model = mjSetting.value.requestModel
|
|
||||||
if (request_model == MJImageType.API_MJ) {
|
|
||||||
// API模式,检查必填数据
|
|
||||||
if (
|
|
||||||
mjSetting.value.apiSetting == null ||
|
|
||||||
mjSetting.value.apiSetting.mjApiUrl == null ||
|
|
||||||
mjSetting.value.apiSetting.mjSpeed == null ||
|
|
||||||
mjSetting.value.apiSetting.apiKey == null
|
|
||||||
) {
|
|
||||||
message.error('请检查API模式设置的必填字段')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request_model == MJImageType.REMOTE_MJ) {
|
|
||||||
// 检查是不是有代理账号
|
|
||||||
let remoteMjRes = await window.setting.GetRemoteMJSettings()
|
|
||||||
if (remoteMjRes.code == 0) {
|
|
||||||
message.error('获取代理MJ配置失败')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remoteMjRes.data.length <= 0) {
|
|
||||||
message.error('请先添加代理模式的配置')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (request_model == MJImageType.BROWSER_MJ) {
|
|
||||||
// 浏览器模式,检查必填数据
|
|
||||||
if (
|
|
||||||
mjSetting.value.browserSetting == null ||
|
|
||||||
mjSetting.value.browserSetting.serviceId == null ||
|
|
||||||
mjSetting.value.browserSetting.channelId == null ||
|
|
||||||
mjSetting.value.browserSetting.token == null ||
|
|
||||||
mjSetting.value.browserSetting.userAgent == null
|
|
||||||
) {
|
|
||||||
message.error('请检查浏览器模式设置的必填字段')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 开始保存数据
|
|
||||||
let res = await window.setting.SaveMJSettingTreeData(toRaw(mjSetting.value))
|
|
||||||
if (res.code == 0) {
|
|
||||||
window.api.showGlobalMessageDialog({ code: 0, message: res.message })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mjSetting.value = res.data
|
|
||||||
// 判断当前的模式
|
|
||||||
if (mjSetting.value.requestModel == MJImageType.REMOTE_MJ) {
|
|
||||||
window.api.showGlobalMessageDialog({
|
|
||||||
code: 1,
|
|
||||||
message: `数据保存成功,当前模式为代理模式`
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
window.api.showGlobalMessageDialog({ code: 1, message: '添加成功' })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新选择的机器人时触发的方法
|
|
||||||
*/
|
|
||||||
async function UpdateSelectRobot(value) {
|
|
||||||
// 刷新数据
|
|
||||||
image_model_options.value = tmp_image_model_options.filter((item) => {
|
|
||||||
return item.type == value
|
|
||||||
})
|
|
||||||
|
|
||||||
// 判断当前选中的机器人是不是在当前的数据中
|
|
||||||
if (
|
|
||||||
image_model_options.value.findIndex((item) => {
|
|
||||||
return item.value == mjSetting.value.imageModel
|
|
||||||
}) == -1
|
|
||||||
) {
|
|
||||||
mjSetting.value.imageModel =
|
|
||||||
image_model_options.value.length > 0 ? image_model_options.value[0].value : null
|
|
||||||
}
|
|
||||||
|
|
||||||
// 刷新命令后缀
|
|
||||||
mjSetting.value.imageSuffix = computedSuffix()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开购买GPT的地址
|
|
||||||
*/
|
|
||||||
async function openGptBuyUrl() {
|
|
||||||
let tmp_gb = mj_api_options.value.filter(
|
|
||||||
(item) => item.value == mjSetting.value.apiSetting.mjApiUrl
|
|
||||||
)
|
|
||||||
if (tmp_gb.length == 0) {
|
|
||||||
message.error('当前选择的服务商没有购买地址!')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let buy_url = tmp_gb[0].buy_url
|
|
||||||
if (isEmpty(buy_url)) {
|
|
||||||
message.error('当前选择的服务商没有购买地址!')
|
|
||||||
} else {
|
|
||||||
window.api.openGptBuyUrl(buy_url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加多个账号,这样可以同时跑多个账号
|
|
||||||
*/
|
|
||||||
async function AddMultiMjAccount() {
|
|
||||||
let dW = window.innerWidth * 0.9
|
|
||||||
let dH = window.innerHeight * 0.9
|
|
||||||
dialog.create({
|
|
||||||
showIcon: false,
|
|
||||||
title: '管理代理模式MJ账号',
|
|
||||||
content: () => h(AddMultiRemoteMj, { height: dH }),
|
|
||||||
style: `min-width : 600px; width : ${dW}px; height : ${dH}px; padding-right : 5px;`,
|
|
||||||
maskClosable: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@ -0,0 +1,95 @@
|
|||||||
|
<template>
|
||||||
|
<div class="mj-api-setting">
|
||||||
|
<n-card title="API模式设置" hoverable style="margin-top: 10px; min-width: 850px" size="medium">
|
||||||
|
<n-form :model="optionStore.MJ_GlobalSetting.mj_apiSetting">
|
||||||
|
<div style="display: flex">
|
||||||
|
<n-form-item
|
||||||
|
label="选择出图的API"
|
||||||
|
style="width: 160px; margin-left: 10px"
|
||||||
|
path="mjApiUrl"
|
||||||
|
>
|
||||||
|
<n-select
|
||||||
|
:options="mjAPIURLOptions"
|
||||||
|
v-model:value="optionStore.MJ_GlobalSetting.mj_apiSetting.mjApiUrl"
|
||||||
|
placeholder="选择出图的中转API"
|
||||||
|
/>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item style="margin-left: 10px" path="mj_api_url">
|
||||||
|
<n-button type="success" @click="openGptBuyUrl">购买</n-button>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item
|
||||||
|
label="选择出图速度模式"
|
||||||
|
style="width: 160px; margin-left: 10px"
|
||||||
|
path="mjSpeed"
|
||||||
|
>
|
||||||
|
<n-select
|
||||||
|
:options="mjImageSpeedOptions"
|
||||||
|
v-model:value="optionStore.MJ_GlobalSetting.mj_apiSetting.mjSpeed"
|
||||||
|
placeholder="选择出图速度模式"
|
||||||
|
/>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="输入API密钥" style="width: 160px; margin-left: 10px" path="apiKey">
|
||||||
|
<n-input
|
||||||
|
type="password"
|
||||||
|
placeholder="请输入密钥"
|
||||||
|
show-password-on="mousedown"
|
||||||
|
v-model:value="optionStore.MJ_GlobalSetting.mj_apiSetting.apiKey"
|
||||||
|
></n-input>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item
|
||||||
|
style="width: 120px; margin-left: 30px"
|
||||||
|
path="useTransfer"
|
||||||
|
label="是否国内转发"
|
||||||
|
>
|
||||||
|
<n-select
|
||||||
|
v-model:value="optionStore.MJ_GlobalSetting.mj_apiSetting.useTransfer"
|
||||||
|
:options="[
|
||||||
|
{ label: '是', value: true },
|
||||||
|
{ label: '否', value: false }
|
||||||
|
]"
|
||||||
|
style="width: 100px"
|
||||||
|
/>
|
||||||
|
</n-form-item>
|
||||||
|
</div>
|
||||||
|
</n-form>
|
||||||
|
</n-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
import { NCard, NForm, NFormItem, NInput, NSelect, NButton, useMessage } from 'naive-ui'
|
||||||
|
import { useOptionStore } from '@/stores/option'
|
||||||
|
import MJDefine from '@/main/Service/MJ/mjDefine'
|
||||||
|
import { isEmpty } from 'lodash'
|
||||||
|
|
||||||
|
let optionStore = useOptionStore()
|
||||||
|
let message = useMessage()
|
||||||
|
|
||||||
|
let mjAPIURLOptions = ref([])
|
||||||
|
let mjImageSpeedOptions = ref([])
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
mjAPIURLOptions.value = MJDefine.GetMJAPIUrlOptions()
|
||||||
|
mjImageSpeedOptions.value = MJDefine.GetMJSpeedOptions()
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开购买GPT的地址
|
||||||
|
*/
|
||||||
|
async function openGptBuyUrl() {
|
||||||
|
let selectAPIUrl = mjAPIURLOptions.value.filter(
|
||||||
|
(item) => item.value == optionStore.MJ_GlobalSetting.mj_apiSetting.mjApiUrl
|
||||||
|
)
|
||||||
|
if (selectAPIUrl.length == 0) {
|
||||||
|
message.error('当前选择的服务商没有购买地址!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let buy_url = selectAPIUrl[0].buy_url
|
||||||
|
if (isEmpty(buy_url)) {
|
||||||
|
message.error('当前选择的服务商没有购买地址!')
|
||||||
|
} else {
|
||||||
|
window.api.OpenUrl(buy_url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
<template>
|
||||||
|
<div class="mj-browser-setting">
|
||||||
|
<n-card title="浏览器模式设置" hoverable style="margin-top: 10px; min-width: 850px">
|
||||||
|
<n-form :model="optionStore.MJ_GlobalSetting.mj_browserSetting">
|
||||||
|
<div style="display: flex; margin-top: 10px">
|
||||||
|
<n-form-item>
|
||||||
|
<n-button type="info" @click="OpenDiscordWindow">打开登录MJ</n-button>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="服务器ID" style="width: 200px; margin-left: 5px" path="serviceId">
|
||||||
|
<n-input
|
||||||
|
v-model:value="optionStore.MJ_GlobalSetting.mj_browserSetting.serviceId"
|
||||||
|
placeholder="登录MJ后切换服务器自动获取"
|
||||||
|
/>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="频道ID" style="width: 200px; margin-left: 10px" path="channelId">
|
||||||
|
<n-input
|
||||||
|
v-model:value="optionStore.MJ_GlobalSetting.mj_browserSetting.channelId"
|
||||||
|
placeholder="登录MJ后切换频道自动获取"
|
||||||
|
/>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="用户token" style="width: 300px; margin-left: 10px" path="token">
|
||||||
|
<n-input
|
||||||
|
v-model:value="optionStore.MJ_GlobalSetting.mj_browserSetting.token"
|
||||||
|
placeholder="登录MJ后切换服务器自动获取"
|
||||||
|
/>
|
||||||
|
</n-form-item>
|
||||||
|
</div>
|
||||||
|
<n-form-item label="用户Agent" style="width: 810px" path="userAgent">
|
||||||
|
<n-input
|
||||||
|
v-model:value="optionStore.MJ_GlobalSetting.mj_browserSetting.userAgent"
|
||||||
|
placeholder="登录MJ后切换服务器自动获取(可自定义)"
|
||||||
|
style="margin-right: 10px"
|
||||||
|
/>
|
||||||
|
<n-tooltip trigger="hover" style="background-color: aliceblue; color: black">
|
||||||
|
<template #trigger>
|
||||||
|
<n-checkbox
|
||||||
|
v-model:checked="optionStore.MJ_GlobalSetting.mj_browserSetting.customUserAgent"
|
||||||
|
style="width: 100px"
|
||||||
|
>
|
||||||
|
自定义
|
||||||
|
</n-checkbox>
|
||||||
|
</template>
|
||||||
|
开启自定义需要手动填写userAgent。可以填入浏览器的userAgent
|
||||||
|
</n-tooltip>
|
||||||
|
</n-form-item>
|
||||||
|
</n-form>
|
||||||
|
</n-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { NCard, NForm, NFormItem, NTooltip, NCheckbox, NInput, NButton } from 'naive-ui'
|
||||||
|
|
||||||
|
import { useOptionStore } from '@/stores/option'
|
||||||
|
|
||||||
|
let optionStore = useOptionStore()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开discord窗口
|
||||||
|
*/
|
||||||
|
async function OpenDiscordWindow() {
|
||||||
|
await window.api.OpenDiscordWindow((value) => {
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
<template>
|
||||||
|
<div class="mj-remote-setting">
|
||||||
|
<n-card title="代理模式设置" hoverable style="margin-top: 10px; min-width: 850px">
|
||||||
|
<n-form inline>
|
||||||
|
<n-form-item style="width: 120px" path="useTransfer" label="是否国内转发">
|
||||||
|
<n-select
|
||||||
|
v-model:value="optionStore.MJ_GlobalSetting.mj_remoteSimpleSetting.useTransfer"
|
||||||
|
:options="[
|
||||||
|
{ label: '是', value: true },
|
||||||
|
{ label: '否', value: false }
|
||||||
|
]"
|
||||||
|
style="width: 100px"
|
||||||
|
/>
|
||||||
|
</n-form-item>
|
||||||
|
|
||||||
|
<n-form-item style="width: 120px; margin-left: 30px" path="useTransfer">
|
||||||
|
<n-button type="info" @click="AddMultiMjAccount">账号管理</n-button>
|
||||||
|
</n-form-item>
|
||||||
|
</n-form>
|
||||||
|
</n-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, h } from 'vue'
|
||||||
|
import { NCard, NButton, useDialog, NForm, NFormItem, NSelect } from 'naive-ui'
|
||||||
|
import AddMultiRemoteMj from '../Components/AddMultiRemoteMj.vue'
|
||||||
|
import { useOptionStore } from '@/stores/option'
|
||||||
|
|
||||||
|
let optionStore = useOptionStore()
|
||||||
|
|
||||||
|
let dialog = useDialog()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加多个账号,这样可以同时跑多个账号
|
||||||
|
*/
|
||||||
|
async function AddMultiMjAccount() {
|
||||||
|
let dW = window.innerWidth * 0.9
|
||||||
|
let dH = window.innerHeight * 0.9
|
||||||
|
dialog.create({
|
||||||
|
showIcon: false,
|
||||||
|
title: '管理代理模式MJ账号',
|
||||||
|
content: () => h(AddMultiRemoteMj, { height: dH }),
|
||||||
|
style: `min-width : 600px; width : ${dW}px; height : ${dH}px; padding-right : 5px;`,
|
||||||
|
maskClosable: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
147
src/renderer/src/components/Setting/MJSetting/MJSettingHome.vue
Normal file
147
src/renderer/src/components/Setting/MJSetting/MJSettingHome.vue
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
<template>
|
||||||
|
<div class="mj-setting-home">
|
||||||
|
<MJSimpleSetting />
|
||||||
|
<MJAPISetting />
|
||||||
|
<MJRemoteSetting />
|
||||||
|
<MJBrowserSetting />
|
||||||
|
<n-button type="info" @click="SaveMjSetting" style="margin-top: 10px">保存MJ配置</n-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import { useMessage, NButton } from 'naive-ui'
|
||||||
|
import { useSoftwareStore } from '@/stores/software'
|
||||||
|
import { useOptionStore } from '@/stores/option'
|
||||||
|
import { TimeDelay } from '@/define/Tools/time'
|
||||||
|
import { OptionKeyName, OptionType } from '@/define/enum/option'
|
||||||
|
import MJSimpleSetting from './MJSimpleSetting.vue'
|
||||||
|
import MJAPISetting from './MJAPISetting.vue'
|
||||||
|
import MJRemoteSetting from './MJRemoteSetting.vue'
|
||||||
|
import MJBrowserSetting from './MJBrowserSetting.vue'
|
||||||
|
import { MJImageType } from '@/define/enum/mjEnum'
|
||||||
|
import { isEmpty } from 'lodash'
|
||||||
|
|
||||||
|
let softwareStore = useSoftwareStore()
|
||||||
|
let optionStore = useOptionStore()
|
||||||
|
let message = useMessage()
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await InitMJSettingData()
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化MJSetting数据
|
||||||
|
*/
|
||||||
|
async function InitMJSettingData() {
|
||||||
|
try {
|
||||||
|
softwareStore.spin.spinning = true
|
||||||
|
softwareStore.spin.tip = '正在加载数据,请稍等...'
|
||||||
|
|
||||||
|
let mjRes = await window.options.GetOptionByKey(OptionKeyName.MJ_GlobalSetting)
|
||||||
|
if (mjRes.code == 0) {
|
||||||
|
window.api.showGlobalMessageDialog({
|
||||||
|
code: 0,
|
||||||
|
message: '加载或者是初始化MJSetting信息失败,失败原因:' + mjRes.message
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (mjRes.data == null) {
|
||||||
|
let saveRes = await window.options.ModifyOptionByKey(
|
||||||
|
OptionKeyName.MJ_GlobalSetting,
|
||||||
|
JSON.stringify(optionStore.MJ_GlobalSetting),
|
||||||
|
OptionType.JSON
|
||||||
|
)
|
||||||
|
if (saveRes.code == 0) {
|
||||||
|
window.api.showGlobalMessageDialog({
|
||||||
|
code: 0,
|
||||||
|
message: '加载或者是初始化MJSetting信息失败,失败原因:' + saveRes.message
|
||||||
|
})
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
message.success('初始化MJSetting信息成功')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
optionStore.MJ_GlobalSetting = JSON.parse(mjRes.data.value)
|
||||||
|
message.success('加载MJSetting信息成功')
|
||||||
|
}
|
||||||
|
|
||||||
|
await TimeDelay(1000)
|
||||||
|
} catch (error) {
|
||||||
|
window.api.showGlobalMessageDialog({
|
||||||
|
code: 0,
|
||||||
|
message: '加载或者是初始化MJSetting信息失败,失败原因:' + error.toString()
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
softwareStore.spin.spinning = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存MJ配置
|
||||||
|
*/
|
||||||
|
async function SaveMjSetting() {
|
||||||
|
// 在保存的时候要进行数据保存
|
||||||
|
debugger
|
||||||
|
// 通过选择的请求模式判断哪些是要校验的
|
||||||
|
let request_model = optionStore.MJ_GlobalSetting.mj_simpleSetting.requestModel
|
||||||
|
if (request_model == MJImageType.API_MJ) {
|
||||||
|
// API模式,检查必填数据
|
||||||
|
if (
|
||||||
|
optionStore.MJ_GlobalSetting.mj_simpleSetting == null ||
|
||||||
|
isEmpty(optionStore.MJ_GlobalSetting.mj_apiSetting.mjApiUrl) ||
|
||||||
|
isEmpty(optionStore.MJ_GlobalSetting.mj_apiSetting.mjSpeed) ||
|
||||||
|
isEmpty(optionStore.MJ_GlobalSetting.mj_apiSetting.apiKey)
|
||||||
|
) {
|
||||||
|
message.error('请检查API模式设置的必填字段')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request_model == MJImageType.REMOTE_MJ) {
|
||||||
|
// 检查是不是有代理账号
|
||||||
|
let remoteMjRes = await window.setting.GetRemoteMJSettings()
|
||||||
|
if (remoteMjRes.code == 0) {
|
||||||
|
message.error('获取代理MJ配置失败')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remoteMjRes.data.length <= 0) {
|
||||||
|
message.error('请先添加代理模式的配置')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (request_model == MJImageType.BROWSER_MJ) {
|
||||||
|
// 浏览器模式,检查必填数据
|
||||||
|
if (
|
||||||
|
optionStore.MJ_GlobalSetting.mj_browserSetting == null ||
|
||||||
|
isEmpty(optionStore.MJ_GlobalSetting.mj_browserSetting.serviceId) ||
|
||||||
|
isEmpty(optionStore.MJ_GlobalSetting.mj_browserSetting.channelId) ||
|
||||||
|
isEmpty(optionStore.MJ_GlobalSetting.mj_browserSetting.token) ||
|
||||||
|
isEmpty(optionStore.MJ_GlobalSetting.mj_browserSetting.userAgent)
|
||||||
|
) {
|
||||||
|
message.error('请检查浏览器模式设置的必填字段')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
optionStore.MJ_GlobalSetting.mj_simpleSetting.type =
|
||||||
|
optionStore.MJ_GlobalSetting.mj_simpleSetting.requestModel
|
||||||
|
|
||||||
|
let saveRes = await window.options.ModifyOptionByKey(
|
||||||
|
OptionKeyName.MJ_GlobalSetting,
|
||||||
|
JSON.stringify(optionStore.MJ_GlobalSetting),
|
||||||
|
OptionType.JSON
|
||||||
|
)
|
||||||
|
|
||||||
|
if (saveRes.code == 0) {
|
||||||
|
window.api.showGlobalMessageDialog(saveRes)
|
||||||
|
} else {
|
||||||
|
window.api.showGlobalMessageDialog({
|
||||||
|
code: 1,
|
||||||
|
message: '保存数据成功'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -0,0 +1,141 @@
|
|||||||
|
<template>
|
||||||
|
<div class="mj-simple-setting">
|
||||||
|
<n-card title="基础设置" size="medium" hoverable style="min-width: 850px">
|
||||||
|
<n-form
|
||||||
|
:model="optionStore.MJ_GlobalSetting.mj_simpleSetting"
|
||||||
|
ref="sampleRef"
|
||||||
|
:rules="sampleRules"
|
||||||
|
>
|
||||||
|
<div style="display: flex; align-items: center">
|
||||||
|
<n-form-item label="出图模式" style="width: 150px" path="requestModel">
|
||||||
|
<n-select
|
||||||
|
:options="mjRequestModelOptions"
|
||||||
|
v-model:value="optionStore.MJ_GlobalSetting.mj_simpleSetting.requestModel"
|
||||||
|
placeholder="请选择出图模式"
|
||||||
|
></n-select>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item
|
||||||
|
label="选择生图机器人"
|
||||||
|
path="selectRobot"
|
||||||
|
style="width: 120px; margin-left: 10px"
|
||||||
|
>
|
||||||
|
<n-select
|
||||||
|
:options="mjRobotOptions"
|
||||||
|
v-model:value="optionStore.MJ_GlobalSetting.mj_simpleSetting.selectRobot"
|
||||||
|
@update:value="UpdateSelectRobot"
|
||||||
|
></n-select>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="机器人模型" style="width: 120px; margin-left: 10px" path="imageModel">
|
||||||
|
<n-select
|
||||||
|
placeholder="请选择机器人模型"
|
||||||
|
:options="mjRobotModelOptions"
|
||||||
|
v-model:value="optionStore.MJ_GlobalSetting.mj_simpleSetting.imageModel"
|
||||||
|
@update:value="UpdateRobotModel"
|
||||||
|
></n-select>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="生图尺寸" style="width: 120px; margin-left: 10px" path="imageScale">
|
||||||
|
<n-select
|
||||||
|
placeholder="请选择生图尺寸"
|
||||||
|
:options="mjImageScaleOptions"
|
||||||
|
v-model:value="optionStore.MJ_GlobalSetting.mj_simpleSetting.imageScale"
|
||||||
|
@update:value="UpdateImageScale"
|
||||||
|
></n-select>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="命令后缀" style="width: 160px; margin-left: 10px" path="imageSuffix">
|
||||||
|
<n-input
|
||||||
|
v-model:value="optionStore.MJ_GlobalSetting.mj_simpleSetting.imageSuffix"
|
||||||
|
placeholder="请输入后缀命令"
|
||||||
|
></n-input>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="生图任务量" style="width: 100px; margin-left: 10px" path="taskCount">
|
||||||
|
<n-input-number
|
||||||
|
v-model:value="optionStore.MJ_GlobalSetting.mj_simpleSetting.taskCount"
|
||||||
|
:show-button="false"
|
||||||
|
placeholder="MJ并发出图数量"
|
||||||
|
:min="1"
|
||||||
|
:max="20"
|
||||||
|
></n-input-number>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="间隔时间(s)" style="width: 100px; margin-left: 10px" path="spaceTime">
|
||||||
|
<n-input-number
|
||||||
|
v-model:value="optionStore.MJ_GlobalSetting.mj_simpleSetting.spaceTime"
|
||||||
|
:show-button="false"
|
||||||
|
placeholder="请输入间隔时间(s)"
|
||||||
|
:min="1"
|
||||||
|
:max="30"
|
||||||
|
></n-input-number>
|
||||||
|
</n-form-item>
|
||||||
|
</div>
|
||||||
|
</n-form>
|
||||||
|
</n-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import { NCard, NForm, NFormItem, NInputNumber, NSelect, NInput } from 'naive-ui'
|
||||||
|
import { useOptionStore } from '@/stores/option'
|
||||||
|
import MJDefine from '@/main/Service/MJ/mjDefine'
|
||||||
|
|
||||||
|
let optionStore = useOptionStore()
|
||||||
|
|
||||||
|
let mjRequestModelOptions = ref([])
|
||||||
|
let mjRobotOptions = ref([])
|
||||||
|
let mjRobotModelOptions = ref([])
|
||||||
|
let mjImageScaleOptions = ref([])
|
||||||
|
|
||||||
|
// 基础配置的必填检测
|
||||||
|
let sampleRules = {
|
||||||
|
imageModel: [{ required: true, message: '请选择机器人模型', trigger: 'blur' }],
|
||||||
|
imageScale: [{ required: true, message: '请选择生图尺寸', trigger: 'blur' }],
|
||||||
|
requestModel: [{ required: true, message: '请选择出图模式', trigger: 'blur' }],
|
||||||
|
selectRobot: [{ required: true, message: '请选择生图机器人', trigger: 'blur' }]
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
mjRequestModelOptions.value = MJDefine.GetMJRequestModelOptions()
|
||||||
|
mjRobotOptions.value = MJDefine.GetMJRobotOptions()
|
||||||
|
mjRobotModelOptions.value = MJDefine.GetMJRobotModelOptions(
|
||||||
|
optionStore.MJ_GlobalSetting.mj_simpleSetting.selectRobot
|
||||||
|
)
|
||||||
|
mjImageScaleOptions.value = MJDefine.GetMJImageScaleOptions()
|
||||||
|
})
|
||||||
|
|
||||||
|
let computedSuffix = () => {
|
||||||
|
let text = mjRobotModelOptions.value.findIndex((item) => {
|
||||||
|
return item.value == optionStore.MJ_GlobalSetting.mj_simpleSetting.imageModel
|
||||||
|
})
|
||||||
|
if (text == -1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let sc = mjImageScaleOptions.value.findIndex((item) => {
|
||||||
|
return item.value == optionStore.MJ_GlobalSetting.mj_simpleSetting.imageScale
|
||||||
|
})
|
||||||
|
let dd = ` --${mjRobotModelOptions.value[text].text} --ar ${mjImageScaleOptions.value[sc].text}`
|
||||||
|
optionStore.MJ_GlobalSetting.mj_simpleSetting.imageSuffix = dd
|
||||||
|
return dd
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新选择的机器人时触发的方法
|
||||||
|
*/
|
||||||
|
function UpdateSelectRobot() {
|
||||||
|
mjRobotModelOptions.value = MJDefine.GetMJRobotModelOptions(
|
||||||
|
optionStore.MJ_GlobalSetting.mj_simpleSetting.selectRobot
|
||||||
|
)
|
||||||
|
|
||||||
|
optionStore.MJ_GlobalSetting.mj_simpleSetting.imageModel =
|
||||||
|
mjRobotModelOptions.value.length > 0 ? mjRobotModelOptions.value[0].value : undefined
|
||||||
|
|
||||||
|
// 刷新命令后缀
|
||||||
|
computedSuffix()
|
||||||
|
}
|
||||||
|
|
||||||
|
function UpdateImageScale() {
|
||||||
|
computedSuffix()
|
||||||
|
}
|
||||||
|
|
||||||
|
function UpdateRobotModel() {
|
||||||
|
computedSuffix()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -111,6 +111,7 @@
|
|||||||
placeholder="输入迭代步数"
|
placeholder="输入迭代步数"
|
||||||
/>
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
<div style="display: flex">
|
||||||
<n-form-item
|
<n-form-item
|
||||||
style="width: 300px"
|
style="width: 300px"
|
||||||
label="FLXU API模型(和GPT公用一个服务商)"
|
label="FLXU API模型(和GPT公用一个服务商)"
|
||||||
@ -122,7 +123,29 @@
|
|||||||
:options="flux_model_options"
|
:options="flux_model_options"
|
||||||
>
|
>
|
||||||
</n-select>
|
</n-select>
|
||||||
|
<n-button type="primary" style="margin-left: 10px" @click="GetFluxModelList"
|
||||||
|
>加载数据
|
||||||
|
</n-button>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
<n-form-item
|
||||||
|
style="width: 150px; margin-left: 30px"
|
||||||
|
label="是否国内转发"
|
||||||
|
path="useTransfer"
|
||||||
|
>
|
||||||
|
<n-select
|
||||||
|
placeholder="请选择是否转换"
|
||||||
|
v-model:value="formValue.useTransfer"
|
||||||
|
:options="[
|
||||||
|
{ label: '是', value: true },
|
||||||
|
{ label: '否', value: false }
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
</n-select>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item style="margin-left: 30px">
|
||||||
|
<div style="color: red">注意:使用国内转发可能会出现服务器超时错误,错误码504</div>
|
||||||
|
</n-form-item>
|
||||||
|
</div>
|
||||||
<n-form-item>
|
<n-form-item>
|
||||||
<n-button attr-type="button" type="primary" @click="SaveSDConfig"> 保存设置 </n-button>
|
<n-button attr-type="button" type="primary" @click="SaveSDConfig"> 保存设置 </n-button>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
@ -134,7 +157,7 @@
|
|||||||
</n-tabs>
|
</n-tabs>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import { defineComponent, ref, h, onMounted, toRaw } from 'vue'
|
import { defineComponent, ref, h, onMounted, toRaw } from 'vue'
|
||||||
import {
|
import {
|
||||||
NForm,
|
NForm,
|
||||||
@ -149,23 +172,11 @@ import {
|
|||||||
NCheckbox
|
NCheckbox
|
||||||
} from 'naive-ui'
|
} from 'naive-ui'
|
||||||
import SDADetailerSetting from '../Components/SDADetailerSetting.vue'
|
import SDADetailerSetting from '../Components/SDADetailerSetting.vue'
|
||||||
import { FLxuAPIImageType } from '../../../../define/enum/image'
|
import InitCommon from '../../common/initCommon'
|
||||||
|
|
||||||
export default defineComponent({
|
let flux_model_options = ref([])
|
||||||
components: {
|
|
||||||
NForm,
|
let formValue = ref({
|
||||||
NFormItem,
|
|
||||||
NInput,
|
|
||||||
NButton,
|
|
||||||
NInputNumber,
|
|
||||||
NSelect,
|
|
||||||
NTabs,
|
|
||||||
NTabPane,
|
|
||||||
SDADetailerSetting,
|
|
||||||
NCheckbox
|
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
let formValue = ref({
|
|
||||||
webui_api_url: window.config.webui_api_url,
|
webui_api_url: window.config.webui_api_url,
|
||||||
type: null,
|
type: null,
|
||||||
prompt: null,
|
prompt: null,
|
||||||
@ -180,14 +191,15 @@ export default defineComponent({
|
|||||||
cfg_scale: 1,
|
cfg_scale: 1,
|
||||||
sd_models: null,
|
sd_models: null,
|
||||||
lora: null,
|
lora: null,
|
||||||
flux_model: FLxuAPIImageType.FLUX
|
flux_model: null,
|
||||||
})
|
useTransfer: false
|
||||||
|
})
|
||||||
|
|
||||||
let samplers_options = ref([])
|
let samplers_options = ref([])
|
||||||
let lora_options = ref([])
|
let lora_options = ref([])
|
||||||
let sd_models_options = ref([])
|
let sd_models_options = ref([])
|
||||||
|
|
||||||
let modelOption = ref([
|
let modelOption = ref([
|
||||||
{
|
{
|
||||||
label: '文生图',
|
label: '文生图',
|
||||||
value: 'txt2img'
|
value: 'txt2img'
|
||||||
@ -196,9 +208,9 @@ export default defineComponent({
|
|||||||
label: '图生图',
|
label: '图生图',
|
||||||
value: 'img2img'
|
value: 'img2img'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await window.api.InitSDConfig((value) => {
|
await window.api.InitSDConfig((value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message)
|
message.error(value.message)
|
||||||
@ -234,13 +246,34 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
await InitFluxModelList()
|
||||||
|
})
|
||||||
|
|
||||||
let message = useMessage()
|
/**
|
||||||
/**
|
* 初始化FLUX模型列表
|
||||||
|
*/
|
||||||
|
async function InitFluxModelList(isMust = false) {
|
||||||
|
try {
|
||||||
|
flux_model_options.value = await InitCommon.InitFluxModelList(isMust)
|
||||||
|
if (!formValue.value.flux_model) {
|
||||||
|
formValue.value.flux_model =
|
||||||
|
flux_model_options.value.length > 0 ? flux_model_options.value[0].value : undefined
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
message.error('加载FLUX模型列表失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function GetFluxModelList() {
|
||||||
|
await InitFluxModelList(true)
|
||||||
|
message.success('加载远程 FLUX API 模型列表成功')
|
||||||
|
}
|
||||||
|
|
||||||
|
let message = useMessage()
|
||||||
|
/**
|
||||||
* 保存SD设置
|
* 保存SD设置
|
||||||
*/
|
*/
|
||||||
async function SaveSDConfig() {
|
async function SaveSDConfig() {
|
||||||
// 保存SD配置
|
// 保存SD配置
|
||||||
await window.api.SaveSDConfig(toRaw(formValue.value), (value) => {
|
await window.api.SaveSDConfig(toRaw(formValue.value), (value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
@ -256,12 +289,12 @@ export default defineComponent({
|
|||||||
window.api.showGlobalMessageDialog({ code: 0, message: value.message })
|
window.api.showGlobalMessageDialog({ code: 0, message: value.message })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载SD数据
|
* 加载SD数据
|
||||||
*/
|
*/
|
||||||
async function LoadSDServiceData() {
|
async function LoadSDServiceData() {
|
||||||
await window.sd.LoadSDServiceData(toRaw(formValue.value).webui_api_url, (value) => {
|
await window.sd.LoadSDServiceData(toRaw(formValue.value).webui_api_url, (value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message)
|
message.error(value.message)
|
||||||
@ -298,39 +331,5 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
message.success('加载成功')
|
message.success('加载成功')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
|
||||||
formValue,
|
|
||||||
SaveSDConfig,
|
|
||||||
modelOption,
|
|
||||||
LoadSDServiceData,
|
|
||||||
samplers_options,
|
|
||||||
lora_options,
|
|
||||||
sd_models_options,
|
|
||||||
flux_model_options: [
|
|
||||||
{
|
|
||||||
label: 'FLUX',
|
|
||||||
value: FLxuAPIImageType.FLUX
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'FLUX DEV',
|
|
||||||
value: FLxuAPIImageType.FLUX_DEV
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'FLUX PRO',
|
|
||||||
value: FLxuAPIImageType.FLUX_PRO
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'FLUX PRO MAX',
|
|
||||||
value: FLxuAPIImageType.FLUX_PRO_MAX
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'FLUX SCHNELL',
|
|
||||||
value: FLxuAPIImageType.FLUX_SCHNELL
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -52,6 +52,7 @@ import { useOptionStore } from '@/stores/option'
|
|||||||
|
|
||||||
let message = useMessage()
|
let message = useMessage()
|
||||||
let optionStore = useOptionStore()
|
let optionStore = useOptionStore()
|
||||||
|
let roleOptions = ref([])
|
||||||
|
|
||||||
async function SwitchTTSOptions(key) {
|
async function SwitchTTSOptions(key) {
|
||||||
console.log('SwitchTTSOptions', key)
|
console.log('SwitchTTSOptions', key)
|
||||||
@ -65,7 +66,6 @@ async function SwitchTTSOptions(key) {
|
|||||||
console.log('SwitchTTSOptions', roleOptions.value)
|
console.log('SwitchTTSOptions', roleOptions.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
let roleOptions = ref([])
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 获取配音角色列表
|
// 获取配音角色列表
|
||||||
await SwitchTTSOptions('edge-tts')
|
await SwitchTTSOptions('edge-tts')
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
</n-form>
|
</n-form>
|
||||||
<EdgeTTS v-if="optionStore.TTS_GlobalSetting.selectModel == 'edge-tts'" />
|
<EdgeTTS v-if="optionStore.TTS_GlobalSetting.selectModel == 'edge-tts'" />
|
||||||
<!-- <AzureTTS
|
<!-- <AzureTTS
|
||||||
:azureTTS="settingStore.ttsSetting.azureTTS"
|
:azureTTS=""
|
||||||
v-else-if="optionStore.TTS_GlobalSetting.selectModel == 'azure-tts'"
|
v-else-if="optionStore.TTS_GlobalSetting.selectModel == 'azure-tts'"
|
||||||
/> -->
|
/> -->
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -86,7 +86,7 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: '/mj_setting',
|
path: '/mj_setting',
|
||||||
name: 'mj_setting',
|
name: 'mj_setting',
|
||||||
component: () => import('./components/Setting/MJSetting.vue')
|
component: () => import('./components/Setting/MJSetting/MJSettingHome.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/video_setting',
|
path: '/video_setting',
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
|
import { MJImageType, MJRobotType, MJSpeed } from "@/define/enum/mjEnum";
|
||||||
import { OptionKeyName } from "@/define/enum/option";
|
import { OptionKeyName } from "@/define/enum/option";
|
||||||
import { OptionModel } from "@/model/option/option";
|
import { OptionModel } from "@/model/option/option";
|
||||||
|
import { MJSettingModel } from "@/model/Setting/mjSetting";
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
|
|
||||||
export type OptionStoreModel = {
|
export type OptionStoreModel = {
|
||||||
//#region
|
|
||||||
|
//#region 文案处理
|
||||||
|
|
||||||
/** 文案处理 AI设置 */
|
/** 文案处理 AI设置 */
|
||||||
[OptionKeyName.CW_AISetting]: {
|
[OptionKeyName.CW_AISetting]: {
|
||||||
@ -23,6 +26,11 @@ export type OptionStoreModel = {
|
|||||||
[OptionKeyName.TTS_GlobalSetting]: OptionModel.TTS_GlobalSettingModel | undefined;
|
[OptionKeyName.TTS_GlobalSetting]: OptionModel.TTS_GlobalSettingModel | undefined;
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
|
//#region MJ
|
||||||
|
/** MJ 基础设置 */
|
||||||
|
[OptionKeyName.MJ_GlobalSetting]: MJSettingModel.MJ_GlobalSettingModel;
|
||||||
|
//#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useOptionStore = defineStore('option', {
|
export const useOptionStore = defineStore('option', {
|
||||||
@ -64,6 +72,38 @@ export const useOptionStore = defineStore('option', {
|
|||||||
ttsText: "你好,我是你的智能语音助手!",
|
ttsText: "你好,我是你的智能语音助手!",
|
||||||
/** 保存的音频文件路径 */
|
/** 保存的音频文件路径 */
|
||||||
saveAudioPath: undefined,
|
saveAudioPath: undefined,
|
||||||
|
},
|
||||||
|
[OptionKeyName.MJ_GlobalSetting]: {
|
||||||
|
mj_simpleSetting: {
|
||||||
|
type: MJImageType.API_MJ,
|
||||||
|
requestModel: MJImageType.API_MJ,
|
||||||
|
selectRobot: MJRobotType.MJ,
|
||||||
|
imageScale: "3e2772f2-041c-49c6-ba13-d0ed120310b8",
|
||||||
|
imageModel: "3e6473ab-9a64-4574-9a38-f5c75af552b6",
|
||||||
|
imageSuffix: " --niji 6 --ar 1:1",
|
||||||
|
taskCount: 3,
|
||||||
|
spaceTime: 10
|
||||||
|
},
|
||||||
|
mj_apiSetting: {
|
||||||
|
id: "6db0d484-2a41-4545-8b26-ed32812965ad",
|
||||||
|
mjApiUrl: "b44c6f24-59e4-4a71-b2c7-3df0c4e35e65",
|
||||||
|
mjSpeed: MJSpeed.RELAX,
|
||||||
|
apiKey: "LAI API的令牌",
|
||||||
|
useTransfer: false
|
||||||
|
},
|
||||||
|
mj_browserSetting: {
|
||||||
|
id: "4d5d57f2-1d7a-4e0f-b347-a7283e75d64a",
|
||||||
|
serviceId: "自己的服务器ID",
|
||||||
|
channelId: "自己的频道ID",
|
||||||
|
mjBotId: "自己的MJ机器人ID",
|
||||||
|
nijBotId: "自己的NIJI机器人ID",
|
||||||
|
token: "自己的令牌",
|
||||||
|
userAgent: "自己的UserAgent",
|
||||||
|
userAgentCustom: false,
|
||||||
|
},
|
||||||
|
mj_remoteSimpleSetting: {
|
||||||
|
useTransfer: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} as unknown as OptionStoreModel),
|
} as unknown as OptionStoreModel),
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { MJSetting } from '../model/Setting/mjSetting'
|
import { MJSettingModel } from '../model/Setting/mjSetting'
|
||||||
|
|
||||||
// 系统相关设置
|
// 系统相关设置
|
||||||
export const useSettingStore = defineStore('setting', {
|
export const useSettingStore = defineStore('setting', {
|
||||||
@ -21,7 +21,7 @@ export const useSettingStore = defineStore('setting', {
|
|||||||
userToken: undefined,
|
userToken: undefined,
|
||||||
createTime: undefined,
|
createTime: undefined,
|
||||||
updateTime: undefined
|
updateTime: undefined
|
||||||
} as MJSetting.ActionRemoteMJSetting,
|
} as MJSettingModel.ActionRemoteMJSettingModel,
|
||||||
// tts 配置
|
// tts 配置
|
||||||
ttsSetting: {
|
ttsSetting: {
|
||||||
selectModel: 'edge-tts',
|
selectModel: 'edge-tts',
|
||||||
@ -62,7 +62,7 @@ export const useSettingStore = defineStore('setting', {
|
|||||||
userToken: undefined,
|
userToken: undefined,
|
||||||
createTime: undefined,
|
createTime: undefined,
|
||||||
updateTime: undefined
|
updateTime: undefined
|
||||||
} as MJSetting.ActionRemoteMJSetting
|
} as MJSettingModel.ActionRemoteMJSettingModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user