V 2.2.6 增加了MJ的api
This commit is contained in:
parent
941a86d07a
commit
8b011856c2
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,5 +9,6 @@ resources/image/Temp*
|
|||||||
resources/package/ffmpeg-2023*
|
resources/package/ffmpeg-2023*
|
||||||
resources/config*
|
resources/config*
|
||||||
*Lai.exe*
|
*Lai.exe*
|
||||||
|
*Lai_1.exe*
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.log*
|
*.log*
|
||||||
|
|||||||
3
.vs/define_string.js
Normal file
3
.vs/define_string.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export const DEFINE_STRING = {
|
||||||
|
SYSTEM: {}
|
||||||
|
}
|
||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -12,5 +12,6 @@
|
|||||||
"./resources/scripts/000_",
|
"./resources/scripts/000_",
|
||||||
"./resources/scripts/000_"
|
"./resources/scripts/000_"
|
||||||
],
|
],
|
||||||
"vue3snippets.enable-compile-vue-file-on-did-save-code": false
|
"vue3snippets.enable-compile-vue-file-on-did-save-code": false,
|
||||||
|
"typescript.tsdk": "node_modules\\typescript\\lib"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,6 @@ export default defineConfig({
|
|||||||
'@renderer': resolve('src/renderer/src')
|
'@renderer': resolve('src/renderer/src')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
plugins: [vue()]
|
plugins: [vue(), Jsx()]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
30
package-lock.json
generated
30
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "laitool",
|
"name": "laitool",
|
||||||
"version": "2.2.5",
|
"version": "2.2.6",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "laitool",
|
"name": "laitool",
|
||||||
"version": "2.2.2",
|
"version": "2.2.5",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alicloud/alimt20181012": "^1.2.0",
|
"@alicloud/alimt20181012": "^1.2.0",
|
||||||
@ -34,6 +34,7 @@
|
|||||||
"node-reg": "^0.2.4",
|
"node-reg": "^0.2.4",
|
||||||
"npm": "^10.7.0",
|
"npm": "^10.7.0",
|
||||||
"sharp": "^0.33.2",
|
"sharp": "^0.33.2",
|
||||||
|
"systeminformation": "^5.22.10",
|
||||||
"tencentcloud-sdk-nodejs": "^4.0.821",
|
"tencentcloud-sdk-nodejs": "^4.0.821",
|
||||||
"uuid": "^9.0.1",
|
"uuid": "^9.0.1",
|
||||||
"vue-router": "^4.2.5",
|
"vue-router": "^4.2.5",
|
||||||
@ -10012,6 +10013,31 @@
|
|||||||
"url": "https://opencollective.com/unts"
|
"url": "https://opencollective.com/unts"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/systeminformation": {
|
||||||
|
"version": "5.22.10",
|
||||||
|
"resolved": "https://registry.npmmirror.com/systeminformation/-/systeminformation-5.22.10.tgz",
|
||||||
|
"integrity": "sha512-RJ3oed80NkqgHtpB0TLkxEKEpQ3pUm2lgVolkHeoaExPidkWsj2D/hO6Rwwi9i+Odl1vm8TMiRNIKK7hBaqDsw==",
|
||||||
|
"os": [
|
||||||
|
"darwin",
|
||||||
|
"linux",
|
||||||
|
"win32",
|
||||||
|
"freebsd",
|
||||||
|
"openbsd",
|
||||||
|
"netbsd",
|
||||||
|
"sunos",
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"bin": {
|
||||||
|
"systeminformation": "lib/cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "Buy me a coffee",
|
||||||
|
"url": "https://www.buymeacoffee.com/systeminfo"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tar": {
|
"node_modules/tar": {
|
||||||
"version": "6.2.0",
|
"version": "6.2.0",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "laitool",
|
"name": "laitool",
|
||||||
"version": "2.2.5",
|
"version": "2.2.6",
|
||||||
"description": "An Electron application with Vue",
|
"description": "An Electron application with Vue",
|
||||||
"main": "./out/main/index.js",
|
"main": "./out/main/index.js",
|
||||||
"author": "example.com",
|
"author": "example.com",
|
||||||
@ -42,6 +42,7 @@
|
|||||||
"node-reg": "^0.2.4",
|
"node-reg": "^0.2.4",
|
||||||
"npm": "^10.7.0",
|
"npm": "^10.7.0",
|
||||||
"sharp": "^0.33.2",
|
"sharp": "^0.33.2",
|
||||||
|
"systeminformation": "^5.22.10",
|
||||||
"tencentcloud-sdk-nodejs": "^4.0.821",
|
"tencentcloud-sdk-nodejs": "^4.0.821",
|
||||||
"uuid": "^9.0.1",
|
"uuid": "^9.0.1",
|
||||||
"vue-router": "^4.2.5",
|
"vue-router": "^4.2.5",
|
||||||
|
|||||||
@ -11,7 +11,15 @@ import shotSplit
|
|||||||
|
|
||||||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
|
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
|
||||||
|
|
||||||
sys.argv = ["C:\\Users\\27698\\Desktop\\LAITool\\resources\\scripts\\Lai.exe","-c","C:/Users/27698/Desktop/测试/mjTest/scripts/output_crop_00001.json"]
|
# 判断sys.argv 的长度,如果小于2,说明没有传入参数,设置初始参数
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
sys.argv = [
|
||||||
|
"C:\\Users\\27698\\Desktop\\LAITool\\resources\\scripts\\Lai.exe",
|
||||||
|
"-c",
|
||||||
|
"C:/Users/27698/Desktop/测试/mjTest/scripts/output_crop_00001.json",
|
||||||
|
"NVIDIA",
|
||||||
|
]
|
||||||
|
|
||||||
print(sys.argv)
|
print(sys.argv)
|
||||||
|
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2:
|
||||||
@ -46,7 +54,7 @@ set_ffmpeg_env()
|
|||||||
|
|
||||||
# 执行剪辑的方法
|
# 执行剪辑的方法
|
||||||
if sys.argv[1] == "-c":
|
if sys.argv[1] == "-c":
|
||||||
clip = clip.Clip(cript_directory, sys.argv[2])
|
clip = clip.Clip(cript_directory, sys.argv[2], sys.argv[3])
|
||||||
clip.MergeVideosAndClip()
|
clip.MergeVideosAndClip()
|
||||||
pass
|
pass
|
||||||
# 获取字体
|
# 获取字体
|
||||||
@ -79,4 +87,4 @@ elif sys.argv[1] == "-k":
|
|||||||
# 智能分镜。字幕识别
|
# 智能分镜。字幕识别
|
||||||
elif sys.argv[1] == "-a":
|
elif sys.argv[1] == "-a":
|
||||||
print("开始算法分镜:" + sys.argv[2] + " -- 输出文件夹:" + sys.argv[3])
|
print("开始算法分镜:" + sys.argv[2] + " -- 输出文件夹:" + sys.argv[3])
|
||||||
shotSplit.init(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5])
|
shotSplit.init(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6])
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -21,7 +21,7 @@ class Clip:
|
|||||||
剪辑合并的类
|
剪辑合并的类
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, cript_directory, config_path) -> None:
|
def __init__(self, cript_directory, config_path, gpu_type) -> None:
|
||||||
self.audio_duration = None
|
self.audio_duration = None
|
||||||
self.cript_directory = cript_directory
|
self.cript_directory = cript_directory
|
||||||
self.ID = str(uuid.uuid4())
|
self.ID = str(uuid.uuid4())
|
||||||
@ -31,6 +31,7 @@ class Clip:
|
|||||||
self.TEMP_FOLDER, self.ASS_ID + ".ass"
|
self.TEMP_FOLDER, self.ASS_ID + ".ass"
|
||||||
).replace("\\", "/")
|
).replace("\\", "/")
|
||||||
self.config_path = config_path
|
self.config_path = config_path
|
||||||
|
self.gpu_type = gpu_type
|
||||||
self.ffmpeg_path = (
|
self.ffmpeg_path = (
|
||||||
"../package/ffmpeg-2023-12-07-git-f89cff96d0-full_build/bin/ffmpeg"
|
"../package/ffmpeg-2023-12-07-git-f89cff96d0-full_build/bin/ffmpeg"
|
||||||
)
|
)
|
||||||
@ -68,7 +69,7 @@ class Clip:
|
|||||||
self.bitRate = self.config_json["bitRate"]
|
self.bitRate = self.config_json["bitRate"]
|
||||||
|
|
||||||
# 图片数据
|
# 图片数据
|
||||||
self.iamge_to_video = iamge_to_video.ImageToVideo()
|
self.iamge_to_video = iamge_to_video.ImageToVideo(self.gpu_type)
|
||||||
self.iamge_to_video.fps = self.config_json["frameRate"]
|
self.iamge_to_video.fps = self.config_json["frameRate"]
|
||||||
self.iamge_to_video.video_size = (
|
self.iamge_to_video.video_size = (
|
||||||
self.video_resolution_x,
|
self.video_resolution_x,
|
||||||
@ -236,32 +237,46 @@ class Clip:
|
|||||||
# 添加txtlist表
|
# 添加txtlist表
|
||||||
txt_list.append(f"file '{os.path.abspath(output_file)}'")
|
txt_list.append(f"file '{os.path.abspath(output_file)}'")
|
||||||
# 删除开头,结尾,镜像,加速,放大
|
# 删除开头,结尾,镜像,加速,放大
|
||||||
|
command = []
|
||||||
|
command.append(self.ffmpeg_path)
|
||||||
|
if self.gpu_type == "NVIDIA":
|
||||||
|
command.append("-hwaccel")
|
||||||
|
command.append("cuda") # 启用 CUDA 硬件加速
|
||||||
|
command.append("-c:v")
|
||||||
|
command.append("h264_cuvid") # 使用 NVIDIA CUVID 解码器进行解码
|
||||||
|
elif self.gpu_type == "AMD":
|
||||||
|
command.append("-hwaccel")
|
||||||
|
command.append("vaapi")
|
||||||
|
command.append("-c:v")
|
||||||
|
command.append("h264_vaapi")
|
||||||
|
command.append("-i")
|
||||||
|
command.append(random_path)
|
||||||
|
command.append("-ss")
|
||||||
|
command.append(str(start_time))
|
||||||
|
command.append("-t")
|
||||||
|
command.append(str(duration))
|
||||||
|
command.append("-vf")
|
||||||
|
command.append(
|
||||||
|
"hflip,setpts=1*PTS,format=yuv420p,scale=iw*1.1:ih*1.1,crop=iw/1.1:ih/1.1"
|
||||||
|
)
|
||||||
|
command.append("-an")
|
||||||
|
command.append("-b:v")
|
||||||
|
command.append("5000k")
|
||||||
|
command.append("-c:v")
|
||||||
|
if self.gpu_type == "NVIDIA":
|
||||||
|
command.append("h264_nvenc")
|
||||||
|
elif self.gpu_type == "AMD":
|
||||||
|
command.append("h264_vaapi")
|
||||||
|
else:
|
||||||
|
command.append("libx264")
|
||||||
|
command.append("-preset")
|
||||||
|
command.append("fast")
|
||||||
|
command.append("-loglevel")
|
||||||
|
command.append("error")
|
||||||
|
command.append(output_file)
|
||||||
|
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
[
|
command,
|
||||||
self.ffmpeg_path,
|
|
||||||
"-hwaccel",
|
|
||||||
"cuda", # 启用 CUDA 硬件加速
|
|
||||||
"-c:v",
|
|
||||||
"h264_cuvid", # 使用 NVIDIA CUVID 解码器进行解码
|
|
||||||
"-i",
|
|
||||||
random_path,
|
|
||||||
"-ss",
|
|
||||||
str(start_time),
|
|
||||||
"-t",
|
|
||||||
str(duration),
|
|
||||||
"-vf",
|
|
||||||
"hflip,setpts=1*PTS,format=yuv420p,scale=iw*1.1:ih*1.1,crop=iw/1.1:ih/1.1",
|
|
||||||
"-an",
|
|
||||||
"-b:v",
|
|
||||||
"5000k",
|
|
||||||
"-c:v",
|
|
||||||
"h264_nvenc",
|
|
||||||
"-preset",
|
|
||||||
"fast",
|
|
||||||
"-loglevel",
|
|
||||||
"error",
|
|
||||||
output_file,
|
|
||||||
],
|
|
||||||
check=True,
|
check=True,
|
||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
)
|
)
|
||||||
@ -453,35 +468,41 @@ class Clip:
|
|||||||
|
|
||||||
# 合并视频并添加音乐和字幕
|
# 合并视频并添加音乐和字幕
|
||||||
def MergeVideoAndAudio(self):
|
def MergeVideoAndAudio(self):
|
||||||
command = [
|
command = []
|
||||||
self.ffmpeg_path,
|
command.append(self.ffmpeg_path)
|
||||||
"-f",
|
command.append("-f")
|
||||||
"concat",
|
command.append("concat")
|
||||||
"-safe",
|
command.append("-safe")
|
||||||
"0",
|
command.append("0")
|
||||||
"-i",
|
command.append("-i")
|
||||||
self.mp4_file_txt,
|
command.append(self.mp4_file_txt)
|
||||||
"-i",
|
command.append("-i")
|
||||||
self.mix_audio,
|
command.append(self.mix_audio)
|
||||||
"-vf",
|
command.append("-vf")
|
||||||
f"subtitles=./Temp/{self.ID}/{self.ASS_ID}.ass",
|
command.append(f"subtitles=./Temp/{self.ID}/{self.ASS_ID}.ass")
|
||||||
# f"subtitles= {ASS_FILE_PATH}",
|
command.append("-c:v")
|
||||||
"-c:v",
|
|
||||||
"h264_nvenc",
|
if self.gpu_type == "NVIDIA":
|
||||||
"-preset",
|
command.append("h264_nvenc")
|
||||||
"fast",
|
elif self.gpu_type == "AMD":
|
||||||
"-rc:v",
|
command.append("h264_vaapi")
|
||||||
"cbr",
|
else:
|
||||||
"-b:v",
|
command.append("libx264")
|
||||||
str(self.bitRate) + "k",
|
|
||||||
"-c:a",
|
command.append("-preset")
|
||||||
"aac",
|
command.append("fast")
|
||||||
"-strict",
|
command.append("-rc:v")
|
||||||
"-2",
|
command.append("cbr")
|
||||||
"-loglevel",
|
command.append("-b:v")
|
||||||
"error",
|
command.append(str(self.bitRate) + "k")
|
||||||
self.outpue_file,
|
command.append("-c:a")
|
||||||
]
|
command.append("aac")
|
||||||
|
command.append("-strict")
|
||||||
|
command.append("-2")
|
||||||
|
command.append("-loglevel")
|
||||||
|
command.append("error")
|
||||||
|
command.append(self.outpue_file)
|
||||||
|
|
||||||
subprocess.run(command, check=True, stderr=subprocess.PIPE)
|
subprocess.run(command, check=True, stderr=subprocess.PIPE)
|
||||||
# subprocess.run(command)
|
# subprocess.run(command)
|
||||||
pass
|
pass
|
||||||
|
|||||||
@ -9,8 +9,9 @@ import json
|
|||||||
|
|
||||||
|
|
||||||
class ImageToVideo:
|
class ImageToVideo:
|
||||||
def __init__(self) -> None:
|
def __init__(self, gpu_type) -> None:
|
||||||
self.frames = 0
|
self.frames = 0
|
||||||
|
self.gpu_type = gpu_type
|
||||||
self.public_tools = public_tools.PublicTools()
|
self.public_tools = public_tools.PublicTools()
|
||||||
self.ffmpeg_path = (
|
self.ffmpeg_path = (
|
||||||
"../package/ffmpeg-2023-12-07-git-f89cff96d0-full_build/bin/ffmpeg"
|
"../package/ffmpeg-2023-12-07-git-f89cff96d0-full_build/bin/ffmpeg"
|
||||||
@ -455,29 +456,37 @@ class ImageToVideo:
|
|||||||
)
|
)
|
||||||
temp_mp4_path = os.path.join(image_dir, "temp_" + str(number) + ".mp4")
|
temp_mp4_path = os.path.join(image_dir, "temp_" + str(number) + ".mp4")
|
||||||
# 开始微调
|
# 开始微调
|
||||||
cmd = [
|
cmd = []
|
||||||
self.ffmpeg_path,
|
cmd.append(self.ffmpeg_path)
|
||||||
"-i",
|
cmd.append("-i")
|
||||||
mp4_path,
|
cmd.append(mp4_path)
|
||||||
"-filter:v",
|
cmd.append("-filter:v")
|
||||||
|
cmd.append(
|
||||||
"setpts=PTS*"
|
"setpts=PTS*"
|
||||||
+ str(
|
+ str(
|
||||||
(filtered_data[0]["end_time"] - filtered_data[0]["start_time"])
|
(filtered_data[0]["end_time"] - filtered_data[0]["start_time"])
|
||||||
/ duration_ms
|
/ duration_ms
|
||||||
),
|
)
|
||||||
"-c:v",
|
)
|
||||||
"h264_nvenc",
|
cmd.append("-c:v")
|
||||||
"-preset",
|
|
||||||
"fast",
|
if self.gpu_type == "NVIDIA":
|
||||||
"-rc:v",
|
cmd.append("h264_nvenc")
|
||||||
"cbr",
|
elif self.gpu_type == "AMD":
|
||||||
"-b:v",
|
cmd.append("h264_vaapi")
|
||||||
str(self.bitRate) + "k",
|
else:
|
||||||
temp_mp4_path,
|
cmd.append("libx264")
|
||||||
"-loglevel",
|
|
||||||
"error",
|
cmd.append("-preset")
|
||||||
"-an",
|
cmd.append("fast")
|
||||||
]
|
cmd.append("-rc:v")
|
||||||
|
cmd.append("cbr")
|
||||||
|
cmd.append("-b:v")
|
||||||
|
cmd.append(str(self.bitRate) + "k")
|
||||||
|
cmd.append(temp_mp4_path)
|
||||||
|
cmd.append("-loglevel")
|
||||||
|
cmd.append("error")
|
||||||
|
cmd.append("-an")
|
||||||
|
|
||||||
subprocess.run(cmd, check=True)
|
subprocess.run(cmd, check=True)
|
||||||
os.remove(mp4_path)
|
os.remove(mp4_path)
|
||||||
|
|||||||
@ -62,7 +62,7 @@ def createDir(file_dir):
|
|||||||
|
|
||||||
|
|
||||||
# 切分一个视频
|
# 切分一个视频
|
||||||
def ClipVideo(video_path, out_folder, image_out_folder, sensitivity):
|
def ClipVideo(video_path, out_folder, image_out_folder, sensitivity, gpu_type):
|
||||||
shijian_list = find_scenes(video_path, sensitivity) # 多组时间列表
|
shijian_list = find_scenes(video_path, sensitivity) # 多组时间列表
|
||||||
shijian_list_len = len(shijian_list)
|
shijian_list_len = len(shijian_list)
|
||||||
|
|
||||||
@ -87,25 +87,33 @@ def ClipVideo(video_path, out_folder, image_out_folder, sensitivity):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# 使用 ffmpeg 裁剪视频
|
# 使用 ffmpeg 裁剪视频
|
||||||
|
command = []
|
||||||
|
command.append("ffmpeg")
|
||||||
|
command.append("-i")
|
||||||
|
command.append(video_path)
|
||||||
|
command.append("-ss")
|
||||||
|
command.append(start_time_str)
|
||||||
|
command.append("-to")
|
||||||
|
command.append(end_time_str)
|
||||||
|
command.append("-c:v")
|
||||||
|
|
||||||
|
if gpu_type == "NVIDIA":
|
||||||
|
command.append("h264_nvenc")
|
||||||
|
elif gpu_type == "AMD":
|
||||||
|
command.append("h264_vaapi")
|
||||||
|
else:
|
||||||
|
command.append("libx264")
|
||||||
|
|
||||||
|
command.append("-preset")
|
||||||
|
command.append("fast")
|
||||||
|
command.append("-c:a")
|
||||||
|
command.append("copy")
|
||||||
|
command.append(out_video_file)
|
||||||
|
command.append("-loglevel")
|
||||||
|
command.append("error")
|
||||||
|
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
[
|
command,
|
||||||
"ffmpeg",
|
|
||||||
"-i",
|
|
||||||
video_path,
|
|
||||||
"-ss",
|
|
||||||
start_time_str,
|
|
||||||
"-to",
|
|
||||||
end_time_str,
|
|
||||||
"-c:v",
|
|
||||||
"h264_nvenc",
|
|
||||||
"-preset",
|
|
||||||
"fast",
|
|
||||||
"-c:a",
|
|
||||||
"copy",
|
|
||||||
out_video_file,
|
|
||||||
"-loglevel",
|
|
||||||
"error",
|
|
||||||
],
|
|
||||||
check=True,
|
check=True,
|
||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
)
|
)
|
||||||
@ -220,8 +228,10 @@ def GetText(out_folder, mp3_list):
|
|||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
|
||||||
def init(video_path, video_out_folder, image_out_folder, sensitivity):
|
def init(video_path, video_out_folder, image_out_folder, sensitivity, gpu_type):
|
||||||
v_l = ClipVideo(video_path, video_out_folder, image_out_folder, sensitivity)
|
v_l = ClipVideo(
|
||||||
|
video_path, video_out_folder, image_out_folder, sensitivity, gpu_type
|
||||||
|
)
|
||||||
|
|
||||||
# 开始分离音频
|
# 开始分离音频
|
||||||
m_l = SplitAudio(video_out_folder, v_l)
|
m_l = SplitAudio(video_out_folder, v_l)
|
||||||
|
|||||||
@ -60,10 +60,9 @@ let basicApi = {
|
|||||||
const request = net.request({
|
const request = net.request({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: url,
|
url: url,
|
||||||
headers: {
|
headers: Object.assign({
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
...headers
|
}, headers)
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
request.write(JSON.stringify(data));
|
request.write(JSON.stringify(data));
|
||||||
@ -108,6 +107,48 @@ let basicApi = {
|
|||||||
request.end();
|
request.end();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载指定的文件,返回buffer
|
||||||
|
* @param {*} url
|
||||||
|
* @param {*} headers
|
||||||
|
*/
|
||||||
|
downloadFileByURL: (url, headers = {}) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const request = net.request({
|
||||||
|
method: 'GET',
|
||||||
|
url: url,
|
||||||
|
headers: headers
|
||||||
|
});
|
||||||
|
request.on('response', (response) => {
|
||||||
|
const chunks = [];
|
||||||
|
response.on('data', (chunk) => chunks.push(chunk));
|
||||||
|
response.on('end', async () => {
|
||||||
|
try {
|
||||||
|
console.log('File downloaded successfully');
|
||||||
|
resolve({
|
||||||
|
data: Buffer.concat(chunks),
|
||||||
|
status: response.statusCode,
|
||||||
|
statusText: response.statusMessage,
|
||||||
|
headers: response.headers
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
response.on('error', (error) => {
|
||||||
|
console.log('error', error);
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
request.on('error', (error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
request.end();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
98
src/api/discordApi.js
Normal file
98
src/api/discordApi.js
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
|
||||||
|
import { basicApi } from "./apiBasic";
|
||||||
|
import { Tools } from "../main/tools";
|
||||||
|
|
||||||
|
export class DiscordAPI {
|
||||||
|
constructor() {
|
||||||
|
this.tools = new Tools();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过设置的ID获取MJ API的任务
|
||||||
|
* @param {*} id
|
||||||
|
*/
|
||||||
|
async GetMJAPITaskByID(id, url, key) {
|
||||||
|
try {
|
||||||
|
let res;
|
||||||
|
url = url.replace("${id}", id);
|
||||||
|
let headers = {
|
||||||
|
"Authorization": key
|
||||||
|
}
|
||||||
|
res = await basicApi.get(url, headers);
|
||||||
|
|
||||||
|
let progress = res.data.progress && res.data.progress.length > 0 ? parseInt(res.data.progress.slice(0, -1)) : 0;
|
||||||
|
let status = res.data.status.toLowerCase();
|
||||||
|
// let code = (status == "success" || status == "in_progress" || status == "not_start") ? 1 : 0;
|
||||||
|
let code = (status == "failure" || status == "cancel") ? 0 : 1;
|
||||||
|
// 返回前端
|
||||||
|
let res_data = {
|
||||||
|
type: "updated",
|
||||||
|
progress: progress,
|
||||||
|
category: "api_mj",
|
||||||
|
image_click: res.data.imageUrl,
|
||||||
|
image_show: res.data.imageUrl,
|
||||||
|
message_id: res.data.id,
|
||||||
|
action: res.data.action,
|
||||||
|
status: status,
|
||||||
|
code: code,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断当前的API是哪个
|
||||||
|
if (url.includes("mjapi.deepwl.net")) {
|
||||||
|
if (res_data.code == 0) {
|
||||||
|
res_data["message"] = res.data.failReason
|
||||||
|
}
|
||||||
|
} else if (url.includes("api.ephone.ai")) {
|
||||||
|
// ePhoneAPI
|
||||||
|
if (res_data.code == 0) {
|
||||||
|
res_data["message"] = res.data.failReason
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res_data;
|
||||||
|
} catch (error) {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MJ使用API进行生图
|
||||||
|
*/
|
||||||
|
async mjApiImagine(url, data, headers) {
|
||||||
|
try {
|
||||||
|
// 判断是不是需要垫图,将指定的图片转换为base64
|
||||||
|
for (let i = 0; data.base64Array && i < data.base64Array.length; i++) {
|
||||||
|
const element = data.base64Array[i];
|
||||||
|
// 将指定的图片转换为base64
|
||||||
|
// 判断图片是本地图片还是网络图片
|
||||||
|
if (element.indexOf("http") == -1) {
|
||||||
|
// 本地图片
|
||||||
|
let base64 = await this.tools.readFileBase64(element);
|
||||||
|
data.base64Array[i] = `data:image/png;base64,${base64}`
|
||||||
|
} else {
|
||||||
|
// 网络图片
|
||||||
|
// 请求对应的图片
|
||||||
|
let image_buffer = await basicApi.get(element);
|
||||||
|
// 将返回来的数据转为base64
|
||||||
|
let base64 = image_buffer.data.toString('base64');
|
||||||
|
data.base64Array[i] = `data:image/png;base64,${base64}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = await basicApi.post(url, data, headers);
|
||||||
|
console.log(res)
|
||||||
|
let res_data = res.data;
|
||||||
|
// 判断res_data 是不是json格式的字符串,是就序列化为json对象
|
||||||
|
if (typeof res_data == "string") {
|
||||||
|
res_data = JSON.parse(res_data);
|
||||||
|
}
|
||||||
|
if (res_data && res_data.code != 1) {
|
||||||
|
throw new Error(res_data.message);
|
||||||
|
}
|
||||||
|
return res_data;
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -70,6 +70,7 @@ export class SdApi {
|
|||||||
data.steps = this.sd_setting.webui.steps;
|
data.steps = this.sd_setting.webui.steps;
|
||||||
data.save_images = false;
|
data.save_images = false;
|
||||||
data.batch_size = data.batch_size ? data.batch_size : 1;
|
data.batch_size = data.batch_size ? data.batch_size : 1;
|
||||||
|
|
||||||
if (data.width == null) {
|
if (data.width == null) {
|
||||||
data.width = 512;
|
data.width = 512;
|
||||||
}
|
}
|
||||||
|
|||||||
56
src/define/api/apiUrlDefine.js
Normal file
56
src/define/api/apiUrlDefine.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
let apiUrl = [{
|
||||||
|
label: "openai-hk",
|
||||||
|
value: "3d64e50e-79c0-49ec-a72d-7dfdf508dd04",
|
||||||
|
gpt_url: "https://api.openai-hk.com/v1/chat/completions",
|
||||||
|
mj_url: null,
|
||||||
|
buy_url: "https://openai-hk.com/?i=10196"
|
||||||
|
}, {
|
||||||
|
label: "通义千问",
|
||||||
|
value: "b630c69a-99e9-46bc-8d88-39a00bcc3d2a",
|
||||||
|
gpt_url: "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation",
|
||||||
|
mj_url: null,
|
||||||
|
buy_url: null
|
||||||
|
}, {
|
||||||
|
label: "DrawAPI(MJ)",
|
||||||
|
value: "2cabf684-ac48-4733-a427-8c41626f7d8f",
|
||||||
|
gpt_url: null,
|
||||||
|
mj_url: {
|
||||||
|
imagine: "https://mjapi.deepwl.net/api/mj/submit/imagine",
|
||||||
|
describe: "https://mjapi.deepwl.net/api/mj/submit/describe",
|
||||||
|
update_file: "https://mjapi.deepwl.net/api/mj/submit/upload-discord-images",
|
||||||
|
once_get_task: "https://mjapi.deepwl.net/api/mj/query/task/${id}",
|
||||||
|
get_task_list: "https://mjapi.deepwl.net/api/mj/task/list-by-condition"
|
||||||
|
},
|
||||||
|
d3_url: null,
|
||||||
|
buy_url: "https://mjapi.deepwl.net/#/home"
|
||||||
|
}, {
|
||||||
|
label: "ePhoneAPI",
|
||||||
|
value: "b8866543-8c27-4888-869c-00aa1eb31272",
|
||||||
|
gpt_url: "https://api.ephone.ai/v1/chat/completions",
|
||||||
|
mj_url: {
|
||||||
|
imagine: "https://api.ephone.ai/mj/submit/imagine",
|
||||||
|
describe: "https://api.ephone.ai/mj/submit/describe",
|
||||||
|
update_file: "https://api.ephone.ai/mj/submit/upload-discord-images",
|
||||||
|
once_get_task: "https://api.ephone.ai/mj/task/${id}/fetch",
|
||||||
|
},
|
||||||
|
d3_url: {
|
||||||
|
image: "https://api.ephone.ai/v1/images/generations"
|
||||||
|
},
|
||||||
|
buy_url: "https://ephone.ai/register?aff=55XT"
|
||||||
|
}]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过ID获取指定的数据(value)
|
||||||
|
* @param {*} id
|
||||||
|
*/
|
||||||
|
function getApiMessageByID(id) {
|
||||||
|
let mj_api_url_index = apiUrl.findIndex(item => item.value == id)
|
||||||
|
if (mj_api_url_index == -1) {
|
||||||
|
throw new Error("没有找到对应的MJ API的配置,请先检查配置")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
export {
|
||||||
|
apiUrl,
|
||||||
|
getApiMessageByID
|
||||||
|
}
|
||||||
@ -132,6 +132,7 @@ export const DEFINE_STRING = {
|
|||||||
TRANSLATE_RETURN_NOW_TASK: "TRANSLATE_RETURN_NOW_TASK",
|
TRANSLATE_RETURN_NOW_TASK: "TRANSLATE_RETURN_NOW_TASK",
|
||||||
IMAGE_SAVE_TO_OTHER_FOLDER: "IMAGE_SAVE_TO_OTHER_FOLDER",
|
IMAGE_SAVE_TO_OTHER_FOLDER: "IMAGE_SAVE_TO_OTHER_FOLDER",
|
||||||
SAVE_FILE_QUEUE: "SAVE_FILE_QUEUE",
|
SAVE_FILE_QUEUE: "SAVE_FILE_QUEUE",
|
||||||
|
AUTO_SAVE_DATA_JSON: "AUTO_SAVE_DATA_JSON"
|
||||||
},
|
},
|
||||||
PERMISSIONS: {
|
PERMISSIONS: {
|
||||||
NORMAL_PERMISSION: "NORMAL_PERMISSION",
|
NORMAL_PERMISSION: "NORMAL_PERMISSION",
|
||||||
@ -156,7 +157,9 @@ export const DEFINE_STRING = {
|
|||||||
ADD_MJ_BAD_PROMPT: "ADD_MJ_BAD_PROMPT",
|
ADD_MJ_BAD_PROMPT: "ADD_MJ_BAD_PROMPT",
|
||||||
MJ_BAD_PROMPT_CHECK: "MJ_BAD_PROMPT_CHECK",
|
MJ_BAD_PROMPT_CHECK: "MJ_BAD_PROMPT_CHECK",
|
||||||
GET_GENERATED_MJ_IMAGE_AND_SPLIT: "GET_GENERATED_MJ_IMAGE_AND_SPLIT",
|
GET_GENERATED_MJ_IMAGE_AND_SPLIT: "GET_GENERATED_MJ_IMAGE_AND_SPLIT",
|
||||||
DOWNLOAD_IMAGE_URL_AND_SPLIT: "DOWNLOAD_IMAGE_URL_AND_SPLIT"
|
DOWNLOAD_IMAGE_URL_AND_SPLIT: "DOWNLOAD_IMAGE_URL_AND_SPLIT",
|
||||||
|
GET_MJ_IMAGE_SCALE: 'GET_MJ_IMAGE_SCALE',
|
||||||
|
GET_MJ_IMAGE_ROBOT_MODEL: "GET_MJ_IMAGE_ROBOT_MODEL"
|
||||||
},
|
},
|
||||||
DISCORD: {
|
DISCORD: {
|
||||||
OPERATE_REFRASH_DISCORD_URL: "OPERATE_REFRASH_DISCORD_URL",
|
OPERATE_REFRASH_DISCORD_URL: "OPERATE_REFRASH_DISCORD_URL",
|
||||||
@ -175,5 +178,8 @@ export const DEFINE_STRING = {
|
|||||||
},
|
},
|
||||||
MAIN: {
|
MAIN: {
|
||||||
OPEN_DISCORD_WINDOW: "OPEN_DISCORD_WINDOW"
|
OPEN_DISCORD_WINDOW: "OPEN_DISCORD_WINDOW"
|
||||||
|
},
|
||||||
|
IMG: {
|
||||||
|
ONE_SPLIT_FOUR: "ONE_SPLIT_FOUR"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2,6 +2,7 @@ let fspromises = require('fs').promises;
|
|||||||
import { cloneDeep, get } from "lodash";
|
import { cloneDeep, get } from "lodash";
|
||||||
import { define } from "./define";
|
import { define } from "./define";
|
||||||
const { v4: uuidv4 } = require('uuid');
|
const { v4: uuidv4 } = require('uuid');
|
||||||
|
import { apiUrl } from "./api/apiUrlDefine";
|
||||||
|
|
||||||
// Create a shared object
|
// Create a shared object
|
||||||
export const gptDefine = {
|
export const gptDefine = {
|
||||||
@ -271,13 +272,7 @@ export const gptDefine = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
gpt_options: [{
|
gpt_options: apiUrl,
|
||||||
label: "openai-hk",
|
|
||||||
value: "https://api.openai-hk.com/v1/chat/completions"
|
|
||||||
}, {
|
|
||||||
label: "通义千问",
|
|
||||||
value: "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation"
|
|
||||||
}],
|
|
||||||
|
|
||||||
gpt_model_options: [{
|
gpt_model_options: [{
|
||||||
label: "gpt-3.5-turbo-16k",
|
label: "gpt-3.5-turbo-16k",
|
||||||
@ -377,7 +372,9 @@ export const gptDefine = {
|
|||||||
gpt[index] = value;
|
gpt[index] = value;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
value.id = uuidv4();
|
let tmp_id = uuidv4();
|
||||||
|
value.id = tmp_id;
|
||||||
|
value.value = tmp_id;
|
||||||
gpt.push(value);
|
gpt.push(value);
|
||||||
}
|
}
|
||||||
tmp_gpt[property] = gpt;
|
tmp_gpt[property] = gpt;
|
||||||
|
|||||||
@ -1,16 +1,89 @@
|
|||||||
import { Tools } from "../../main/tools";
|
import { successMessage } from "../../main/generalTools";
|
||||||
import { define } from "../define";
|
|
||||||
import path from "path";
|
|
||||||
import { DEFINE_STRING } from "../define_string";
|
|
||||||
import { get, has } from "lodash";
|
|
||||||
let tools = new Tools();
|
|
||||||
const { v4: uuidv4 } = require('uuid'); // 引入UUID库来生成唯一标识符
|
|
||||||
|
|
||||||
export class MjSetting {
|
export class MjSetting {
|
||||||
constructor(golbal) {
|
constructor(golbal) {
|
||||||
this.golbal = golbal;
|
this.golbal = golbal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取MJ生成图片的机器人模型
|
||||||
|
*/
|
||||||
|
GetMJImageRobotModel() {
|
||||||
|
return successMessage([
|
||||||
|
{
|
||||||
|
label: "MJ V6.0",
|
||||||
|
text: "v 6",
|
||||||
|
type: "mj",
|
||||||
|
value: "3e6473ab-9a64-4574-9a38-f5c75af552b6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "MJ V5.2",
|
||||||
|
text: "v 5.2",
|
||||||
|
type: "mj",
|
||||||
|
value: "27a0d30e-f46c-4684-96c8-d91334deb94f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "MJ V5.1",
|
||||||
|
text: "v 5.1",
|
||||||
|
type: "mj",
|
||||||
|
value: "e1226715-e969-44c4-b18b-f2ad5dae5d2f"
|
||||||
|
}, {
|
||||||
|
label: "MJ V5.0",
|
||||||
|
text: "v 5",
|
||||||
|
type: "mj",
|
||||||
|
value: "afb7bea1-4eda-46ea-8165-34701b4566bf"
|
||||||
|
}, {
|
||||||
|
label: "MJ V4.0",
|
||||||
|
text: "v 4",
|
||||||
|
type: "mj",
|
||||||
|
value: "d05b8497-7f4a-4890-8fac-89f1803984d2"
|
||||||
|
}, {
|
||||||
|
label: "NIJI V6",
|
||||||
|
text: "niji 6",
|
||||||
|
type: "niji",
|
||||||
|
value: "99377cad-c103-4cee-a958-86a104879328"
|
||||||
|
}, {
|
||||||
|
label: "NIJI V5",
|
||||||
|
text: "niji 5",
|
||||||
|
type: "niji",
|
||||||
|
value: "53cec077-9885-4635-ab18-e021066b2c4c"
|
||||||
|
}, {
|
||||||
|
label: "NIJI V4",
|
||||||
|
text: "niji 4",
|
||||||
|
type: "niji",
|
||||||
|
value: "6a7199fe-6e0d-40a9-9772-b5eb3d2e2e66"
|
||||||
|
},
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取生图的比例
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
GetMJImageScale() {
|
||||||
|
return successMessage([{
|
||||||
|
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生成图片方式的分类
|
* 返回mj生成图片方式的分类
|
||||||
*/
|
*/
|
||||||
@ -18,20 +91,24 @@ export class MjSetting {
|
|||||||
return {
|
return {
|
||||||
code: 1,
|
code: 1,
|
||||||
data: [{
|
data: [{
|
||||||
label: "本地MJ",
|
label: "本地MJ(待开发)",
|
||||||
value: "local_mj"
|
value: "local_mj",
|
||||||
|
disable: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "代理MJ(待开发)",
|
label: "代理MJ(待开发)",
|
||||||
value: "remote_mj"
|
value: "remote_mj",
|
||||||
|
disable: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "浏览器模式",
|
label: "浏览器模式",
|
||||||
value: "browser_mj"
|
value: "browser_mj",
|
||||||
|
disable: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "API模式(待开发)",
|
label: "API模式",
|
||||||
value: "api_mj"
|
value: "api_mj",
|
||||||
|
disable: false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/main/IPCEvent/imageIpc.js
Normal file
14
src/main/IPCEvent/imageIpc.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { ipcMain } from "electron";
|
||||||
|
import { DEFINE_STRING } from '../../define/define_string'
|
||||||
|
import { Image } from "../Public/Image";
|
||||||
|
let image = new Image(global);
|
||||||
|
|
||||||
|
|
||||||
|
function ImageIpc() {
|
||||||
|
|
||||||
|
// 一拆四
|
||||||
|
ipcMain.handle(DEFINE_STRING.IMG.ONE_SPLIT_FOUR, async (event, value) => await image.OneSplitFour(value));
|
||||||
|
}
|
||||||
|
export {
|
||||||
|
ImageIpc
|
||||||
|
}
|
||||||
@ -57,6 +57,12 @@ function MjIpc() {
|
|||||||
// 给图片链接,下载指定的图片并分割保存
|
// 给图片链接,下载指定的图片并分割保存
|
||||||
ipcMain.handle(DEFINE_STRING.MJ.DOWNLOAD_IMAGE_URL_AND_SPLIT, async (event, value) => await mJOriginalImageGenerate.DownloadImageUrlAndSplit(value));
|
ipcMain.handle(DEFINE_STRING.MJ.DOWNLOAD_IMAGE_URL_AND_SPLIT, async (event, value) => await mJOriginalImageGenerate.DownloadImageUrlAndSplit(value));
|
||||||
|
|
||||||
|
// 获取MJ图片的所有的分割尺寸
|
||||||
|
ipcMain.handle(DEFINE_STRING.MJ.GET_MJ_IMAGE_SCALE, async (event) => await mjSimple.GetMJImageScale());
|
||||||
|
|
||||||
|
// 获取所有的MJ生图模型
|
||||||
|
ipcMain.handle(DEFINE_STRING.MJ.GET_MJ_IMAGE_ROBOT_MODEL, async (event) => await mjSimple.GetMJImageRobotModel());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听DISCORD界面创建消息,并修改数据
|
* 监听DISCORD界面创建消息,并修改数据
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -9,7 +9,11 @@ import path from 'path'
|
|||||||
import sharp from 'sharp'
|
import sharp from 'sharp'
|
||||||
import { define } from "../../define/define";
|
import { define } from "../../define/define";
|
||||||
import { AwesomeRegx } from "awesome-js";
|
import { AwesomeRegx } from "awesome-js";
|
||||||
import { checkStringValueAddSuffix } from "../generalTools";
|
import { checkStringValueAddSuffix, errorMessage, successMessage } from "../generalTools";
|
||||||
|
import { ImageSetting } from "../../define/setting/imageSetting";
|
||||||
|
import { DiscordAPI } from "../../api/discordApi";
|
||||||
|
import { GPT } from "../Public/GPT";
|
||||||
|
const { v4: uuidv4 } = require('uuid');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MJ原创生图的类
|
* MJ原创生图的类
|
||||||
@ -20,6 +24,39 @@ export class MJOriginalImageGenerate {
|
|||||||
this.pm = new PublicMethod(global);
|
this.pm = new PublicMethod(global);
|
||||||
this.discordWorker = new DiscordWorker();
|
this.discordWorker = new DiscordWorker();
|
||||||
this.tools = new Tools();
|
this.tools = new Tools();
|
||||||
|
this.discordAPI = new DiscordAPI();
|
||||||
|
this.gpt = new GPT(global);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 返回指定的人物到前端
|
||||||
|
* @param {*} data
|
||||||
|
*/
|
||||||
|
sendChangeMessage(data) {
|
||||||
|
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.DISCORD.MAIN_DISCORD_MESSAGE_CHANGE, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化MJ设置
|
||||||
|
*/
|
||||||
|
async InitMjSetting() {
|
||||||
|
let mjSetting_res = await ImageSetting.GetDefineConfigJsonByProperty(JSON.stringify(['img_base', 'mj_config', false, null]));
|
||||||
|
if (mjSetting_res.code == 0 || !mjSetting_res.data) {
|
||||||
|
throw new Error("请先添加MJ配置")
|
||||||
|
}
|
||||||
|
let mjSetting = mjSetting_res.data;
|
||||||
|
return mjSetting;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化MJ API的URL
|
||||||
|
*/
|
||||||
|
async InitMJAPIUrl(id) {
|
||||||
|
let mj_api = (await this.gpt.GetGPTBusinessOption("all", (value) => value.mj_url)).data;
|
||||||
|
let mj_api_url_index = mj_api.findIndex(item => item.value == id);
|
||||||
|
if (mj_api_url_index == -1) {
|
||||||
|
throw new Error("没有找到对应的MJ API的配置,请先检查配置")
|
||||||
|
}
|
||||||
|
return mj_api[mj_api_url_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,6 +65,7 @@ export class MJOriginalImageGenerate {
|
|||||||
*/
|
*/
|
||||||
async DownloadImageUrlAndSplit(value) {
|
async DownloadImageUrlAndSplit(value) {
|
||||||
try {
|
try {
|
||||||
|
console.log(value)
|
||||||
value = JSON.parse(value);
|
value = JSON.parse(value);
|
||||||
let element = value[0];
|
let element = value[0];
|
||||||
let iamge_url = value[1];
|
let iamge_url = value[1];
|
||||||
@ -77,52 +115,97 @@ export class MJOriginalImageGenerate {
|
|||||||
async GetGeneratedMJImageAndSplit(value) {
|
async GetGeneratedMJImageAndSplit(value) {
|
||||||
try {
|
try {
|
||||||
value = JSON.parse(value);
|
value = JSON.parse(value);
|
||||||
let param = [];
|
let mjSetting = await this.InitMjSetting();
|
||||||
// 循环数据,直传需要的数据
|
let request_model = mjSetting.request_model;
|
||||||
for (let i = 0; i < value.length; i++) {
|
let result = [];
|
||||||
const element = value[i];
|
// 浏览器生图模式
|
||||||
param.push({
|
if (request_model == "browser_mj") {
|
||||||
id: element.id,
|
let param = [];
|
||||||
image_id: element.mj_message.image_id,
|
// 循环数据,直传需要的数据
|
||||||
name: element.name,
|
for (let i = 0; i < value.length; i++) {
|
||||||
});
|
const element = value[i];
|
||||||
|
// 一般进度大于 50 会出现图片,
|
||||||
|
if (!element.mj_message) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (element.mj_message.progress && element.mj_message.progress == 100) {
|
||||||
|
// 判断 image_path 是不是存在。
|
||||||
|
if (item.mj_message.image_id && !element.mj_message.image_path) {
|
||||||
|
// 通过当前的image_id获取图片
|
||||||
|
param.push({
|
||||||
|
id: element.id,
|
||||||
|
image_id: element.mj_message.image_id,
|
||||||
|
name: element.name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断窗口是不是开启
|
||||||
|
let discordWin = await this.discordWorker.CheckDiscordWindowIsOpenAndLoad();
|
||||||
|
// 执行采集图片的脚本
|
||||||
|
// 开始写入
|
||||||
|
let discordSimple = new DiscordSimple(discordWin);
|
||||||
|
// 开始执行脚本
|
||||||
|
result = await discordSimple.ExecuteScript(define.discordScript, `GetGeneratedMJImageAndSplit(${JSON.stringify(param)})`);
|
||||||
|
|
||||||
|
} else if (request_model == "api_mj") {
|
||||||
|
let mj_api = await this.InitMJAPIUrl(mjSetting.mj_api_url);
|
||||||
|
let once_get_task = mj_api.mj_url.once_get_task;
|
||||||
|
|
||||||
|
// 请求
|
||||||
|
for (let i = 0; i < value.length; i++) {
|
||||||
|
const element = value[i];
|
||||||
|
if (element.mj_message.progress == 100) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (element.mj_message.progress.status == "success") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
let task_res = await this.discordAPI.GetMJAPITaskByID(element.mj_message.message_id, once_get_task, mjSetting.api_key);
|
||||||
|
if (task_res.code == 0) {
|
||||||
|
task_res["id"] = element.id;
|
||||||
|
task_res["mj_api_url"] = mjSetting.mj_api_url;
|
||||||
|
this.sendChangeMessage()
|
||||||
|
}
|
||||||
|
// 判断进度是不是百分百
|
||||||
|
if (task_res.progress != 100) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push({
|
||||||
|
id: element.id,
|
||||||
|
image_id: null,
|
||||||
|
result: task_res.image_click,
|
||||||
|
name: element.name
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断窗口是不是开启
|
|
||||||
let discordWin = await this.discordWorker.CheckDiscordWindowIsOpenAndLoad();
|
|
||||||
// 执行采集图片的脚本
|
|
||||||
// 开始写入
|
|
||||||
let discordSimple = new DiscordSimple(discordWin);
|
|
||||||
// 开始执行脚本
|
|
||||||
let result = await discordSimple.ExecuteScript(define.discordScript, `GetGeneratedMJImageAndSplit(${JSON.stringify(param)})`);
|
|
||||||
|
|
||||||
let res = [];
|
let res = [];
|
||||||
result = JSON.parse(result);
|
// 判断返回的数据是不是一个字符串
|
||||||
|
if (typeof result == "string") {
|
||||||
|
result = JSON.parse(result);
|
||||||
|
}
|
||||||
|
|
||||||
// 将返回的数据进行分割
|
// 将返回的数据进行分割
|
||||||
for (let i = 0; i < result.length; i++) {
|
for (let i = 0; i < result.length; i++) {
|
||||||
const element = result[i];
|
const element = result[i];
|
||||||
let image_path = path.join(global.config.project_path, `data\\MJOriginalImage\\${element.image_id}.png`);
|
let image_path = path.join(global.config.project_path, `data\\MJOriginalImage\\${uuidv4()}.png`);
|
||||||
|
let ds = await this.DownloadImageUrlAndSplit(JSON.stringify([element, element.result, image_path]));
|
||||||
|
|
||||||
let ds = this.DownloadImageUrlAndSplit(JSON.stringify[element, element.result, image_path]);
|
|
||||||
if (ds.code == 0) {
|
if (ds.code == 0) {
|
||||||
throw new Error(ds.message);
|
throw new Error(ds.message);
|
||||||
}
|
}
|
||||||
|
// 修改数据。
|
||||||
|
ds.data["progress"] = 100;
|
||||||
|
ds.data["status"] = "success";
|
||||||
res.push(ds.data);
|
res.push(ds.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 全部分割完毕,返回
|
// 全部分割完毕,返回
|
||||||
return {
|
return successMessage(res);
|
||||||
code: 1,
|
|
||||||
data: res
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return errorMessage("获取已经生图完成的数据,并获取图片错误,错误信息如下" + error.message)
|
||||||
code: 0,
|
|
||||||
message: "获取已经生图完成的数据,并获取图片错误,错误信息如下" + error.message
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,6 +265,114 @@ export class MJOriginalImageGenerate {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用API生图的方法
|
||||||
|
* @param {*} element
|
||||||
|
* @param {*} mjSetting
|
||||||
|
*/
|
||||||
|
async MJImagineRequest(element, mjSetting, prompt) {
|
||||||
|
try {
|
||||||
|
// 获取当前的API url
|
||||||
|
let apiUrl = await this.InitMJAPIUrl(mjSetting.mj_api_url);
|
||||||
|
let imagine_url = apiUrl.mj_url.imagine;
|
||||||
|
let once_get_task = apiUrl.mj_url.once_get_task;
|
||||||
|
let task_count = mjSetting.task_count ? mjSetting.task_count : 3;
|
||||||
|
let request_model = mjSetting.request_model ? mjSetting.request_model : "relaxed";
|
||||||
|
let res;
|
||||||
|
// 判断当前的API是哪个
|
||||||
|
if (imagine_url.includes("mjapi.deepwl.net")) {
|
||||||
|
// DrawAPI(MJ)
|
||||||
|
let data = {
|
||||||
|
prompt: prompt,
|
||||||
|
mode: request_model == "fast" ? "FAST" : "RELAX",
|
||||||
|
}
|
||||||
|
let headers = {
|
||||||
|
"Authorization": mjSetting.api_key
|
||||||
|
}
|
||||||
|
res = await this.discordAPI.mjApiImagine(imagine_url, data, headers);
|
||||||
|
} else if (imagine_url.includes("api.ephone.ai")) {
|
||||||
|
// ePhoneAPI
|
||||||
|
let headers = {
|
||||||
|
"Authorization": mjSetting.api_key
|
||||||
|
}
|
||||||
|
let data = {
|
||||||
|
prompt: prompt,
|
||||||
|
botType: "MID_JOURNEY",
|
||||||
|
accountFilter: {
|
||||||
|
modes: [
|
||||||
|
request_model == "fast" ? "FAST" : "RELAX"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res = await this.discordAPI.mjApiImagine(imagine_url, data, headers);
|
||||||
|
}
|
||||||
|
// 创建成功,开始下一个
|
||||||
|
this.sendChangeMessage({
|
||||||
|
code: 1,
|
||||||
|
type: "created",
|
||||||
|
category: "api_mj",
|
||||||
|
message_id: res.result,
|
||||||
|
image_click: null,
|
||||||
|
image_show: null,
|
||||||
|
id: element.id,
|
||||||
|
progress: 0,
|
||||||
|
mj_api_url: mjSetting.mj_api_url
|
||||||
|
});
|
||||||
|
this.global.mjGenerateQuene.setCurrentCreateItem(null);
|
||||||
|
// 开始监听当前ID是不是的生图任务完成
|
||||||
|
// 这边设置一个循环监听,每隔一段时间去请求一次
|
||||||
|
let timeoutId;
|
||||||
|
let startInterval = () => {
|
||||||
|
timeoutId = setTimeout(async () => {
|
||||||
|
// 执行你的操作
|
||||||
|
let task_res = await this.discordAPI.GetMJAPITaskByID(res.result, once_get_task, mjSetting.api_key)
|
||||||
|
console.log(task_res)
|
||||||
|
// 判断他的状态是不是成功
|
||||||
|
if (task_res.code == 0) {
|
||||||
|
// 将但钱任务删除
|
||||||
|
this.global.mjGenerateQuene.removeTaskProgress((taskProgress) => {
|
||||||
|
return taskProgress.filter(item => item?.id != element.id)
|
||||||
|
});
|
||||||
|
// 停止当前循环
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
} else {
|
||||||
|
if (task_res.progress == 100) {
|
||||||
|
// 将但钱任务删除
|
||||||
|
this.global.mjGenerateQuene.removeTaskProgress((taskProgress) => {
|
||||||
|
return taskProgress.filter(item => item?.id != element.id)
|
||||||
|
});
|
||||||
|
task_res.type = "finished";
|
||||||
|
// 下载对应的图片
|
||||||
|
let image_path = path.join(this.global.config.project_path, `data\\MJOriginalImage\\${task_res.message_id}.png`);
|
||||||
|
// 这边开始下载对应的图片
|
||||||
|
await this.tools.downloadFileUrl(task_res.image_click, image_path);
|
||||||
|
task_res["image_path"] = image_path;
|
||||||
|
// 开始下一个任务
|
||||||
|
this.global.mjGenerateQuene.startNextTask(task_count);
|
||||||
|
} else {
|
||||||
|
// 当获取的图片的进度小于100的时候,继续监听
|
||||||
|
startInterval();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
task_res['id'] = element.id;
|
||||||
|
task_res["mj_api_url"] = mjSetting.mj_api_url;
|
||||||
|
this.sendChangeMessage(task_res);
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
startInterval();
|
||||||
|
this.global.mjGenerateQuene.startNextTask(task_count);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
this.sendChangeMessage({
|
||||||
|
code: 0,
|
||||||
|
status: "error",
|
||||||
|
message: error.message,
|
||||||
|
id: element.id
|
||||||
|
})
|
||||||
|
throw new Error("MJ API 出图错误,错误信息如下:" + error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MJ 原创生图
|
* MJ 原创生图
|
||||||
* @param {*} value
|
* @param {*} value
|
||||||
@ -206,6 +397,8 @@ export class MJOriginalImageGenerate {
|
|||||||
let output_crop_00001 = path.join(this.global.config.project_path, `tmp\\output_crop_00001`);
|
let output_crop_00001 = path.join(this.global.config.project_path, `tmp\\output_crop_00001`);
|
||||||
await this.tools.checkFolderExistsOrCreate(output_crop_00001);
|
await this.tools.checkFolderExistsOrCreate(output_crop_00001);
|
||||||
|
|
||||||
|
// 获取MJ配置
|
||||||
|
let mjSetting = await this.InitMjSetting();
|
||||||
|
|
||||||
// 检查this.global中是不是又mj队列,没有的话创建一个
|
// 检查this.global中是不是又mj队列,没有的话创建一个
|
||||||
if (!this.global.mjGenerateQuene) {
|
if (!this.global.mjGenerateQuene) {
|
||||||
@ -225,35 +418,41 @@ export class MJOriginalImageGenerate {
|
|||||||
let old_prompt = element.prompt;
|
let old_prompt = element.prompt;
|
||||||
// 拼接提示词
|
// 拼接提示词
|
||||||
// 图生图的链接
|
// 图生图的链接
|
||||||
// 获取风格词
|
// 获取风格词 + 命令后缀
|
||||||
let prompt = " " + image_styles + old_prompt;
|
let prompt = " " + image_styles + old_prompt + (mjSetting.image_suffix ? mjSetting.image_suffix : "");
|
||||||
|
|
||||||
|
// 判断当前生图模式
|
||||||
this.global.mjGenerateQuene.enqueue(async () => {
|
let request_model = mjSetting.request_model
|
||||||
try {
|
switch (request_model) {
|
||||||
this.global.mjGenerateQuene.setCurrentCreateItem(element)
|
case "api_mj":
|
||||||
// 开始进行mj生图
|
this.global.mjGenerateQuene.enqueue(async () => {
|
||||||
current_task = element.name;
|
this.global.mjGenerateQuene.setCurrentCreateItem(element)
|
||||||
// 判断窗口是不是开启
|
await this.MJImagineRequest(element, mjSetting, prompt)
|
||||||
|
}, tasK_id, batch)
|
||||||
let discordW = await this.discordWorker.CheckDiscordWindowIsOpenAndLoad();
|
break;
|
||||||
|
case "browser_mj":
|
||||||
// 开始写入
|
this.global.mjGenerateQuene.enqueue(async () => {
|
||||||
let discordSimple = new DiscordSimple(discordW);
|
try {
|
||||||
await discordSimple.WritePromptToInput(prompt);
|
this.global.mjGenerateQuene.setCurrentCreateItem(element)
|
||||||
|
// 开始进行mj生图
|
||||||
// 发送命令完成(删除当前正在执行。开始下一个任务)
|
current_task = element.name;
|
||||||
|
// 判断窗口是不是开启
|
||||||
} catch (error) {
|
let discordW = await this.discordWorker.CheckDiscordWindowIsOpenAndLoad();
|
||||||
throw error;
|
// 开始写入
|
||||||
}
|
let discordSimple = new DiscordSimple(discordW, mjSetting);
|
||||||
|
await discordSimple.WritePromptToInput(prompt);
|
||||||
|
// 发送命令完成(删除当前正在执行。开始下一个任务)
|
||||||
}, tasK_id, batch);
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}, tasK_id, batch);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断该当前正在执行的人物队列数(小于设置的数量,开始一个任务)
|
// 判断该当前正在执行的人物队列数(小于设置的数量,开始一个任务)
|
||||||
this.global.mjGenerateQuene.startNextTask();
|
this.global.mjGenerateQuene.startNextTask(mjSetting.task_count ? mjSetting.task_count : 3);
|
||||||
|
|
||||||
this.global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => {
|
this.global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => {
|
||||||
if (failedTasks.length > 0) {
|
if (failedTasks.length > 0) {
|
||||||
@ -265,31 +464,16 @@ export class MJOriginalImageGenerate {
|
|||||||
message += `${taskId}-, \n 错误信息: ${error}` + '\n';
|
message += `${taskId}-, \n 错误信息: ${error}` + '\n';
|
||||||
});
|
});
|
||||||
|
|
||||||
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
|
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, errorMessage(message))
|
||||||
code: 0,
|
|
||||||
message: message
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
if (show_global_message) {
|
if (show_global_message) {
|
||||||
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
|
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, successMessage(null, '所有MJ生图任务完成'))
|
||||||
code: 1,
|
|
||||||
message: "所有MJ生图任务完成"
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return successMessage(null)
|
||||||
|
|
||||||
return {
|
|
||||||
code: 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return errorMessage("MJ生图错误,错误信息如下" + error.message)
|
||||||
code: 0,
|
|
||||||
message: "MJ生图错误,错误信息如下" + error.message
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -214,7 +214,6 @@ export class OriginalImageGenerate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自动保存数据到json文件
|
* 自动保存数据到json文件
|
||||||
* @param {*} value 自动保存数据到json文件
|
* @param {*} value 自动保存数据到json文件
|
||||||
@ -223,9 +222,11 @@ export class OriginalImageGenerate {
|
|||||||
try {
|
try {
|
||||||
// 目前自动保存的信息,中文提示词,英文提示词,前缀,后缀
|
// 目前自动保存的信息,中文提示词,英文提示词,前缀,后缀
|
||||||
value = JSON.parse(value);
|
value = JSON.parse(value);
|
||||||
|
let batch = DEFINE_STRING.QUEUE_BATCH.AUTO_SAVE_DATA_JSON;
|
||||||
for (let i = 0; i < value.length; i++) {
|
for (let i = 0; i < value.length; i++) {
|
||||||
const element = value[i];
|
const element = value[i];
|
||||||
// 将修改文件的的方法添加到修改文件队列中
|
// 将修改文件的的方法添加到修改文件队列中
|
||||||
|
|
||||||
this.global.fileQueue.enqueue(async () => {
|
this.global.fileQueue.enqueue(async () => {
|
||||||
try {
|
try {
|
||||||
if (element.prompt_json) {
|
if (element.prompt_json) {
|
||||||
@ -244,7 +245,7 @@ export class OriginalImageGenerate {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
});
|
}, `${batch}_${element.id}`, batch);
|
||||||
|
|
||||||
// 判断是不是有图片。判断图片是不是符合格式(有些格式是file:// 开头的, 以时间结尾(都要删除))
|
// 判断是不是有图片。判断图片是不是符合格式(有些格式是file:// 开头的, 以时间结尾(都要删除))
|
||||||
// 判断是不是有图片
|
// 判断是不是有图片
|
||||||
|
|||||||
@ -4,6 +4,8 @@ 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 "../generalTools";
|
||||||
|
|
||||||
export class GPT {
|
export class GPT {
|
||||||
constructor(global) {
|
constructor(global) {
|
||||||
@ -255,6 +257,18 @@ export class GPT {
|
|||||||
gpt_key = this.global.config.gpt_key,
|
gpt_key = this.global.config.gpt_key,
|
||||||
gpt_model = this.global.config.gpt_model) {
|
gpt_model = this.global.config.gpt_model) {
|
||||||
try {
|
try {
|
||||||
|
// 还有自定义的
|
||||||
|
let all_options = (await this.GetGPTBusinessOption("all", (value) => value.gpt_url)).data;
|
||||||
|
// 判断gpt_business 是不是一个http开头的
|
||||||
|
if (!gpt_url.includes("http")) {
|
||||||
|
// 获取对应Id的gpt_url
|
||||||
|
let index = all_options.findIndex(item => item.value == gpt_url && item.gpt_url);
|
||||||
|
if (index < 0) {
|
||||||
|
throw new Error("获取GPT的服务商配置失败");
|
||||||
|
}
|
||||||
|
gpt_url = all_options[index].gpt_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
"model": gpt_model,
|
"model": gpt_model,
|
||||||
@ -268,7 +282,8 @@ export class GPT {
|
|||||||
url: gpt_url,
|
url: gpt_url,
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${gpt_key}`,
|
'Authorization': `Bearer ${gpt_key}`,
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json',
|
||||||
|
"Accept": "application/json"
|
||||||
},
|
},
|
||||||
data: JSON.stringify(data)
|
data: JSON.stringify(data)
|
||||||
};
|
};
|
||||||
@ -317,8 +332,16 @@ export class GPT {
|
|||||||
* 获取GPT的服务商配置,默认的和自定义的
|
* 获取GPT的服务商配置,默认的和自定义的
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async GetGPTBusinessOption(value) {
|
async GetGPTBusinessOption(value, callback = null) {
|
||||||
return await gptDefine.getGptDataByTypeAndProperty(value, "gpt_options", []);
|
let res = await gptDefine.getGptDataByTypeAndProperty(value, "gpt_options", []);
|
||||||
|
if (res.code == 0) {
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
if (callback) {
|
||||||
|
callback(res.data)
|
||||||
|
}
|
||||||
|
return successMessage(res.data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
48
src/main/Public/Image.js
Normal file
48
src/main/Public/Image.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { errorMessage, successMessage } from "../generalTools";
|
||||||
|
import path from "path";
|
||||||
|
import { Tools } from "../tools";
|
||||||
|
|
||||||
|
export class Image {
|
||||||
|
constructor(global) {
|
||||||
|
this.global = global;
|
||||||
|
this.tools = new Tools();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将指定的文件夹复制到四个文件夹中
|
||||||
|
async OneSplitFour(value) {
|
||||||
|
try {
|
||||||
|
value = JSON.parse(value);
|
||||||
|
let count = value[1];
|
||||||
|
let data = value[0];
|
||||||
|
// 先创建输出文件
|
||||||
|
if (count <= 1) {
|
||||||
|
throw new Error("可选择的图片的数量必须大于1");
|
||||||
|
}
|
||||||
|
for (let i = 1; i < count; i++) {
|
||||||
|
let out_folder = path.join(this.global.config.project_path, `tmp/output_crop_0000${i + 1}`);
|
||||||
|
// 判断当前的文件夹是不是存在,存在删除
|
||||||
|
let isH = await this.tools.checkExists(out_folder);
|
||||||
|
if (isH) {
|
||||||
|
await this.tools.deleteFileOrDirectory(out_folder);
|
||||||
|
}
|
||||||
|
await this.tools.checkFolderExistsOrCreate(out_folder)
|
||||||
|
}
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
const element = data[i];
|
||||||
|
let subImagePath = element.subImagePath;
|
||||||
|
for (let j = 1; j < count; j++) {
|
||||||
|
let out_file = path.join(this.global.config.project_path, `tmp/output_crop_0000${j + 1}/${element.name}`);
|
||||||
|
if (subImagePath[j] && subImagePath[j].startsWith("file")) {
|
||||||
|
subImagePath[j] = subImagePath[j].replace("file://", "");
|
||||||
|
subImagePath[j] = subImagePath[j].replace(/\?time=.*$/, '');
|
||||||
|
}
|
||||||
|
await this.tools.copyFileOrDirectory(subImagePath[j], out_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return successMessage("拆分成功");
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
return errorMessage(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -365,7 +365,7 @@ export class VideoGenerate {
|
|||||||
// let task_list = JSON.parse(await fspromises.readFile(path.join(this.global.config.project_path,'scripts/task_')));
|
// let task_list = JSON.parse(await fspromises.readFile(path.join(this.global.config.project_path,'scripts/task_')));
|
||||||
let scriptPath = path.join(define.scripts_path, 'Lai.exe');
|
let scriptPath = path.join(define.scripts_path, 'Lai.exe');
|
||||||
// 执行生成图片的脚本
|
// 执行生成图片的脚本
|
||||||
let script = `cd "${define.scripts_path}" && "${scriptPath}" -c "${project_config_path.replaceAll('\\', '/')}"`;
|
let script = `cd "${define.scripts_path}" && "${scriptPath}" -c "${project_config_path.replaceAll('\\', '/')}" "${this.global.gpu.type}"`;
|
||||||
const output = await execAsync(script, { maxBuffer: 1024 * 1024 * 10, encoding: 'utf-8' });
|
const output = await execAsync(script, { maxBuffer: 1024 * 1024 * 10, encoding: 'utf-8' });
|
||||||
if (output.stderr != '') {
|
if (output.stderr != '') {
|
||||||
obj.status = "video_error";
|
obj.status = "video_error";
|
||||||
|
|||||||
@ -1,482 +0,0 @@
|
|||||||
const axios = require('axios');
|
|
||||||
const fetch = require("node-fetch");
|
|
||||||
|
|
||||||
export class DiscordAPI {
|
|
||||||
constructor(mj_setting) {
|
|
||||||
// https://discord.com/api/v9/channels/1208362852482809939/messages?limit=20
|
|
||||||
this.apiClient = axios.create({
|
|
||||||
baseURL: 'https://discord.com'
|
|
||||||
});
|
|
||||||
this.DiscordBaseUrl = 'https://discord.com';
|
|
||||||
this.ServerId = mj_setting.serviceID;
|
|
||||||
this.ChannelId = mj_setting.channelID;
|
|
||||||
this.userToken = mj_setting.token;
|
|
||||||
this.botId = mj_setting.select_robot?.botId;
|
|
||||||
this.commandId = mj_setting.select_robot?.commandId;
|
|
||||||
this.versionId = mj_setting.select_robot?.versionId;
|
|
||||||
this.versionName = mj_setting.select_robot?.versionName;
|
|
||||||
this.botName = mj_setting.select_robot?.botName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 提交任务
|
|
||||||
async imagine(data) {
|
|
||||||
|
|
||||||
// let req_data = {
|
|
||||||
// "token": this.userToken,
|
|
||||||
// "method": "post",
|
|
||||||
// "api_url": "/mj/submit/imagine",
|
|
||||||
// "data":data
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
|
|
||||||
// await this.interactions(data.prompt);
|
|
||||||
return await this.interactions(data.prompt)
|
|
||||||
// return {
|
|
||||||
// code:1,
|
|
||||||
// result:'taskid_'+new Date().getTime()
|
|
||||||
// }
|
|
||||||
// return response.data;
|
|
||||||
|
|
||||||
}
|
|
||||||
async channelList() {
|
|
||||||
axios.get(`https://discord.com/api/v9/channels/${this.ChannelId}/messages?limit=20`, {
|
|
||||||
method: 'get',
|
|
||||||
headers: {
|
|
||||||
"Authorization": this.userToken
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(response => {
|
|
||||||
// 请求成功处理
|
|
||||||
console.log(typeof response.data);
|
|
||||||
let eList = []
|
|
||||||
let flg = false;
|
|
||||||
let job_id = '';
|
|
||||||
let type = '';
|
|
||||||
if (response && response.data) {
|
|
||||||
try {
|
|
||||||
response.data.forEach(element => {
|
|
||||||
flg = false;
|
|
||||||
type = '';
|
|
||||||
if (element.attachments && element.attachments.length) {
|
|
||||||
const arr = element.attachments[0].filename.split("_");
|
|
||||||
job_id = arr[arr.length - 1].replace(".png", '');
|
|
||||||
if (element.components) {
|
|
||||||
element.components.forEach(e2 => {
|
|
||||||
e2.components.forEach(e3 => {
|
|
||||||
if (e3.label == 'U1') {
|
|
||||||
flg = true;
|
|
||||||
type = 'U1'
|
|
||||||
} else if (e3.label && e3.label.indexOf('Upscale') > -1) {
|
|
||||||
flg = true;
|
|
||||||
type = 'Upscale'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let t = eList.find((e) => {
|
|
||||||
return e.filename == element.attachments[0].filename;
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!t) {
|
|
||||||
eList.push(
|
|
||||||
{
|
|
||||||
flg: flg, job_id: job_id, filename: element.attachments[0].filename,
|
|
||||||
url: element.attachments[0].url,
|
|
||||||
proxy_url: element.attachments[0].proxy_url,
|
|
||||||
type: type,
|
|
||||||
timestamp: element.timestamp
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log({flg:flg,job_id:job_id,filename:element.attachments[0].filename})
|
|
||||||
} else {
|
|
||||||
console.log({ flg: flg })
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.log('异常2', error)
|
|
||||||
}
|
|
||||||
// console.log(eList)
|
|
||||||
// 8e7406df-bf0c-4e3d-8e49-b2bb8e2c263d
|
|
||||||
// 5abedc71-ba80-4756-8ddc-489c927d3acd
|
|
||||||
}
|
|
||||||
}).catch(error => {
|
|
||||||
// 请求失败处理
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// 混合
|
|
||||||
async blend(data) {
|
|
||||||
|
|
||||||
let req_data = {
|
|
||||||
"token": this.userToken,
|
|
||||||
"method": "post",
|
|
||||||
"api_url": "/mj/submit/blend",
|
|
||||||
"data": data
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
|
|
||||||
return response.data;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 反推
|
|
||||||
async describe(data) {
|
|
||||||
|
|
||||||
let req_data = {
|
|
||||||
"token": this.userToken,
|
|
||||||
"method": "post",
|
|
||||||
"api_url": "/mj/submit/describe",
|
|
||||||
"data": data
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
|
|
||||||
return response.data;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取任务
|
|
||||||
async getTaskId(task_id) {
|
|
||||||
let req_data = {
|
|
||||||
"token": this.userToken,
|
|
||||||
"method": "get",
|
|
||||||
"api_url": `/mj/task/${task_id}/fetch`,
|
|
||||||
"data": {}
|
|
||||||
}
|
|
||||||
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
|
|
||||||
return response.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取seed
|
|
||||||
async imageSeed(task_id) {
|
|
||||||
let req_data = {
|
|
||||||
"token": this.userToken,
|
|
||||||
"method": "get",
|
|
||||||
"api_url": `/mj/task/${task_id}/image-seed`,
|
|
||||||
"data": {}
|
|
||||||
}
|
|
||||||
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
|
|
||||||
return response.data;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//账号创建
|
|
||||||
async account_create(data) {
|
|
||||||
let req_data = {
|
|
||||||
"token": this.userToken,
|
|
||||||
"method": "post",
|
|
||||||
"api_url": '/mj/account/create',
|
|
||||||
"data": data
|
|
||||||
}
|
|
||||||
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data, { timeout: 20000 });
|
|
||||||
return response.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//账号创建
|
|
||||||
async account_fetch(cid) {
|
|
||||||
let req_data = {
|
|
||||||
"token": this.userToken,
|
|
||||||
"method": "get",
|
|
||||||
"api_url": `/mj/account/${cid}/fetch`,
|
|
||||||
"data": {}
|
|
||||||
}
|
|
||||||
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
|
|
||||||
return response.data;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//账号同步信息
|
|
||||||
async account_asyn_info(cid) {
|
|
||||||
let req_data = {
|
|
||||||
"token": this.userToken,
|
|
||||||
"method": "post",
|
|
||||||
"api_url": `/mj/account/${cid}/sync-info`,
|
|
||||||
"data": {}
|
|
||||||
}
|
|
||||||
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data, { timeout: 20000 });
|
|
||||||
return response.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//账号删除信息
|
|
||||||
async account_del_info(cid) {
|
|
||||||
let req_data = {
|
|
||||||
"token": this.userToken,
|
|
||||||
"method": "delete",
|
|
||||||
"api_url": `/mj/account/${cid}/delete`,
|
|
||||||
"data": {}
|
|
||||||
}
|
|
||||||
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
|
|
||||||
return response.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//执行动作
|
|
||||||
async action(data) {
|
|
||||||
let req_data = {
|
|
||||||
"token": this.userToken,
|
|
||||||
"method": "post",
|
|
||||||
"api_url": '/mj/submit/action',
|
|
||||||
"data": data
|
|
||||||
}
|
|
||||||
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
|
|
||||||
return response.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 确认弹窗
|
|
||||||
async modal(data) {
|
|
||||||
let req_data = {
|
|
||||||
"token": this.userToken,
|
|
||||||
"method": "post",
|
|
||||||
"api_url": '/mj/submit/modal',
|
|
||||||
"data": data
|
|
||||||
}
|
|
||||||
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
|
|
||||||
return response.data;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async interactions(prompt) {
|
|
||||||
// 直接自己调用
|
|
||||||
prompt = prompt.trim();
|
|
||||||
// prompt = "4k,8k,best quality, masterpiece, woman, divorced, leaving fast-paced city life, serene expression, walking away from cityscape, bustling streets, entering tranquil countryside, peaceful surroundings, rejuvenating atmosphere, , --niji 5 --ar 4:3"
|
|
||||||
var payload = {};
|
|
||||||
if (this.botName == 'niji') {
|
|
||||||
payload = {
|
|
||||||
"type": 2,
|
|
||||||
"application_id": this.botId,
|
|
||||||
"guild_id": this.ServerId,
|
|
||||||
"channel_id": this.ChannelId,
|
|
||||||
"session_id": this.userToken,
|
|
||||||
"data": {
|
|
||||||
"version": this.versionId,
|
|
||||||
"id": this.commandId,
|
|
||||||
"name": "imagine",
|
|
||||||
"type": 1,
|
|
||||||
"options": [
|
|
||||||
{
|
|
||||||
"type": 3,
|
|
||||||
"name": "prompt",
|
|
||||||
"value": prompt
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"application_command": {
|
|
||||||
"id": this.commandId,
|
|
||||||
"type": 1,
|
|
||||||
"application_id": this.botId,
|
|
||||||
"version": this.versionId,
|
|
||||||
"name": "imagine",
|
|
||||||
"description": "Create images with Midjourney",
|
|
||||||
"options": [
|
|
||||||
{
|
|
||||||
"type": 3,
|
|
||||||
"name": "prompt",
|
|
||||||
"description": "The prompt to imagine",
|
|
||||||
"required": true,
|
|
||||||
"description_localized": "The prompt to imagine",
|
|
||||||
"name_localized": "prompt"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"integration_types": [
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"global_popularity_rank": 1,
|
|
||||||
"description_localized": "Create images with Midjourney",
|
|
||||||
"name_localized": "imagine"
|
|
||||||
},
|
|
||||||
"attachments": [
|
|
||||||
|
|
||||||
]
|
|
||||||
},
|
|
||||||
// "nonce": "1210857131343872000",
|
|
||||||
"analytics_location": "slash_ui"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
payload = {
|
|
||||||
"type": 2,
|
|
||||||
// "application_id":"1022952195194359889",//niji
|
|
||||||
"application_id": this.botId,
|
|
||||||
"guild_id": this.ServerId,
|
|
||||||
"channel_id": this.ChannelId,
|
|
||||||
"session_id": this.userToken,
|
|
||||||
"data": {
|
|
||||||
"version": this.versionId,
|
|
||||||
"id": this.commandId,
|
|
||||||
"name": "imagine", "type": 1,
|
|
||||||
"options":
|
|
||||||
[{
|
|
||||||
"type": 3,
|
|
||||||
"name": "prompt",
|
|
||||||
"value": prompt
|
|
||||||
}],
|
|
||||||
"application_command": {
|
|
||||||
"id": this.commandId,
|
|
||||||
"type": 1,
|
|
||||||
"application_id": this.botId,
|
|
||||||
"version": this.versionId,
|
|
||||||
"name": "imagine",
|
|
||||||
"description": "Create images with Niji journey",
|
|
||||||
"options": [{ "type": 3, "name": "prompt", "description": "The prompt to imagine", "required": true, "description_localized": "The prompt to imagine", "name_localized": "prompt" }],
|
|
||||||
"integration_types": [0], "global_popularity_rank": 1, "description_localized": "Create images with Niji journey", "name_localized": "imagine"
|
|
||||||
},
|
|
||||||
"attachments": []
|
|
||||||
},
|
|
||||||
"analytics_location": "slash_ui"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let response = {
|
|
||||||
status: 200,
|
|
||||||
data: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
|
||||||
const headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: this.userToken,
|
|
||||||
};
|
|
||||||
await fetch(`${this.DiscordBaseUrl}/api/v9/interactions`, {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify(payload),
|
|
||||||
headers: headers,
|
|
||||||
}).then(res => res.json()).then(res => {
|
|
||||||
response.data = res;
|
|
||||||
}).catch(e => {
|
|
||||||
console.error("请求失败了,详细信息:" + JSON.stringify(e));
|
|
||||||
response = {
|
|
||||||
status: 500,
|
|
||||||
data: JSON.stringify(e)
|
|
||||||
};
|
|
||||||
});
|
|
||||||
console.log('response结果')
|
|
||||||
console.log(response)
|
|
||||||
// if (response.status == 204) {
|
|
||||||
// //成功
|
|
||||||
|
|
||||||
// }
|
|
||||||
if (response.status >= 400) {
|
|
||||||
console.error("api.error.config", {
|
|
||||||
payload: JSON.stringify(payload)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
code: response.status,
|
|
||||||
response: response
|
|
||||||
};
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
return 500;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
const client = new Midjourney.Midjourney({
|
|
||||||
ServerId: this.ServerId,
|
|
||||||
ChannelId: this.ChannelId,
|
|
||||||
SalaiToken: this.userToken,
|
|
||||||
Debug: true,
|
|
||||||
fetch: fetch,
|
|
||||||
Ws: true, //enable ws is required for remix mode (and custom zoom)
|
|
||||||
});
|
|
||||||
await client.init();
|
|
||||||
console.log('mjmj_begin2', prompt);
|
|
||||||
// const prompt =
|
|
||||||
// "Christmas dinner with spaghetti with family in a cozy house, we see interior details , simple blue&white illustration";
|
|
||||||
//imagine
|
|
||||||
const Imagine = await client.Imagine(
|
|
||||||
prompt,
|
|
||||||
(uri, progress) => {
|
|
||||||
client.Close();
|
|
||||||
|
|
||||||
console.log("loading", uri, "progress", progress);
|
|
||||||
return
|
|
||||||
}
|
|
||||||
);
|
|
||||||
console.log(Imagine);
|
|
||||||
if (!Imagine) {
|
|
||||||
console.log("no message");
|
|
||||||
console.log('mjmj_end2')
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log('mjmj_end')
|
|
||||||
client.Close();
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取频道内的机器人
|
|
||||||
* @returns 返回机器人列表
|
|
||||||
*/
|
|
||||||
async getBotList() {
|
|
||||||
try {
|
|
||||||
|
|
||||||
const headers = {
|
|
||||||
'Host': 'discord.com',
|
|
||||||
'Connection': 'keep-alive',
|
|
||||||
'authorization': this.userToken,
|
|
||||||
}
|
|
||||||
|
|
||||||
await fetch('https://discord.com/api/v9/guilds/1182523906855284826/application-command-index', {
|
|
||||||
method: 'GET',
|
|
||||||
headers: headers,
|
|
||||||
})
|
|
||||||
.then(response => {
|
|
||||||
response.json()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then(data => {
|
|
||||||
console.log(data)
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error:', error)
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
throw new Error(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async getMjMsgList() {
|
|
||||||
// const headers = {
|
|
||||||
// "Content-Type": "application/json",
|
|
||||||
// Authorization:this.userToken,
|
|
||||||
// };
|
|
||||||
let response = {
|
|
||||||
status: 200,
|
|
||||||
data: {}
|
|
||||||
};
|
|
||||||
// // `https://discord.com/api/v9/channels/${mj_channelId}/messages?limit=10
|
|
||||||
// await fetch(`${this.DiscordBaseUrl}/api/v9/channels/${this.ChannelId}/messages?limit=50`, {
|
|
||||||
// method: "GET",
|
|
||||||
// headers: headers,
|
|
||||||
// }).then(res => res.json()).then(res => {
|
|
||||||
// response.data=res;
|
|
||||||
// }).catch(e => {
|
|
||||||
// console.error("请求失败了,详细信息:" + JSON.stringify(e));
|
|
||||||
// response ={
|
|
||||||
// status:500,
|
|
||||||
// data:JSON.stringify(e)
|
|
||||||
// };
|
|
||||||
// });
|
|
||||||
// console.log('getMjMsgList_response结果')
|
|
||||||
// // console.log(response)
|
|
||||||
|
|
||||||
// return response;
|
|
||||||
axios.get(`https://discord.com/api/v9/channels/${this.ChannelId}/messages?limit=20`, {
|
|
||||||
method: 'get',
|
|
||||||
headers: {
|
|
||||||
"Authorization": this.userToken
|
|
||||||
}
|
|
||||||
}).then(res => {
|
|
||||||
response.data = res;
|
|
||||||
}).catch(error => {
|
|
||||||
// 请求失败处理
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -10,10 +10,11 @@ import { DEFINE_STRING } from "../../define/define_string";
|
|||||||
* 对DisCord窗口进行操作的方法
|
* 对DisCord窗口进行操作的方法
|
||||||
*/
|
*/
|
||||||
export class DiscordSimple {
|
export class DiscordSimple {
|
||||||
constructor(win) {
|
constructor(win, mjSetting) {
|
||||||
this.win = win;
|
this.win = win;
|
||||||
this.tools = new Tools();
|
this.tools = new Tools();
|
||||||
this.script = define.discordScript;
|
this.script = define.discordScript;
|
||||||
|
this.mjSetting = mjSetting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -103,7 +104,7 @@ export class DiscordSimple {
|
|||||||
async GetInputPosition() {
|
async GetInputPosition() {
|
||||||
try {
|
try {
|
||||||
await this.InitData();
|
await this.InitData();
|
||||||
await this.tools.delay(10000)
|
await this.tools.delay(this.mjSetting.space_time ? this.mjSetting.space_time * 1000 : 10000)
|
||||||
let result = await this.ExecuteScript(this.script, 'GetMessageInputPosition()');
|
let result = await this.ExecuteScript(this.script, 'GetMessageInputPosition()');
|
||||||
this.x = result.mouseX;
|
this.x = result.mouseX;
|
||||||
this.y = result.mouseY;
|
this.y = result.mouseY;
|
||||||
@ -641,6 +642,7 @@ export class DiscordSimple {
|
|||||||
let currentCreateItem = global.mjGenerateQuene.getCurrentCreateItem();
|
let currentCreateItem = global.mjGenerateQuene.getCurrentCreateItem();
|
||||||
console.log("LAITOOL 创建数据: ", value);
|
console.log("LAITOOL 创建数据: ", value);
|
||||||
value.type = "created"
|
value.type = "created"
|
||||||
|
value.category = "browser_mj"
|
||||||
|
|
||||||
// 判断是不是是不是错误数据
|
// 判断是不是是不是错误数据
|
||||||
if (value.error) {
|
if (value.error) {
|
||||||
@ -652,7 +654,7 @@ export class DiscordSimple {
|
|||||||
// 在将当前任务设置为空
|
// 在将当前任务设置为空
|
||||||
global.mjGenerateQuene.setCurrentCreateItem(null);
|
global.mjGenerateQuene.setCurrentCreateItem(null);
|
||||||
// 开始下一个任务
|
// 开始下一个任务
|
||||||
global.mjGenerateQuene.startNextTask();
|
global.mjGenerateQuene.startNextTask(this.mjSetting.task_count ? this.mjSetting.task_count : 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -702,7 +704,7 @@ export class DiscordSimple {
|
|||||||
global.mjGenerateQuene.setCurrentCreateItem(null);
|
global.mjGenerateQuene.setCurrentCreateItem(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
global.mjGenerateQuene.startNextTask();
|
global.mjGenerateQuene.startNextTask(this.mjSetting.task_count ? this.mjSetting.task_count : 3);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.sendChangeMessage({
|
this.sendChangeMessage({
|
||||||
@ -722,6 +724,7 @@ export class DiscordSimple {
|
|||||||
// 接收到discord的消息
|
// 接收到discord的消息
|
||||||
console.log("LAITOOL 更新数据: ", value);
|
console.log("LAITOOL 更新数据: ", value);
|
||||||
value.type = "updated";
|
value.type = "updated";
|
||||||
|
value.category = "browser_mj"
|
||||||
|
|
||||||
// 更新的时候,修改数据(判断是不是有进度)
|
// 更新的时候,修改数据(判断是不是有进度)
|
||||||
let regex = /\((\d+)%\)/;
|
let regex = /\((\d+)%\)/;
|
||||||
@ -760,6 +763,7 @@ export class DiscordSimple {
|
|||||||
}
|
}
|
||||||
console.log("LAITOOL 删除数据: ", value)
|
console.log("LAITOOL 删除数据: ", value)
|
||||||
value.type = "delete"
|
value.type = "delete"
|
||||||
|
value.category = "browser_mj"
|
||||||
this.sendChangeMessage(value)
|
this.sendChangeMessage(value)
|
||||||
|
|
||||||
// 这边可能要做判断(判断是不是开启下一个)
|
// 这边可能要做判断(判断是不是开启下一个)
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
let path = require('path');
|
let path = require('path');
|
||||||
import { Tools } from "../tools";
|
import { Tools } from "../tools";
|
||||||
import { DiscordAPI } from "./discordApi";
|
import { DiscordAPI } from "../../api/discordApi";
|
||||||
import { MjSetting } from "../../define/setting/mjSetting";
|
import { MjSetting } from "../../define/setting/mjSetting";
|
||||||
import { DynamicSetting } from "../../define/setting/dynamicSetting";
|
import { DynamicSetting } from "../../define/setting/dynamicSetting";
|
||||||
import { AwesomeHelp } from "awesome-js"
|
import { AwesomeHelp } from "awesome-js"
|
||||||
|
import { errorMessage, successMessage } from "../generalTools";
|
||||||
|
|
||||||
export class MjSimple {
|
export class MjSimple {
|
||||||
constructor(global) {
|
constructor(global) {
|
||||||
@ -58,8 +59,6 @@ export class MjSimple {
|
|||||||
value = JSON.parse(value);
|
value = JSON.parse(value);
|
||||||
let discordAPI = new DiscordAPI(value);
|
let discordAPI = new DiscordAPI(value);
|
||||||
let res = await discordAPI.getBotList();
|
let res = await discordAPI.getBotList();
|
||||||
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
code: 0,
|
code: 0,
|
||||||
@ -102,7 +101,10 @@ export class MjSimple {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取MJ所有的敏感词
|
/**
|
||||||
|
* 获取MJ所有的敏感词
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
async GetMJBadPrompt() {
|
async GetMJBadPrompt() {
|
||||||
try {
|
try {
|
||||||
let default_bad_prompt = this.mjSetting.GetMJBadPrompt().data;
|
let default_bad_prompt = this.mjSetting.GetMJBadPrompt().data;
|
||||||
@ -119,6 +121,34 @@ export class MjSimple {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有的MJ的图片比例
|
||||||
|
*/
|
||||||
|
async GetMJImageScale() {
|
||||||
|
try {
|
||||||
|
let default_image_scale = this.mjSetting.GetMJImageScale().data;
|
||||||
|
let data = await this.dynamicSetting.getDataByTypeAndProperty("all", 'mj', 'image_scale', default_image_scale, []);
|
||||||
|
return successMessage(data.data)
|
||||||
|
} catch (error) {
|
||||||
|
return errorMessage("获取图片比例失败, 错误信息如下:" + error.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有的生图机器人模型
|
||||||
|
*/
|
||||||
|
async GetMJImageRobotModel() {
|
||||||
|
try {
|
||||||
|
let default_image_robot_model = this.mjSetting.GetMJImageRobotModel().data;
|
||||||
|
let data = await this.dynamicSetting.getDataByTypeAndProperty("all", 'mj', 'image_robot_model', default_image_robot_model, []);
|
||||||
|
return successMessage(data.data)
|
||||||
|
} catch (error) {
|
||||||
|
return errorMessage("获取生图机器人模型失败, 错误信息如下:" + error.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查当前出入数据所有的敏感词
|
* 检查当前出入数据所有的敏感词
|
||||||
* @param {*} data
|
* @param {*} data
|
||||||
@ -175,10 +205,6 @@ export class MjSimple {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(res);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(bad_prompt_ids)
|
console.log(bad_prompt_ids)
|
||||||
|
|||||||
@ -970,10 +970,7 @@ async function DeleteBadPrompt() {
|
|||||||
* 打开购买 GPT 的网址
|
* 打开购买 GPT 的网址
|
||||||
*/
|
*/
|
||||||
async function openGptBuyUrl(value) {
|
async function openGptBuyUrl(value) {
|
||||||
// console.log(value)
|
OpenUrl(value)
|
||||||
if (value == "https://api.openai-hk.com/v1/chat/completions") {
|
|
||||||
OpenUrl('https://openai-hk.com/?i=10196')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1055,7 +1052,7 @@ async function StartStoryboarding(value) {
|
|||||||
|
|
||||||
global.newWindow[0].win.webContents.send(DEFINE_STRING.GET_FRAME_RETUN, { code: 1, data: "正在调用进程。请勿关闭程序" })
|
global.newWindow[0].win.webContents.send(DEFINE_STRING.GET_FRAME_RETUN, { code: 1, data: "正在调用进程。请勿关闭程序" })
|
||||||
let cc = `${path.join(define.scripts_path, 'Lai.exe')}`;
|
let cc = `${path.join(define.scripts_path, 'Lai.exe')}`;
|
||||||
let child = spawn(cc, ["-a", value.video_path, frame_path, input_path, value.sensitivity], { encoding: 'utf-8' });
|
let child = spawn(cc, ["-a", value.video_path, frame_path, input_path, value.sensitivity, global.gpu.type], { encoding: 'utf-8' });
|
||||||
child.on('error', console.error)
|
child.on('error', console.error)
|
||||||
child.stdout.on('data', (data) => {
|
child.stdout.on('data', (data) => {
|
||||||
console.log(data.toString());
|
console.log(data.toString());
|
||||||
|
|||||||
@ -66,7 +66,6 @@ function checkStringValueDeletePrefix(value, prefix) {
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 返回成功的消息,包含code,data,message
|
* 返回成功的消息,包含code,data,message
|
||||||
* @param {*} code
|
|
||||||
* @param {*} data
|
* @param {*} data
|
||||||
* @param {*} message
|
* @param {*} message
|
||||||
* @returns
|
* @returns
|
||||||
@ -81,7 +80,6 @@ function successMessage(data, message = null) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回失败的消息,包含code,message
|
* 返回失败的消息,包含code,message
|
||||||
* @param {*} code
|
|
||||||
* @param {*} message
|
* @param {*} message
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import fspromises from "fs/promises";
|
import fspromises from "fs/promises";
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import { version } from '../../package.json'
|
import { version } from '../../package.json'
|
||||||
|
import { graphics } from "systeminformation"
|
||||||
|
|
||||||
|
|
||||||
import { app, shell, BrowserWindow, ipcMain, dialog, nativeTheme } from 'electron'
|
import { app, shell, BrowserWindow, ipcMain, dialog, nativeTheme } from 'electron'
|
||||||
@ -29,6 +30,8 @@ import { SdIpc } from './IPCEvent/sdIpc.js'
|
|||||||
import { DiscordIpc, RemoveDiscordIpc } from './IPCEvent/discordIpc.js'
|
import { DiscordIpc, RemoveDiscordIpc } from './IPCEvent/discordIpc.js'
|
||||||
import { MainIpc } from './IPCEvent/mainIpc.js'
|
import { MainIpc } from './IPCEvent/mainIpc.js'
|
||||||
import { GlobalIpc } from "./IPCEvent/globalIpc.js";
|
import { GlobalIpc } from "./IPCEvent/globalIpc.js";
|
||||||
|
import { ImageIpc } from "./IPCEvent/imageIpc.js";
|
||||||
|
import { system } from "systeminformation";
|
||||||
|
|
||||||
let tools = new Tools();
|
let tools = new Tools();
|
||||||
let imageGenerate = new ImageGenerate(global);
|
let imageGenerate = new ImageGenerate(global);
|
||||||
@ -226,6 +229,7 @@ MjIpc();
|
|||||||
MainIpc(createWindow);
|
MainIpc(createWindow);
|
||||||
OriginalImageGenerateIpc();
|
OriginalImageGenerateIpc();
|
||||||
GlobalIpc();
|
GlobalIpc();
|
||||||
|
ImageIpc();
|
||||||
|
|
||||||
|
|
||||||
ipcMain.handle('dark-mode:toggle', (event, value) => {
|
ipcMain.handle('dark-mode:toggle', (event, value) => {
|
||||||
@ -313,7 +317,31 @@ ipcMain.handle(DEFINE_STRING.ADD_DRAFT, async (event, value) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 获取当前版本
|
// 获取当前版本
|
||||||
ipcMain.handle(DEFINE_STRING.GET_VERSION, async (event) => version);
|
ipcMain.handle(DEFINE_STRING.GET_VERSION, async (event) => {
|
||||||
|
// 获取当前电脑的显卡信息
|
||||||
|
let da = await graphics();
|
||||||
|
for (let i = 0; i < da.controllers.length; i++) {
|
||||||
|
// 获取第一个英伟达或者是AMD的显卡信息
|
||||||
|
const element = da.controllers[i];
|
||||||
|
if (element.vendor.startsWith("NVIDIA")) {
|
||||||
|
global.gpu = element;
|
||||||
|
global.gpu.type = "NVIDIA";
|
||||||
|
break;
|
||||||
|
} else if (element.vendor.startsWith("AMD") || element.vendor.startsWith("Advanced")) {
|
||||||
|
global.gpu = element;
|
||||||
|
global.gpu.type = "AMD";
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
global.gpu = {
|
||||||
|
name: "OTHER"
|
||||||
|
};
|
||||||
|
global.gpu.type = "OTHER";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return version + " " + (global.gpu?.name ? global.gpu.name : "");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
// 监听保存SD配置
|
// 监听保存SD配置
|
||||||
ipcMain.handle(DEFINE_STRING.SAVE_SD_CONFIG, async (event, value) => await func.SaveSDConfig(value))
|
ipcMain.handle(DEFINE_STRING.SAVE_SD_CONFIG, async (event, value) => await func.SaveSDConfig(value))
|
||||||
|
|||||||
@ -19,6 +19,14 @@ export class AsyncQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async enqueue(task, taskId, batchId, subBatchId = 'default') {
|
async enqueue(task, taskId, batchId, subBatchId = 'default') {
|
||||||
|
|
||||||
|
if (batchId && batchId != DEFINE_STRING.QUEUE_BATCH.IMAGE_SAVE_TO_OTHER_FOLDER) {
|
||||||
|
// 判断当前的任务是否已经存在,存在则不添加
|
||||||
|
let index = this.tasks.findIndex(item => item.taskId === taskId && item.batchId === batchId && item.subBatchId === subBatchId);
|
||||||
|
if (index != -1) {
|
||||||
|
throw new Error(`Task ${taskId} in batch ${batchId} already exists.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!this.batchCompletion[batchId]) {
|
if (!this.batchCompletion[batchId]) {
|
||||||
this.batchCompletion[batchId] = { remaining: 0, subBatches: {}, callback: null, failedTasks: [] };
|
this.batchCompletion[batchId] = { remaining: 0, subBatches: {}, callback: null, failedTasks: [] };
|
||||||
}
|
}
|
||||||
@ -50,7 +58,7 @@ export class AsyncQueue {
|
|||||||
this.taskDeadline = deadline;
|
this.taskDeadline = deadline;
|
||||||
}
|
}
|
||||||
|
|
||||||
async process() {
|
async process(task_count = 0) {
|
||||||
|
|
||||||
// 判断是不是有机器码检测的标识
|
// 判断是不是有机器码检测的标识
|
||||||
if (!this.global.CheckMachineId) {
|
if (!this.global.CheckMachineId) {
|
||||||
@ -68,7 +76,7 @@ export class AsyncQueue {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (this.tasks.length > 0 && this.currentConcurrency < this.concurrencyLimit) {
|
while (this.tasks.length > 0 && (this.manualMode ? this.taskProgress.length < task_count : this.currentConcurrency < this.concurrencyLimit)) {
|
||||||
const { task, taskId, batchId, subBatchId } = this.tasks.shift();
|
const { task, taskId, batchId, subBatchId } = this.tasks.shift();
|
||||||
this.currentConcurrency++;
|
this.currentConcurrency++;
|
||||||
task().then(() => {
|
task().then(() => {
|
||||||
@ -244,14 +252,14 @@ export class AsyncQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 手动开启下一个任务
|
// 手动开启下一个任务
|
||||||
async startNextTask() {
|
async startNextTask(taskCount = 3) {
|
||||||
// 判断当前是不是有任务正在执行
|
// 判断当前是不是有任务正在执行
|
||||||
if (this.currentCreateItem) {
|
if (this.currentCreateItem) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log("调用开始下一个任务", this.taskProgress)
|
console.log("调用开始下一个任务", this.taskProgress)
|
||||||
if (this.manualMode && this.tasks.length > 0 && this.currentConcurrency < this.concurrencyLimit && this.taskProgress.length < 3) {
|
if (this.manualMode && this.tasks.length > 0 && this.taskProgress.length < taskCount) {
|
||||||
this.process();
|
this.process(taskCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ const { spawn, exec } = require('child_process');
|
|||||||
const execAsync = util.promisify(exec);
|
const execAsync = util.promisify(exec);
|
||||||
import { define } from "../define/define";
|
import { define } from "../define/define";
|
||||||
import { get, has, set } from "lodash";
|
import { get, has, set } from "lodash";
|
||||||
import axios from "axios";
|
import { basicApi } from "../api/apiBasic";
|
||||||
|
|
||||||
export class Tools {
|
export class Tools {
|
||||||
constructor() { }
|
constructor() { }
|
||||||
@ -311,31 +311,12 @@ export class Tools {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async downloadFileUrl(url, filePath) {
|
async downloadFileUrl(url, filePath) {
|
||||||
return new Promise((resolve, reject) => {
|
try {
|
||||||
const request = net.request({
|
let data = await basicApi.downloadFileByURL(url);
|
||||||
method: 'GET',
|
await fspromises.writeFile(filePath, data.data);
|
||||||
url: url
|
} catch (error) {
|
||||||
});
|
throw error;
|
||||||
request.on('response', (response) => {
|
}
|
||||||
const chunks = [];
|
|
||||||
response.on('data', (chunk) => chunks.push(chunk));
|
|
||||||
response.on('end', async () => {
|
|
||||||
try {
|
|
||||||
await fspromises.writeFile(filePath, Buffer.concat(chunks));
|
|
||||||
console.log('File downloaded successfully');
|
|
||||||
resolve();
|
|
||||||
} catch (err) {
|
|
||||||
reject(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
request.on('error', (error) => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
request.end();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
11
src/preload/img.js
Normal file
11
src/preload/img.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { ipcRenderer } from "electron"
|
||||||
|
import { DEFINE_STRING } from "../define/define_string"
|
||||||
|
|
||||||
|
|
||||||
|
const img = {
|
||||||
|
// 加载当前链接的SD服务数据
|
||||||
|
OneSplitFour: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.IMG.ONE_SPLIT_FOUR, value)),
|
||||||
|
}
|
||||||
|
export {
|
||||||
|
img
|
||||||
|
}
|
||||||
@ -4,6 +4,7 @@ import { DEFINE_STRING } from '../define/define_string.js';
|
|||||||
import { discord } from './discord.js';
|
import { discord } from './discord.js';
|
||||||
import { mj } from './mj.js';
|
import { mj } from './mj.js';
|
||||||
import { sd } from './sd.js';
|
import { sd } from './sd.js';
|
||||||
|
import { img } from './img.js';
|
||||||
// Custom APIs for renderer
|
// Custom APIs for renderer
|
||||||
|
|
||||||
let events = [];
|
let events = [];
|
||||||
@ -411,6 +412,7 @@ if (process.contextIsolated) {
|
|||||||
contextBridge.exposeInMainWorld('mj', mj)
|
contextBridge.exposeInMainWorld('mj', mj)
|
||||||
contextBridge.exposeInMainWorld('discord', discord)
|
contextBridge.exposeInMainWorld('discord', discord)
|
||||||
contextBridge.exposeInMainWorld("sd", sd)
|
contextBridge.exposeInMainWorld("sd", sd)
|
||||||
|
contextBridge.exposeInMainWorld("img", img)
|
||||||
contextBridge.exposeInMainWorld('darkMode', {
|
contextBridge.exposeInMainWorld('darkMode', {
|
||||||
toggle: (value) => ipcRenderer.invoke('dark-mode:toggle', value),
|
toggle: (value) => ipcRenderer.invoke('dark-mode:toggle', value),
|
||||||
})
|
})
|
||||||
@ -423,5 +425,6 @@ if (process.contextIsolated) {
|
|||||||
window.mj = mj;
|
window.mj = mj;
|
||||||
window.discord = discord;
|
window.discord = discord;
|
||||||
window.sd = sd;
|
window.sd = sd;
|
||||||
|
window.img = img;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ const mj = {
|
|||||||
SvaeMJWordSrt: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.SAVE_WORD_SRT, value)),
|
SvaeMJWordSrt: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.SAVE_WORD_SRT, value)),
|
||||||
// 获取MJ配置文件的字幕信息
|
// 获取MJ配置文件的字幕信息
|
||||||
GetMJConfigSrtInformation: async (callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_MJ_CONFIG_SRT_INFORMATION)),
|
GetMJConfigSrtInformation: async (callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_MJ_CONFIG_SRT_INFORMATION)),
|
||||||
|
|
||||||
// 获取标签集的基础信息
|
// 获取标签集的基础信息
|
||||||
GetTagDataByTypeAndProperty: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_TAG_DATA_BY_TYPE_AND_PROPERTY, value)),
|
GetTagDataByTypeAndProperty: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_TAG_DATA_BY_TYPE_AND_PROPERTY, value)),
|
||||||
// 保存数据到标签集中
|
// 保存数据到标签集中
|
||||||
@ -14,10 +15,12 @@ const mj = {
|
|||||||
DeleteTagPropertyData: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.DELETE_TAG_PROPERTY_DATA, value)),
|
DeleteTagPropertyData: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.DELETE_TAG_PROPERTY_DATA, value)),
|
||||||
// 获取选择标签的模式option列表
|
// 获取选择标签的模式option列表
|
||||||
GetTagSelectModel: async (callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_TAG_SELECT_MODEL)),
|
GetTagSelectModel: async (callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_TAG_SELECT_MODEL)),
|
||||||
|
|
||||||
// 将翻译任务添加到后台队列中
|
// 将翻译任务添加到后台队列中
|
||||||
TranslateReturnNowTask: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.TRANSLATE_RETURN_NOW_TASK, value)),
|
TranslateReturnNowTask: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.TRANSLATE_RETURN_NOW_TASK, value)),
|
||||||
// MJ原创生图
|
// MJ原创生图
|
||||||
OriginalMJImageGenerate: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.ORIGINAL_MJ_IMAGE_GENERATE, value)),
|
OriginalMJImageGenerate: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.ORIGINAL_MJ_IMAGE_GENERATE, value)),
|
||||||
|
|
||||||
// 获取当前对话频道的机器人列表
|
// 获取当前对话频道的机器人列表
|
||||||
GetChannelRobots: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_CHANNEL_ROBOTS, value)),
|
GetChannelRobots: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_CHANNEL_ROBOTS, value)),
|
||||||
|
|
||||||
@ -29,6 +32,7 @@ const mj = {
|
|||||||
|
|
||||||
// 添加MJ敏感词
|
// 添加MJ敏感词
|
||||||
AddMjBadPrompt: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.ADD_MJ_BAD_PROMPT, value)),
|
AddMjBadPrompt: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.ADD_MJ_BAD_PROMPT, value)),
|
||||||
|
|
||||||
// 添加MJ敏感词检查
|
// 添加MJ敏感词检查
|
||||||
MJBadPromptCheck: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.MJ_BAD_PROMPT_CHECK, value)),
|
MJBadPromptCheck: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.MJ_BAD_PROMPT_CHECK, value)),
|
||||||
|
|
||||||
@ -37,6 +41,12 @@ const mj = {
|
|||||||
|
|
||||||
// 给图片链接,下载指定的图片并分割保存
|
// 给图片链接,下载指定的图片并分割保存
|
||||||
DownloadImageUrlAndSplit: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.DOWNLOAD_IMAGE_URL_AND_SPLIT, value)),
|
DownloadImageUrlAndSplit: async (value, callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.DOWNLOAD_IMAGE_URL_AND_SPLIT, value)),
|
||||||
|
|
||||||
|
// 获取图片的所有的分割尺寸
|
||||||
|
GetMJImageScale: async (callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_MJ_IMAGE_SCALE)),
|
||||||
|
|
||||||
|
// 获取所有的MJ生图模型
|
||||||
|
GetMJImageRobotModel: async (callback) => callback(await ipcRenderer.invoke(DEFINE_STRING.MJ.GET_MJ_IMAGE_ROBOT_MODEL)),
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|||||||
@ -47,8 +47,8 @@
|
|||||||
<n-card style=" margin-top: 10px;" title="手动保存">
|
<n-card style=" margin-top: 10px;" title="手动保存">
|
||||||
<div class="first_row" style="display: flex; margin-top: 15px">
|
<div class="first_row" style="display: flex; margin-top: 15px">
|
||||||
<div style="margin-left: 10px; ">
|
<div style="margin-left: 10px; ">
|
||||||
<div style="margin-bottom: 3px;">选择保存到的文件夹</div>
|
<div style="margin-bottom: 3px;">选择手动保存的文件夹</div>
|
||||||
<n-input placeholder="选择保存到的文件夹" v-model:value="save_setting.save_folder"
|
<n-input placeholder="选择手动保存的文件夹" v-model:value="save_setting.save_folder"
|
||||||
style="width: 200px; margin-right: 10px;"></n-input>
|
style="width: 200px; margin-right: 10px;"></n-input>
|
||||||
<n-button type="info" @click="SelectOutFolder">选择文件夹</n-button>
|
<n-button type="info" @click="SelectOutFolder">选择文件夹</n-button>
|
||||||
</div>
|
</div>
|
||||||
@ -169,7 +169,7 @@ export default defineComponent({
|
|||||||
async function SaveImage() {
|
async function SaveImage() {
|
||||||
debugger
|
debugger
|
||||||
if (isEmpty(save_setting.value.save_folder)) {
|
if (isEmpty(save_setting.value.save_folder)) {
|
||||||
message.error("请选择保存到的文件夹")
|
message.error("请选择手动保存的文件夹")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (save_setting.value.save_match_count == 0) {
|
if (save_setting.value.save_match_count == 0) {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,83 +1,109 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="height: 200px;">
|
<div style="height: 200px">
|
||||||
<div style="height: 40px;"></div>
|
<div style="height: 40px"></div>
|
||||||
<div style="display: flex;">
|
<div style="display: flex">
|
||||||
<n-input :disabled="true" v-model:value="machineId" type="text" placeholder="唯一码" />
|
<n-input :disabled="true" v-model:value="machineId" type="text" placeholder="唯一码" />
|
||||||
<n-popover trigger="click">
|
<n-popover trigger="click">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<n-button text style="width: 24px; font-size: 24px; color: skyblue; display: flex; heigh">
|
<n-button text style="width: 24px; font-size: 24px; color: skyblue; display: flex; heigh">
|
||||||
<n-icon>
|
<n-icon>
|
||||||
<InformationCircle />
|
<InformationCircle />
|
||||||
</n-icon>
|
</n-icon>
|
||||||
</n-button>
|
</n-button>
|
||||||
</template>
|
</template>
|
||||||
<span>VX:xiangbie88</span>
|
<span>VX:xiangbie88</span>
|
||||||
</n-popover>
|
</n-popover>
|
||||||
</div>
|
|
||||||
<div style="color: red; margin: 10px">如未激活,将上面的码给管理员激活
|
|
||||||
<n-popover trigger="hover" raw :show-arrow="false">
|
|
||||||
<template #trigger>
|
|
||||||
<n-tag type="info">
|
|
||||||
客服微信
|
|
||||||
</n-tag>
|
|
||||||
</template>
|
|
||||||
<n-image width="250" src="http://qiniuyun.upsurging.xyz/LAI/a41237ef53a18b6c7fba5d966e9a28f.jpg"
|
|
||||||
preview-disabled />
|
|
||||||
</n-popover>
|
|
||||||
</div>
|
|
||||||
<div style="margin: 10px;">详细的教程文档:<span class="url_class" @click="OpenTeachDoc">教程文档</span></div>
|
|
||||||
<div style="margin: 10px;">问题/需求收集表:<span class="url_class" @click="OpenQueDoc">问题/需求收集表</span></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div style="color: red; margin: 10px">
|
||||||
|
如未激活,将上面的码给管理员激活
|
||||||
|
<n-popover trigger="hover" raw :show-arrow="false">
|
||||||
|
<template #trigger>
|
||||||
|
<n-tag type="info"> 客服微信 </n-tag>
|
||||||
|
</template>
|
||||||
|
<n-image
|
||||||
|
width="250"
|
||||||
|
src="http://qiniuyun.upsurging.xyz/LAI/a41237ef53a18b6c7fba5d966e9a28f.jpg"
|
||||||
|
preview-disabled
|
||||||
|
/>
|
||||||
|
</n-popover>
|
||||||
|
</div>
|
||||||
|
<div style="margin: 10px; font-size: large; color: red">
|
||||||
|
教程视频:<span class="url_class" @click="OpenTeach('video')">向北-LAITool</span>
|
||||||
|
</div>
|
||||||
|
<div style="margin: 10px">
|
||||||
|
详细的教程文档:<span class="url_class" @click="OpenTeach('doc')">教程文档</span>
|
||||||
|
</div>
|
||||||
|
<div style="margin: 10px">
|
||||||
|
问题/需求收集表:<span class="url_class" @click="OpenQueDoc">问题/需求收集表</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent, ref, h, onMounted, toRaw } from "vue";
|
import { defineComponent, ref, h, onMounted, toRaw } from 'vue'
|
||||||
import { useMessage, NInput, NButton, NIcon, NPopover, NImage, NTag } from "naive-ui"
|
import { useMessage, NInput, NButton, NIcon, NPopover, NImage, NTag } from 'naive-ui'
|
||||||
import { InformationCircle } from '@vicons/ionicons5'
|
import { InformationCircle } from '@vicons/ionicons5'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
NInput, NButton, NIcon, InformationCircle, NPopover, NImage, NTag
|
NInput,
|
||||||
},
|
NButton,
|
||||||
setup() {
|
NIcon,
|
||||||
let machineId = ref("");
|
InformationCircle,
|
||||||
let message = useMessage();
|
NPopover,
|
||||||
|
NImage,
|
||||||
|
NTag
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
let machineId = ref('')
|
||||||
|
let message = useMessage()
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 获取机械码
|
// 获取机械码
|
||||||
await window.api.GetMachineId((value) => {
|
await window.api.GetMachineId((value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message);
|
message.error(value.message)
|
||||||
return;
|
return
|
||||||
}
|
|
||||||
machineId.value = value.value;
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
function OpenTeachDoc() {
|
|
||||||
window.api.OpenUrl("https://rvgyir5wk1c.feishu.cn/docx/RZYCdG7ZpoKsIzxBEzccNEIFn8f?from=from_copylink");
|
|
||||||
}
|
|
||||||
|
|
||||||
function OpenQueDoc() {
|
|
||||||
window.api.OpenUrl("https://pvwu1oahp5m.feishu.cn/sheets/G5s3sX0KahH1XQtWDazcF70anUb?from=from_copylink");
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
machineId,
|
|
||||||
OpenQueDoc,
|
|
||||||
OpenTeachDoc
|
|
||||||
}
|
}
|
||||||
|
machineId.value = value.value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
function OpenTeach(type) {
|
||||||
|
switch (type) {
|
||||||
|
case 'doc':
|
||||||
|
window.api.OpenUrl(
|
||||||
|
'https://rvgyir5wk1c.feishu.cn/docx/RZYCdG7ZpoKsIzxBEzccNEIFn8f?from=from_copylink'
|
||||||
|
)
|
||||||
|
break
|
||||||
|
case 'video':
|
||||||
|
window.api.OpenUrl('https://space.bilibili.com/110586931')
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function OpenQueDoc() {
|
||||||
|
window.api.OpenUrl(
|
||||||
|
'https://pvwu1oahp5m.feishu.cn/sheets/G5s3sX0KahH1XQtWDazcF70anUb?from=from_copylink'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
machineId,
|
||||||
|
OpenQueDoc,
|
||||||
|
OpenTeach
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.url_class {
|
.url_class {
|
||||||
color: blue;
|
color: #e18a3b;
|
||||||
}
|
}
|
||||||
|
|
||||||
.url_class:hover {
|
.url_class:hover {
|
||||||
color: brown;
|
color: brown;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -232,6 +232,7 @@ export default defineComponent({
|
|||||||
window.api.setEventListen(
|
window.api.setEventListen(
|
||||||
[DEFINE_STRING.REGENERATE_IMAGE_RETUN, window.id],
|
[DEFINE_STRING.REGENERATE_IMAGE_RETUN, window.id],
|
||||||
(value) => {
|
(value) => {
|
||||||
|
debugger
|
||||||
if (value.type != 1) {
|
if (value.type != 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -17,9 +17,39 @@
|
|||||||
@click="MJGetImage"
|
@click="MJGetImage"
|
||||||
>MJ采集图片</n-button
|
>MJ采集图片</n-button
|
||||||
>
|
>
|
||||||
|
<n-button
|
||||||
|
v-if="select_image_category == 'mj'"
|
||||||
|
color="#e18a3b"
|
||||||
|
size="tiny"
|
||||||
|
style="margin-left: 5px"
|
||||||
|
@click="OneSplitFour"
|
||||||
|
>1拆4</n-button
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="type == 'data'">
|
<div v-else-if="type == 'data'">
|
||||||
<div style="height: 22px">进度:{{ data.mj_message?.progress }}%</div>
|
<div style="height: 22px; display: flex" v-if="select_image_category == 'mj'">
|
||||||
|
<div>进度:{{ data.mj_message?.progress }}%</div>
|
||||||
|
<n-tag
|
||||||
|
v-if="data.mj_message?.status != 'error'"
|
||||||
|
type="success"
|
||||||
|
style="height: 18px; margin: 2px 0 2px 5px"
|
||||||
|
>{{
|
||||||
|
data.mj_message?.status != null && data.mj_message?.status != ''
|
||||||
|
? data.mj_message?.status
|
||||||
|
: 'wait'
|
||||||
|
}}</n-tag
|
||||||
|
>
|
||||||
|
<div v-else style="margin-left: 5px">
|
||||||
|
<n-popover style="padding: 0; margin: 0" trigger="hover">
|
||||||
|
<template #trigger>
|
||||||
|
<n-tag style="height: 18px; margin: 2px 0 2px 0" type="error">error</n-tag>
|
||||||
|
</template>
|
||||||
|
<span>{{ data.mj_message?.message }}</span>
|
||||||
|
</n-popover>
|
||||||
|
</div>
|
||||||
|
<div style="margin-left: 5px">{{ data.mj_message?.message_id }}</div>
|
||||||
|
</div>
|
||||||
|
<div></div>
|
||||||
<div
|
<div
|
||||||
style="display: flex; margin-right: 10px; height: auto; min-height: 120px"
|
style="display: flex; margin-right: 10px; height: auto; min-height: 120px"
|
||||||
@dragstart="imageDragStart"
|
@dragstart="imageDragStart"
|
||||||
@ -64,7 +94,16 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, h, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
import { ref, h, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||||
import { NImage, useMessage, NDivider, NImageGroup, NButton, NSelect } from 'naive-ui'
|
import {
|
||||||
|
NImage,
|
||||||
|
useMessage,
|
||||||
|
NDivider,
|
||||||
|
NImageGroup,
|
||||||
|
NButton,
|
||||||
|
NSelect,
|
||||||
|
NPopover,
|
||||||
|
NTag
|
||||||
|
} from 'naive-ui'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
@ -72,7 +111,9 @@ export default defineComponent({
|
|||||||
NDivider,
|
NDivider,
|
||||||
NImageGroup,
|
NImageGroup,
|
||||||
NButton,
|
NButton,
|
||||||
NSelect
|
NSelect,
|
||||||
|
NPopover,
|
||||||
|
NTag
|
||||||
},
|
},
|
||||||
props: ['initData', 'type', 'image_generate_category', 'func'],
|
props: ['initData', 'type', 'image_generate_category', 'func'],
|
||||||
setup(props) {
|
setup(props) {
|
||||||
@ -234,6 +275,13 @@ export default defineComponent({
|
|||||||
props.func.mJGetImage()
|
props.func.mJGetImage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1拆4
|
||||||
|
*/
|
||||||
|
async function OneSplitFour() {
|
||||||
|
await props.func.oneSplitFour()
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data,
|
data,
|
||||||
type,
|
type,
|
||||||
@ -247,7 +295,8 @@ export default defineComponent({
|
|||||||
imageDragOver,
|
imageDragOver,
|
||||||
select_image_category,
|
select_image_category,
|
||||||
UpdateImageGenerateCategory,
|
UpdateImageGenerateCategory,
|
||||||
MJGetImage
|
MJGetImage,
|
||||||
|
OneSplitFour
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -80,8 +80,56 @@
|
|||||||
<n-card title="MJ设置" hoverable style="margin-top: 5px">
|
<n-card title="MJ设置" hoverable style="margin-top: 5px">
|
||||||
<div class="first_row" style="display: flex">
|
<div class="first_row" style="display: flex">
|
||||||
<div>
|
<div>
|
||||||
<!-- <div style="margin-bottom: 3px;">铭感词相关</div> -->
|
<div style="margin-bottom: 3px">出图模式</div>
|
||||||
<n-button size="small" @click="AddMjBadPrompt" color="#7c461e">添加敏感词</n-button>
|
<n-select
|
||||||
|
size="small"
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="request_model_options"
|
||||||
|
v-model:value="mjSetting.request_model"
|
||||||
|
style="width: 120px"
|
||||||
|
>
|
||||||
|
</n-select>
|
||||||
|
</div>
|
||||||
|
<div style="margin-left: 10px; display: flex; flex-wrap: wrap; width: 80px">
|
||||||
|
<div style="margin-bottom: 3px">出图机器人</div>
|
||||||
|
<n-select
|
||||||
|
size="small"
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="select_robot_options"
|
||||||
|
v-model:value="mjSetting.select_robot"
|
||||||
|
style="width: 80px"
|
||||||
|
>
|
||||||
|
</n-select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-left: 10px; display: flex; flex-wrap: wrap; width: 100px">
|
||||||
|
<div style="margin-bottom: 3px">出图速度模式</div>
|
||||||
|
<n-select
|
||||||
|
size="small"
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="mj_speed_options"
|
||||||
|
v-model:value="mjSetting.mj_speed"
|
||||||
|
style="width: 100px"
|
||||||
|
>
|
||||||
|
</n-select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-left: 10px; display: flex; flex-wrap: wrap; width: 80px">
|
||||||
|
<div style="margin-bottom: 3px">MJ并发数量</div>
|
||||||
|
<n-input-number
|
||||||
|
size="small"
|
||||||
|
style="width: 80px"
|
||||||
|
v-model:value="mjSetting.task_count"
|
||||||
|
:show-button="false"
|
||||||
|
:min="1"
|
||||||
|
:max="10"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-left: 10px; display: flex; flex-wrap: wrap; width: 130px">
|
||||||
|
<n-button style="margin-top: 25px" size="small" @click="AddMjBadPrompt" color="#7c461e"
|
||||||
|
>添加敏感词</n-button
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</n-card>
|
</n-card>
|
||||||
@ -149,6 +197,15 @@ export default defineComponent({
|
|||||||
|
|
||||||
let character_select_model = ref(window.config.character_select_model)
|
let character_select_model = ref(window.config.character_select_model)
|
||||||
let character_select_model_options = ref([])
|
let character_select_model_options = ref([])
|
||||||
|
let mjSetting = ref({
|
||||||
|
select_robot: null,
|
||||||
|
task_count: 1,
|
||||||
|
request_model: null,
|
||||||
|
mj_speed: 'relaxed'
|
||||||
|
})
|
||||||
|
let request_model_options = ref([])
|
||||||
|
let select_robot_options = ref([])
|
||||||
|
let mj_speed_options = ref([])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化GPT的option
|
* 初始化GPT的option
|
||||||
@ -187,6 +244,60 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化MJ的option
|
||||||
|
*/
|
||||||
|
async function InitMjOptions() {
|
||||||
|
// 获取当前mj配置信息
|
||||||
|
await window.api.GetDefineConfigJsonByProperty(
|
||||||
|
JSON.stringify(['img_base', 'mj_config', false, null]),
|
||||||
|
(value) => {
|
||||||
|
debugger
|
||||||
|
console.log(value)
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 判断是不是有数据
|
||||||
|
if (value.data) {
|
||||||
|
mjSetting.value = value.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
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.request_model == null) {
|
||||||
|
mjSetting.value.request_model = request_model_options.value[0].value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
select_robot_options.value = [
|
||||||
|
{
|
||||||
|
label: 'MJ',
|
||||||
|
value: 'mj'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'NIJI',
|
||||||
|
value: 'niji'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
mj_speed_options.value = [
|
||||||
|
{
|
||||||
|
label: 'RELAXED',
|
||||||
|
value: 'relaxed'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'FAST',
|
||||||
|
value: 'fast'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 加载全局配置
|
// 加载全局配置
|
||||||
// 获取SD配置
|
// 获取SD配置
|
||||||
@ -200,8 +311,10 @@ export default defineComponent({
|
|||||||
sd_image_width.value = value.data.width
|
sd_image_width.value = value.data.width
|
||||||
sd_image_height.value = value.data.height
|
sd_image_height.value = value.data.height
|
||||||
})
|
})
|
||||||
|
|
||||||
await InitGptOptions()
|
await InitGptOptions()
|
||||||
|
|
||||||
|
// 获取MJ相关配置
|
||||||
|
await InitMjOptions()
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -236,6 +349,18 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 保存MJ配置
|
||||||
|
|
||||||
|
await window.api.SaveDefineConfigJsonByProperty(
|
||||||
|
JSON.stringify(['img_base', 'mj_config', toRaw(mjSetting.value), false]),
|
||||||
|
(value) => {
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
message.success('保存成功')
|
message.success('保存成功')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
debugger
|
debugger
|
||||||
@ -300,7 +425,11 @@ export default defineComponent({
|
|||||||
character_select_model_options,
|
character_select_model_options,
|
||||||
character_select_model,
|
character_select_model,
|
||||||
AddMjBadPrompt,
|
AddMjBadPrompt,
|
||||||
bad_prompt_ref
|
bad_prompt_ref,
|
||||||
|
mjSetting,
|
||||||
|
request_model_options,
|
||||||
|
select_robot_options,
|
||||||
|
mj_speed_options
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -115,7 +115,6 @@ export default defineComponent({
|
|||||||
watch(
|
watch(
|
||||||
() => props.tags,
|
() => props.tags,
|
||||||
async (newVal) => {
|
async (newVal) => {
|
||||||
debugger
|
|
||||||
tags.value = newVal
|
tags.value = newVal
|
||||||
// 同步修改 selectStyle.value 的值
|
// 同步修改 selectStyle.value 的值
|
||||||
for (let i = 0; i < selectStyle.value.length; i++) {
|
for (let i = 0; i < selectStyle.value.length; i++) {
|
||||||
@ -126,7 +125,8 @@ export default defineComponent({
|
|||||||
selectStyle.value[i] = tags.value.style_tags[index]
|
selectStyle.value[i] = tags.value.style_tags[index]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -315,7 +315,8 @@ export default defineComponent({
|
|||||||
type: 'title',
|
type: 'title',
|
||||||
image_generate_category: image_generate_category,
|
image_generate_category: image_generate_category,
|
||||||
func: {
|
func: {
|
||||||
mJGetImage: MJGetImage
|
mJGetImage: MJGetImage,
|
||||||
|
oneSplitFour: OneSplitFour
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -324,6 +325,7 @@ export default defineComponent({
|
|||||||
width: '300',
|
width: '300',
|
||||||
render(row, index) {
|
render(row, index) {
|
||||||
return h(DataTableShowGenerateImage, {
|
return h(DataTableShowGenerateImage, {
|
||||||
|
image_generate_category: image_generate_category,
|
||||||
initData: row,
|
initData: row,
|
||||||
index: index,
|
index: index,
|
||||||
type: 'data'
|
type: 'data'
|
||||||
@ -335,7 +337,6 @@ export default defineComponent({
|
|||||||
let isSaved = false
|
let isSaved = false
|
||||||
// 监听control+s 保存数据
|
// 监听control+s 保存数据
|
||||||
let saveListener = function (event) {
|
let saveListener = function (event) {
|
||||||
debugger
|
|
||||||
if (event.ctrlKey && event.key === 's') {
|
if (event.ctrlKey && event.key === 's') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
if (!isSaved) {
|
if (!isSaved) {
|
||||||
@ -366,7 +367,7 @@ export default defineComponent({
|
|||||||
selectStyle.value = value.data
|
selectStyle.value = value.data
|
||||||
})
|
})
|
||||||
|
|
||||||
for (let i = 0; i < customize_image_style_list && customize_image_style_list.length; i++) {
|
for (let i = 0; customize_image_style_list && i < customize_image_style_list.length; i++) {
|
||||||
const element = customize_image_style_list[i]
|
const element = customize_image_style_list[i]
|
||||||
selectStyle.value.push({
|
selectStyle.value.push({
|
||||||
key: element,
|
key: element,
|
||||||
@ -431,19 +432,25 @@ export default defineComponent({
|
|||||||
mainDiscordMessageChanged(value)
|
mainDiscordMessageChanged(value)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
await props.InitTags()
|
await props.InitTags()
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(async () => {
|
onBeforeUnmount(async () => {
|
||||||
debugger
|
|
||||||
await AutoSaveDataJson()
|
await AutoSaveDataJson()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 接收Discord的修改信息
|
// 接收Discord的修改信息
|
||||||
async function mainDiscordMessageChanged(value) {
|
async function mainDiscordMessageChanged(value) {
|
||||||
|
console.log(value)
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error('Discord返回错误,错误信息如下:' + value.message)
|
message.error('Discord返回错误,错误信息如下:' + value.message)
|
||||||
|
// 判断当前的数据是不是有ID
|
||||||
|
if (value.id) {
|
||||||
|
let index = data.value.findIndex((item) => item.id == value.id)
|
||||||
|
data.value[index]['mj_message']['status'] = 'error'
|
||||||
|
data.value[index]['mj_message']['message'] = value.message
|
||||||
|
}
|
||||||
|
AutoSaveDataJsonDebounced()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,6 +468,7 @@ export default defineComponent({
|
|||||||
delete value.type
|
delete value.type
|
||||||
delete value.code
|
delete value.code
|
||||||
data.value[index]['mj_message'] = value
|
data.value[index]['mj_message'] = value
|
||||||
|
AutoSaveDataJsonDebounced()
|
||||||
} else if (value.type == 'updated') {
|
} else if (value.type == 'updated') {
|
||||||
console.log('接收Discord的更新消息', value)
|
console.log('接收Discord的更新消息', value)
|
||||||
// 修改对应的数据
|
// 修改对应的数据
|
||||||
@ -475,15 +483,18 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
delete value.type
|
delete value.type
|
||||||
delete value.code
|
delete value.code
|
||||||
|
|
||||||
data.value[index]['mj_message'] = value
|
data.value[index]['mj_message'] = value
|
||||||
} else if (value.type == 'delete') {
|
} else if (value.type == 'delete') {
|
||||||
console.log('接收Discord的删除消息', value)
|
console.log('接收Discord的删除消息', value)
|
||||||
} else if (value.type == 'finished') {
|
} else if (value.type == 'finished') {
|
||||||
console.log('接收Discord的完成消息', value)
|
console.log('接收Discord的完成消息', value)
|
||||||
// 修改对应的数据
|
let index
|
||||||
let index = data.value.findIndex((item) => item.mj_message?.image_id == value.image_id)
|
if (value.category == 'api_mj') {
|
||||||
if (index < 0) {
|
index = data.value.findIndex((item) => item.id == value.id)
|
||||||
|
} else if (value.category == 'browser_mj') {
|
||||||
|
index = data.value.findIndex((item) => item.mj_message?.image_id == value.image_id)
|
||||||
|
}
|
||||||
|
if (index == null || index < 0) {
|
||||||
message.error('未找到对应的数据')
|
message.error('未找到对应的数据')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -494,20 +505,32 @@ export default defineComponent({
|
|||||||
delete value.code
|
delete value.code
|
||||||
value.progress = 100
|
value.progress = 100
|
||||||
value.message_id = value.message_id
|
value.message_id = value.message_id
|
||||||
|
value.message = null
|
||||||
|
|
||||||
data.value[index]['mj_message'] = value
|
data.value[index]['mj_message'] = value
|
||||||
|
AutoSaveDataJsonDebounced()
|
||||||
|
|
||||||
// 返回后端分割图片(传入图片地址,返回分割后的图片地址数组)
|
// 返回后端分割图片(传入图片地址,返回分割后的图片地址数组)
|
||||||
await window.mj.ImageSplit(
|
await window.mj.ImageSplit(
|
||||||
JSON.stringify([value.image_path, data.value[index].name]),
|
JSON.stringify([
|
||||||
|
value.image_path,
|
||||||
|
data.value[index].name == null ? '' : data.value[index].name
|
||||||
|
]),
|
||||||
(value) => {
|
(value) => {
|
||||||
if (value.code == 0) {
|
if (value.code == 0) {
|
||||||
message.error(value.message)
|
message.error(value.message)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 修改数据
|
// 修改数据
|
||||||
data.value[index]['outImagePath'] = value.data.outImagePath
|
data.value[index]['outImagePath'] =
|
||||||
data.value[index]['subImagePath'] = value.data.subImagePath
|
'file://' +
|
||||||
|
value.data.outImagePath.replaceAll('\\', '/') +
|
||||||
|
'?time=' +
|
||||||
|
new Date().getTime()
|
||||||
|
data.value[index]['subImagePath'] = value.data.subImagePath.map(
|
||||||
|
(item) => 'file://' + item.replaceAll('\\', '/') + '?time=' + new Date().getTime()
|
||||||
|
)
|
||||||
|
AutoSaveDataJsonDebounced()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@ -1018,23 +1041,22 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* 采集图片
|
||||||
*/
|
*/
|
||||||
async function MJGetImage() {
|
async function MJGetImage() {
|
||||||
|
// 判断是什么方式获取图片
|
||||||
|
// 判断当前是不是有MJ_message,并且状态不为error,并且有message_id
|
||||||
let pa = []
|
let pa = []
|
||||||
// MJ采集图片
|
|
||||||
for (let i = 0; i < data.value.length; i++) {
|
for (let i = 0; i < data.value.length; i++) {
|
||||||
const item = data.value[i]
|
const item = data.value[i]
|
||||||
// 一般进度大于 50 会出现图片,
|
|
||||||
if (!item.mj_message) {
|
if (!item.mj_message) {
|
||||||
return
|
continue
|
||||||
}
|
}
|
||||||
if (item.mj_message.progress && item.mj_message.progress == 100) {
|
if (item.mj_message.status && item.mj_message.status == 'error') {
|
||||||
// 判断 image_path 是不是存在。
|
continue
|
||||||
if (item.mj_message.image_id && !item.mj_message.image_path) {
|
}
|
||||||
// 通过当前的image_id获取图片
|
if (item.mj_message.message_id && !isEmpty(item.mj_message.message_id)) {
|
||||||
pa.push(item)
|
pa.push(item)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1053,11 +1075,22 @@ export default defineComponent({
|
|||||||
message.error('未找到对应的数据')
|
message.error('未找到对应的数据')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data.value[index].outImagePath = element.outImagePath
|
|
||||||
data.value[index].subImagePath = element.subImagePath
|
data.value[index].outImagePath =
|
||||||
|
'file://' +
|
||||||
|
element.outImagePath.replaceAll('\\', '/') +
|
||||||
|
'?time=' +
|
||||||
|
new Date().getTime()
|
||||||
|
|
||||||
|
data.value[index].subImagePath = element.subImagePath.map(
|
||||||
|
(item) => 'file://' + item.replaceAll('\\', '/') + '?time=' + new Date().getTime()
|
||||||
|
)
|
||||||
data.value[index].mj_message.image_click = element.result
|
data.value[index].mj_message.image_click = element.result
|
||||||
data.value[index].mj_message.image_path = element.image_path
|
data.value[index].mj_message.image_path = element.image_path
|
||||||
|
data.value[index].mj_message.progress = 100
|
||||||
|
data.value[index].mj_message.status = 'success'
|
||||||
}
|
}
|
||||||
|
AutoSaveDataJsonDebounced()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
message.error('没有找到可以自动下载图片的数据,可以手动粘贴链接分割')
|
message.error('没有找到可以自动下载图片的数据,可以手动粘贴链接分割')
|
||||||
@ -1065,6 +1098,54 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一拆四
|
||||||
|
*/
|
||||||
|
async function OneSplitFour() {
|
||||||
|
debugger
|
||||||
|
// 判断当前的data中是不是都有图片
|
||||||
|
let min
|
||||||
|
let pra = []
|
||||||
|
for (let i = 0; i < data.value.length; i++) {
|
||||||
|
const element = data.value[i]
|
||||||
|
if (element.outImagePath == null || element.outImagePath == '') {
|
||||||
|
message.error('当前数据没有图片,无法进行一拆四')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (element.subImagePath == null || element.subImagePath.length == 0) {
|
||||||
|
message.error('当前数据没有图片,无法进行一拆四')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (min == null) {
|
||||||
|
min = element.subImagePath.length
|
||||||
|
}
|
||||||
|
if (element.subImagePath.length < min) {
|
||||||
|
min = element.subImagePath.length
|
||||||
|
}
|
||||||
|
pra.push({
|
||||||
|
id: element.id,
|
||||||
|
name: element.name,
|
||||||
|
outImagePath: element.outImagePath,
|
||||||
|
subImagePath: element.subImagePath
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断最小的min
|
||||||
|
if (min <= 1) {
|
||||||
|
message.error('当前最小图片小于等于1,无法进行一拆四')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将当前数据传到后端进行一拆四
|
||||||
|
await window.img.OneSplitFour(JSON.stringify([pra, min]), (value) => {
|
||||||
|
debugger
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error('一拆四失败,错误信息如下:' + value.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data,
|
data,
|
||||||
columns: createColumns({}),
|
columns: createColumns({}),
|
||||||
|
|||||||
@ -84,7 +84,7 @@ export default defineComponent({
|
|||||||
message.error(value.message)
|
message.error(value.message)
|
||||||
promptError = false
|
promptError = false
|
||||||
}
|
}
|
||||||
data.value[i].prompt = value.data.webui_config.prompt
|
data.value[i].prompt = value.data?.webui_config.prompt
|
||||||
data.value[i].chinese_prompt = value.data?.chinese_prompt
|
data.value[i].chinese_prompt = value.data?.chinese_prompt
|
||||||
// data.value[i].gpt_prompt = value.data?.gpt_prompt;
|
// data.value[i].gpt_prompt = value.data?.gpt_prompt;
|
||||||
data.value[i].adetailer = value.data?.adetailer
|
data.value[i].adetailer = value.data?.adetailer
|
||||||
|
|||||||
@ -217,8 +217,6 @@ export default defineComponent({
|
|||||||
* 生成所有的图片
|
* 生成所有的图片
|
||||||
*/
|
*/
|
||||||
async function GenerateImageAll() {
|
async function GenerateImageAll() {
|
||||||
debugger
|
|
||||||
console.log(data.value)
|
|
||||||
let tmpData = cloneDeep(toRaw(data.value))
|
let tmpData = cloneDeep(toRaw(data.value))
|
||||||
tmpData = tmpData.filter((item) => {
|
tmpData = tmpData.filter((item) => {
|
||||||
return item.outImagePath == null || item.outImagePath == ''
|
return item.outImagePath == null || item.outImagePath == ''
|
||||||
@ -230,7 +228,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 判断当前是mj还是sd
|
// 判断当前是mj还是sd
|
||||||
let ca = window.config.image_generate_category
|
let ca = window.config.image_generate_category ? window.config.image_generate_category : 'sd'
|
||||||
if (ca == 'sd') {
|
if (ca == 'sd') {
|
||||||
// 将所有的人物添加到后台队列任务中
|
// 将所有的人物添加到后台队列任务中
|
||||||
await window.api.OriginalSDImageGenerate([JSON.stringify(tmpData), true, true], (value) => {
|
await window.api.OriginalSDImageGenerate([JSON.stringify(tmpData), true, true], (value) => {
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
<n-input v-model:value="gpt_select_value.label"></n-input>
|
<n-input v-model:value="gpt_select_value.label"></n-input>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item path="value" label="GPT请求网址(写全)">
|
<n-form-item path="value" label="GPT请求网址(写全)">
|
||||||
<n-input v-model:value="gpt_select_value.value"></n-input>
|
<n-input v-model:value="gpt_select_value.gpt_url"></n-input>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<div style="text-align: right;">
|
<div style="text-align: right;">
|
||||||
<n-button type="primary" @click="SaveGptOption">保存</n-button>
|
<n-button type="primary" @click="SaveGptOption">保存</n-button>
|
||||||
@ -234,7 +234,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
let rules = {
|
let rules = {
|
||||||
label: ruleObj("必填GPT名称"),
|
label: ruleObj("必填GPT名称"),
|
||||||
value: ruleObj("必填GPT请求网址"),
|
gpt_url: ruleObj("必填GPT请求网址"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let modelRules = {
|
let modelRules = {
|
||||||
|
|||||||
@ -1,346 +1,556 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-button type="info" round @click="OpenDiscordWindow">打开登录MJ</n-button>
|
<n-button type="info" round @click="OpenDiscordWindow">打开登录MJ</n-button>
|
||||||
<n-button type="info" round @click="GetChannelRobots" style="margin-left: 10px;">获取频道机器人</n-button>
|
<n-button type="info" round @click="GetChannelRobots" style="margin-left: 10px"
|
||||||
<n-button type="info" round @click="SaveMjSetting" style="margin-left: 10px;">保存MJ配置</n-button>
|
>获取频道机器人</n-button
|
||||||
<n-divider />
|
>
|
||||||
<n-form ref="formRef" label-placement="top" :model="mjSetting" :rules="rules">
|
<n-button type="info" round @click="SaveMjSetting" style="margin-left: 10px">保存MJ配置</n-button>
|
||||||
<div style="display: flex;">
|
<n-divider />
|
||||||
<n-form-item label="服务器ID" style="width: 400px;" path="serviceID">
|
<n-form ref="formRef" label-placement="top" :model="mjSetting" :rules="rules">
|
||||||
<n-input v-model:value="mjSetting.serviceID" placeholder="登录MJ后切换服务器自动获取" />
|
<div style="display: flex">
|
||||||
</n-form-item>
|
<n-form-item label="服务器ID" style="width: 400px" path="serviceID">
|
||||||
<n-form-item label="频道ID" style="width: 400px; margin-left: 10px" path="channelID">
|
<n-input v-model:value="mjSetting.serviceID" placeholder="登录MJ后切换服务器自动获取" />
|
||||||
<n-input v-model:value="mjSetting.channelID" placeholder="登录MJ后切换频道自动获取" />
|
</n-form-item>
|
||||||
</n-form-item>
|
<n-form-item label="频道ID" style="width: 400px; margin-left: 10px" path="channelID">
|
||||||
</div>
|
<n-input v-model:value="mjSetting.channelID" placeholder="登录MJ后切换频道自动获取" />
|
||||||
<div style="display: flex;">
|
</n-form-item>
|
||||||
<n-form-item label="MJ机器ID" path="mj.botId">
|
</div>
|
||||||
<n-input v-model:value="mjSetting.mj.botId" placeholder="MJ机器ID" />
|
<!-- <div style="display: flex">
|
||||||
</n-form-item>
|
<n-form-item label="MJ机器ID" path="mj.botId">
|
||||||
<n-form-item label="MJ命令ID" style="margin-left: 10px" path="mj.commandId">
|
<n-input v-model:value="mjSetting.mj.botId" placeholder="MJ机器ID" />
|
||||||
<n-input v-model:value="mjSetting.mj.commandId" placeholder="MJ命令ID" />
|
</n-form-item>
|
||||||
</n-form-item>
|
<n-form-item label="MJ命令ID" style="margin-left: 10px" path="mj.commandId">
|
||||||
<n-form-item label="MJ命令名称" style="margin-left: 10px" path="mj.commandName">
|
<n-input v-model:value="mjSetting.mj.commandId" placeholder="MJ命令ID" />
|
||||||
<n-input v-model:value="mjSetting.mj.commandName" placeholder="MJ命令名称" />
|
</n-form-item>
|
||||||
</n-form-item>
|
<n-form-item label="MJ命令名称" style="margin-left: 10px" path="mj.commandName">
|
||||||
<n-form-item label="MJ版本ID" style="margin-left: 10px" path="mj.versionId">
|
<n-input v-model:value="mjSetting.mj.commandName" placeholder="MJ命令名称" />
|
||||||
<n-input v-model:value="mjSetting.mj.versionId" placeholder="MJ版本ID" />
|
</n-form-item>
|
||||||
</n-form-item>
|
<n-form-item label="MJ版本ID" style="margin-left: 10px" path="mj.versionId">
|
||||||
</div>
|
<n-input v-model:value="mjSetting.mj.versionId" placeholder="MJ版本ID" />
|
||||||
|
</n-form-item>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div style="display: flex;">
|
<div style="display: flex">
|
||||||
<n-form-item label="NIJI机器ID" path="niji.botId">
|
<n-form-item label="NIJI机器ID" path="niji.botId">
|
||||||
<n-input v-model:value="mjSetting.niji.botId" placeholder="NIJI机器ID" />
|
<n-input v-model:value="mjSetting.niji.botId" placeholder="NIJI机器ID" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="NIJI命令ID" style="margin-left: 10px" path="niji.commandId">
|
<n-form-item label="NIJI命令ID" style="margin-left: 10px" path="niji.commandId">
|
||||||
<n-input v-model:value="mjSetting.niji.commandId" placeholder="NIJI命令ID" />
|
<n-input v-model:value="mjSetting.niji.commandId" placeholder="NIJI命令ID" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="NIJI命令名称" style="margin-left: 10px" path="niji.commandName">
|
<n-form-item label="NIJI命令名称" style="margin-left: 10px" path="niji.commandName">
|
||||||
<n-input v-model:value="mjSetting.niji.commandName" placeholder="NIJI命令名称" />
|
<n-input v-model:value="mjSetting.niji.commandName" placeholder="NIJI命令名称" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="NIJI版本ID" style="margin-left: 10px" path="niji.versionId">
|
<n-form-item label="NIJI版本ID" style="margin-left: 10px" path="niji.versionId">
|
||||||
<n-input v-model:value="mjSetting.niji.versionId" placeholder="NIJI版本ID" />
|
<n-input v-model:value="mjSetting.niji.versionId" placeholder="NIJI版本ID" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<n-form-item label="用户token" style="width: 810px;" path="token">
|
<n-form-item label="用户token" style="width: 810px" path="token">
|
||||||
<n-input v-model:value="mjSetting.token" placeholder="登录MJ后切换服务器自动获取" />
|
<n-input v-model:value="mjSetting.token" placeholder="登录MJ后切换服务器自动获取" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="用户Agent" style="width: 810px;" path="userAgent.userAgent">
|
<n-form-item label="用户Agent" style="width: 810px" path="userAgent.userAgent">
|
||||||
<n-input v-model:value="mjSetting.userAgent.userAgent" placeholder="登录MJ后切换服务器自动获取(可自定义)"
|
<n-input
|
||||||
style="margin-right: 10px;" />
|
v-model:value="mjSetting.userAgent.userAgent"
|
||||||
<n-tooltip trigger="hover" style="background-color: aliceblue; color: black;">
|
placeholder="登录MJ后切换服务器自动获取(可自定义)"
|
||||||
<template #trigger>
|
style="margin-right: 10px"
|
||||||
<n-checkbox v-model:checked="mjSetting.userAgent.customize" style="width: 100px;">
|
/>
|
||||||
自定义
|
<n-tooltip trigger="hover" style="background-color: aliceblue; color: black">
|
||||||
</n-checkbox>
|
<template #trigger>
|
||||||
</template>
|
<n-checkbox v-model:checked="mjSetting.userAgent.customize" style="width: 100px">
|
||||||
开启自定义需要手动填写userAgent。可以填入浏览器的userAgent
|
自定义
|
||||||
</n-tooltip>
|
</n-checkbox>
|
||||||
</n-form-item>
|
</template>
|
||||||
<div style="display: flex; align-items: center;">
|
开启自定义需要手动填写userAgent。可以填入浏览器的userAgent
|
||||||
<n-form-item label="选择生图机器人" path="select_robot" style="width: 200px;">
|
</n-tooltip>
|
||||||
<n-select :options="select_robot_options" v-model:value="mjSetting.select_robot"></n-select>
|
</n-form-item>
|
||||||
</n-form-item>
|
<div style="display: flex; align-items: center">
|
||||||
<n-button color="#e18a3b" style="margin-left : 3px" @click="RefreshRobotOptions">
|
<n-form-item label="选择生图机器人" path="select_robot" style="width: 120px">
|
||||||
<n-icon size="large">
|
<n-select
|
||||||
<reload></reload>
|
:options="select_robot_options"
|
||||||
</n-icon>
|
v-model:value="mjSetting.select_robot"
|
||||||
</n-button>
|
@update:value="UpdateSelectRobot"
|
||||||
</div>
|
></n-select>
|
||||||
</n-form>
|
</n-form-item>
|
||||||
|
<n-form-item label="机器人模型" style="width: 120px; margin-left: 10px" path="image_scale">
|
||||||
|
<n-select
|
||||||
|
placeholder="请选择机器人模型"
|
||||||
|
:options="image_model_options"
|
||||||
|
v-model:value="mjSetting.image_model"
|
||||||
|
></n-select>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="生图尺寸" style="width: 120px; margin-left: 10px" path="image_scale">
|
||||||
|
<n-select
|
||||||
|
placeholder="请选择生图尺寸"
|
||||||
|
:options="image_scale_options"
|
||||||
|
v-model:value="mjSetting.image_scale"
|
||||||
|
></n-select>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="命令后缀" style="width: 160px; margin-left: 10px" path="image_suffix">
|
||||||
|
<n-input v-model:value="image_suffix" placeholder="请输入后缀命令"></n-input>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="生图任务量" style="width: 100px; margin-left: 10px" path="task_count">
|
||||||
|
<n-input-number
|
||||||
|
v-model:value="mjSetting.task_count"
|
||||||
|
:show-button="false"
|
||||||
|
placeholder="MJ并发出图数量"
|
||||||
|
:min="1"
|
||||||
|
:max="10"
|
||||||
|
></n-input-number>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="间隔时间(s)" style="width: 100px; margin-left: 10px" path="space_time">
|
||||||
|
<n-input-number
|
||||||
|
v-model:value="mjSetting.space_time"
|
||||||
|
:show-button="false"
|
||||||
|
placeholder="请输入间隔时间(s)"
|
||||||
|
:min="1"
|
||||||
|
:max="20"
|
||||||
|
></n-input-number>
|
||||||
|
</n-form-item>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="display: flex">
|
||||||
|
<n-form-item label="出图模式" style="width: 150px" path="request_model">
|
||||||
|
<n-select
|
||||||
|
:options="request_model_options"
|
||||||
|
v-model:value="mjSetting.request_model"
|
||||||
|
placeholder="请选择出图模式"
|
||||||
|
></n-select>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="选择出图的API" style="width: 160px; margin-left: 10px" path="mj_api_url">
|
||||||
|
<n-select
|
||||||
|
:options="mj_api_options"
|
||||||
|
v-model:value="mjSetting.mj_api_url"
|
||||||
|
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="mj_speed">
|
||||||
|
<n-select
|
||||||
|
:options="mj_speed_options"
|
||||||
|
v-model:value="mjSetting.mj_speed"
|
||||||
|
placeholder="选择出图速度模式"
|
||||||
|
/>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="输入API密钥" style="width: 160px; margin-left: 10px" path="mj_speed">
|
||||||
|
<n-input
|
||||||
|
type="password"
|
||||||
|
placeholder="请输入密钥"
|
||||||
|
v-model:value="mjSetting.api_key"
|
||||||
|
></n-input>
|
||||||
|
</n-form-item>
|
||||||
|
</div>
|
||||||
|
</n-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent, ref, h, onMounted, nextTick, watch, toRaw } from "vue";
|
import { defineComponent, ref, onMounted, computed, toRaw } from 'vue'
|
||||||
import { NButton, useMessage, NDataTable, NForm, NFormItem, NInput, NDivider, NCheckbox, NSelect, NTooltip, NIcon } from "naive-ui"
|
import {
|
||||||
import { DEFINE_STRING } from "../../../../define/define_string";
|
NButton,
|
||||||
import { Reload } from "@vicons/ionicons5"
|
useMessage,
|
||||||
import { isEmpty } from "lodash";
|
NDataTable,
|
||||||
|
NForm,
|
||||||
|
NFormItem,
|
||||||
|
NInput,
|
||||||
|
NDivider,
|
||||||
|
NCheckbox,
|
||||||
|
NSelect,
|
||||||
|
NTooltip,
|
||||||
|
NIcon,
|
||||||
|
NInputNumber
|
||||||
|
} from 'naive-ui'
|
||||||
|
import { DEFINE_STRING } from '../../../../define/define_string'
|
||||||
|
import { Reload } from '@vicons/ionicons5'
|
||||||
|
import { isEmpty, max, min } from 'lodash'
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
NButton, NDataTable, NForm, NFormItem, NInput, NDivider, NCheckbox, NSelect, NTooltip, NIcon, Reload
|
NButton,
|
||||||
},
|
NDataTable,
|
||||||
setup() {
|
NForm,
|
||||||
let message = useMessage();
|
NFormItem,
|
||||||
let formRef = ref(null);
|
NInput,
|
||||||
|
NDivider,
|
||||||
|
NCheckbox,
|
||||||
|
NSelect,
|
||||||
|
NTooltip,
|
||||||
|
NIcon,
|
||||||
|
Reload,
|
||||||
|
NInputNumber
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
let message = useMessage()
|
||||||
|
let formRef = ref(null)
|
||||||
|
let select_robot_options = ref([
|
||||||
|
{
|
||||||
|
label: 'MJ',
|
||||||
|
value: 'mj'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'NIJI',
|
||||||
|
value: 'niji'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
let mjSetting = ref({
|
let mj_speed_options = ref([
|
||||||
serviceID: null,
|
{
|
||||||
channelID: null,
|
label: 'RELAXED',
|
||||||
mj: {
|
value: 'relaxed'
|
||||||
botId: null,
|
},
|
||||||
commandId: null,
|
{
|
||||||
commandName: null,
|
label: 'FAST',
|
||||||
versionId: null
|
value: 'fast'
|
||||||
},
|
}
|
||||||
niji: {
|
])
|
||||||
botId: null,
|
|
||||||
commandId: null,
|
|
||||||
commandName: null,
|
|
||||||
versionId: null
|
|
||||||
},
|
|
||||||
token: null,
|
|
||||||
userAgent: {
|
|
||||||
userAgent: null,
|
|
||||||
customize: false
|
|
||||||
|
|
||||||
},
|
let mjSetting = ref({
|
||||||
select_robot: null,
|
serviceID: null,
|
||||||
});
|
channelID: null,
|
||||||
|
mj: {
|
||||||
|
botId: null,
|
||||||
|
commandId: null,
|
||||||
|
commandName: null,
|
||||||
|
versionId: null
|
||||||
|
},
|
||||||
|
niji: {
|
||||||
|
botId: null,
|
||||||
|
commandId: null,
|
||||||
|
commandName: null,
|
||||||
|
versionId: null
|
||||||
|
},
|
||||||
|
token: null,
|
||||||
|
userAgent: {
|
||||||
|
userAgent: null,
|
||||||
|
customize: false
|
||||||
|
},
|
||||||
|
select_robot: null,
|
||||||
|
image_scale: null,
|
||||||
|
image_model: null,
|
||||||
|
image_suffix: null,
|
||||||
|
task_count: 3,
|
||||||
|
space_time: 5,
|
||||||
|
request_model: null,
|
||||||
|
mj_api_url: null,
|
||||||
|
mj_speed: null,
|
||||||
|
api_key: null
|
||||||
|
})
|
||||||
|
|
||||||
function checkNull(obj) {
|
let image_scale_options = ref([])
|
||||||
for (let key in obj) {
|
let image_model_options = ref([])
|
||||||
if (obj[key] == undefined) {
|
let tmp_image_model_options = []
|
||||||
return false;
|
let request_model_options = ref([])
|
||||||
}
|
let mj_api_options = ref([])
|
||||||
|
|
||||||
|
let image_suffix = computed(() => {
|
||||||
|
debugger
|
||||||
|
let text = image_model_options.value.findIndex((item) => {
|
||||||
|
return item.value == mjSetting.value.image_model
|
||||||
|
})
|
||||||
|
if (text == -1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let sc = image_scale_options.value.findIndex((item) => {
|
||||||
|
return item.value == mjSetting.value.image_scale
|
||||||
|
})
|
||||||
|
let dd = ` --${image_model_options.value[text].text} --ar ${image_scale_options.value[sc].text}`
|
||||||
|
mjSetting.value.image_suffix = dd
|
||||||
|
return dd
|
||||||
|
})
|
||||||
|
|
||||||
|
// 初始化现在设置的数据
|
||||||
|
async function InitData() {
|
||||||
|
// 获取当前mj配置信息
|
||||||
|
await window.api.GetDefineConfigJsonByProperty(
|
||||||
|
JSON.stringify(['img_base', 'mj_config', false, null]),
|
||||||
|
(value) => {
|
||||||
|
debugger
|
||||||
|
console.log(value)
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 判断是不是有数据
|
||||||
|
if (value.data) {
|
||||||
|
mjSetting.value = Object.assign(mjSetting.value, value.data)
|
||||||
|
if (mjSetting.value.select_robot != 'mj' && mjSetting.value.select_robot != 'niji') {
|
||||||
|
mjSetting.value.select_robot = null
|
||||||
}
|
}
|
||||||
return true;
|
}
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
function modifyOption(value) {
|
await window.mj.GetMJImageScale((value) => {
|
||||||
// 遍历mjSetting.mj,判断里面的属性数据是不是都存在,如果存在则添加到 select_robot_options 中
|
if (value.code == 0) {
|
||||||
select_robot_options.value = [];
|
message.error(value.message)
|
||||||
|
return
|
||||||
let isObj = checkNull(value.mj);
|
|
||||||
if (isObj) {
|
|
||||||
select_robot_options.value.push({
|
|
||||||
label: "MJ",
|
|
||||||
value: value.mj.botId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
isObj = checkNull(value.niji);
|
|
||||||
|
|
||||||
if (isObj) {
|
|
||||||
select_robot_options.value.push({
|
|
||||||
label: "NIJI",
|
|
||||||
value: value.niji.botId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 判断当前的select_robot是不是在select_robot_options中,如果不在则设置为null
|
|
||||||
if (select_robot_options.value.findIndex((item) => { return item.value == mjSetting.value.select_robot }) == -1)
|
|
||||||
mjSetting.value.select_robot = null;
|
|
||||||
}
|
}
|
||||||
|
image_scale_options.value = value.data
|
||||||
// 监听数据改变,生成下拉的options
|
if (image_scale_options.value.length > 0 && mjSetting.value.image_scale == null) {
|
||||||
watch(mjSetting.value, (value) => {
|
mjSetting.value.image_scale = image_scale_options.value[0].value
|
||||||
mjSetting.value = value;
|
|
||||||
// 计算下拉的options
|
|
||||||
modifyOption(value)
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let select_robot_options = ref([])
|
|
||||||
|
|
||||||
// 初始化现在设置的数据
|
|
||||||
async function InitData() {
|
|
||||||
// 获取当前mj配置信息
|
|
||||||
await window.api.GetDefineConfigJsonByProperty(JSON.stringify(["img_base", "mj_config", false, null]), (value) => {
|
|
||||||
debugger
|
|
||||||
console.log(value);
|
|
||||||
if (value.code == 0) {
|
|
||||||
message.error(value.message);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 判断是不是有数据
|
|
||||||
if (value.data) {
|
|
||||||
mjSetting.value = value.data;
|
|
||||||
modifyOption(value.data);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
onMounted(async () => {
|
await window.mj.GetMJImageRobotModel((value) => {
|
||||||
// 监听修改当前界面的数据,后续可以将数据保存到本地配置
|
if (value.code == 0) {
|
||||||
window.api.setEventListen([DEFINE_STRING.DISCORD.OPERATE_REFRASH_DISCORD_URL], (value) => {
|
message.error(value.message)
|
||||||
if (value.code == 0) {
|
return
|
||||||
message.error(value.message);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 保存数据
|
|
||||||
console.log(value);
|
|
||||||
if (value.type == DEFINE_STRING.DISCORD_SIMPLE_DATA_TYPE.URL) {
|
|
||||||
mjSetting.value.serviceID = value.data.serviceID;
|
|
||||||
mjSetting.value.channelID = value.data.channelID;
|
|
||||||
} else if (value.type == DEFINE_STRING.DISCORD_SIMPLE_DATA_TYPE.TOKEN) {
|
|
||||||
mjSetting.value.token = value.data.authorization;
|
|
||||||
if (!mjSetting.value.userAgent.customize) {
|
|
||||||
mjSetting.value.userAgent.userAgent = value.data.userAgent;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
message.error("未知的数据类型");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
await InitData();
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开discord窗口
|
|
||||||
*/
|
|
||||||
async function OpenDiscordWindow() {
|
|
||||||
await window.api.OpenDiscordWindow((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.image_model == null) {
|
||||||
*/
|
mjSetting.value.image_model = image_model_options.value[0].value
|
||||||
async function GetChannelRobots() {
|
|
||||||
|
|
||||||
// 判断是不是有数据(服务器ID,频道ID,用户token,用户Agent)
|
|
||||||
if (isEmpty(mjSetting.value.serviceID) &&
|
|
||||||
isEmpty(mjSetting.value.channelID) &&
|
|
||||||
isEmpty(mjSetting.value.token) &&
|
|
||||||
isEmpty(mjSetting.value.userAgent.userAgent)) {
|
|
||||||
message.error("请先填写或获取完整的数据(服务器ID,频道ID,用户token,用户Agent)");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const headers = {
|
|
||||||
'authorization': mjSetting.value.token
|
|
||||||
}
|
|
||||||
|
|
||||||
await fetch(`https://discord.com/api/v9/guilds/${mjSetting.value.serviceID}/application-command-index`, {
|
|
||||||
method: 'GET',
|
|
||||||
headers: headers,
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
debugger
|
|
||||||
// 修改配置信息(判断是不是niji或者是mj)
|
|
||||||
// 填充mj,niji数据
|
|
||||||
if (data.applications && data.application_commands) {
|
|
||||||
let mj_inedx = data.applications.findIndex((item) => {
|
|
||||||
return item.name.toLowerCase().startsWith("midjourney");
|
|
||||||
})
|
|
||||||
if (mj.index != -1) {
|
|
||||||
mjSetting.value.mj.botId = data.applications[mj_inedx].id;
|
|
||||||
let f = data.application_commands.find((a) => { return a.name == "imagine" && a.application_id == data.applications[mj_inedx].id })
|
|
||||||
mjSetting.value.mj.commandId = f?.id;
|
|
||||||
mjSetting.value.mj.commandName = "imagine";
|
|
||||||
mjSetting.value.mj.versionId = f?.version;
|
|
||||||
}
|
|
||||||
|
|
||||||
let niji_inedx = data.applications.findIndex((item) => {
|
|
||||||
return item.name.toLowerCase().startsWith("niji");
|
|
||||||
})
|
|
||||||
if (mj.index != -1) {
|
|
||||||
mjSetting.value.niji.botId = data.applications[niji_inedx].id;
|
|
||||||
let f = data.application_commands.find((a) => { return a.name == "imagine" && a.application_id == data.applications[niji_inedx].id })
|
|
||||||
mjSetting.value.niji.commandId = f?.id;
|
|
||||||
mjSetting.value.niji.commandName = "imagine";
|
|
||||||
mjSetting.value.niji.versionId = f?.version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
window.api.showGlobalNotificationDialog({
|
|
||||||
code: 0,
|
|
||||||
message: "获取频道机器人请求失败,错误信息如下: " + error.message.toString()
|
|
||||||
})
|
|
||||||
return
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
await window.mj.GetMJGenerateCategory((value) => {
|
||||||
* 保存MJ配置
|
if (value.code == 0) {
|
||||||
*/
|
message.error(value.message)
|
||||||
async function SaveMjSetting(e) {
|
return
|
||||||
e.preventDefault();
|
|
||||||
formRef.value?.validate(async (errors) => {
|
|
||||||
if (errors) {
|
|
||||||
message.error("请检查必填字段");
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
await window.api.SaveDefineConfigJsonByProperty(JSON.stringify(["img_base", "mj_config", toRaw(mjSetting.value), false]), (value) => {
|
|
||||||
debugger
|
|
||||||
console.log(value);
|
|
||||||
if (value.code == 0) {
|
|
||||||
message.error(value.message);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
message.success(value.message);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
request_model_options.value = value.data.filter((item) => !item.disable)
|
||||||
/**
|
if (request_model_options.value.length > 0 && mjSetting.value.request_model == null) {
|
||||||
* 刷新数据
|
mjSetting.value.request_model = request_model_options.value[0].value
|
||||||
*/
|
|
||||||
async function RefreshRobotOptions() {
|
|
||||||
modifyOption(mjSetting.value);
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
let ruleObj = (errorMessage) => {
|
await window.api.getGptBusinessOption('all', (value) => {
|
||||||
return [{
|
if (value.code == 0) {
|
||||||
required: true,
|
message.error(value.message)
|
||||||
validator(rule, value) {
|
return
|
||||||
if (value == null || value == "")
|
|
||||||
return new Error(errorMessage);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
trigger: ["input", "blur", "change"]
|
|
||||||
}]
|
|
||||||
}
|
}
|
||||||
let rules = {
|
mj_api_options.value = value.data.filter((item) => item.mj_url)
|
||||||
"serviceID": ruleObj("必填人物名称"),
|
if (mj_api_options.value.length > 0 && mjSetting.value.mj_api_url == null) {
|
||||||
"channelID": ruleObj("必填英文提示词"),
|
mjSetting.value.mj_api_url = mj_api_options.value[0].value
|
||||||
|
|
||||||
"mj.botId": ruleObj("必填英文提示词"),
|
|
||||||
|
|
||||||
"mj.commandId": ruleObj("必填英文提示词"),
|
|
||||||
"mj.commandName": ruleObj("必填英文提示词"),
|
|
||||||
"mj.versionId": ruleObj("必填英文提示词"),
|
|
||||||
"niji.botId": ruleObj("必填英文提示词"),
|
|
||||||
"niji.commandId": ruleObj("必填英文提示词"),
|
|
||||||
"niji.commandName": ruleObj("必填英文提示词"),
|
|
||||||
"niji.versionId": ruleObj("必填英文提示词"),
|
|
||||||
"token": ruleObj("必填英文提示词"),
|
|
||||||
"userAgent.userAgent": ruleObj("必填英文提示词"),
|
|
||||||
"select_robot": ruleObj("必填英文提示词"),
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
OpenDiscordWindow,
|
|
||||||
mjSetting,
|
|
||||||
select_robot_options,
|
|
||||||
GetChannelRobots,
|
|
||||||
SaveMjSetting,
|
|
||||||
RefreshRobotOptions,
|
|
||||||
rules,
|
|
||||||
formRef
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.serviceID = value.data.serviceID
|
||||||
|
mjSetting.value.channelID = value.data.channelID
|
||||||
|
} else if (value.type == DEFINE_STRING.DISCORD_SIMPLE_DATA_TYPE.TOKEN) {
|
||||||
|
mjSetting.value.token = value.data.authorization
|
||||||
|
if (!mjSetting.value.userAgent.customize) {
|
||||||
|
mjSetting.value.userAgent.userAgent = value.data.userAgent
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message.error('未知的数据类型')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await InitData()
|
||||||
|
|
||||||
|
if (mjSetting.value.mj_speed == null) {
|
||||||
|
mjSetting.value.mj_speed = mj_speed_options.value[0].value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开discord窗口
|
||||||
|
*/
|
||||||
|
async function OpenDiscordWindow() {
|
||||||
|
await window.api.OpenDiscordWindow((value) => {
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取频道机器人
|
||||||
|
*/
|
||||||
|
async function GetChannelRobots() {
|
||||||
|
// 判断是不是有数据(服务器ID,频道ID,用户token,用户Agent)
|
||||||
|
if (
|
||||||
|
isEmpty(mjSetting.value.serviceID) &&
|
||||||
|
isEmpty(mjSetting.value.channelID) &&
|
||||||
|
isEmpty(mjSetting.value.token) &&
|
||||||
|
isEmpty(mjSetting.value.userAgent.userAgent)
|
||||||
|
) {
|
||||||
|
message.error('请先填写或获取完整的数据(服务器ID,频道ID,用户token,用户Agent)')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
authorization: mjSetting.value.token
|
||||||
|
}
|
||||||
|
|
||||||
|
await fetch(
|
||||||
|
`https://discord.com/api/v9/guilds/${mjSetting.value.serviceID}/application-command-index`,
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
headers: headers
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data) => {
|
||||||
|
debugger
|
||||||
|
// 修改配置信息(判断是不是niji或者是mj)
|
||||||
|
// 填充mj,niji数据
|
||||||
|
if (data.applications && data.application_commands) {
|
||||||
|
let mj_inedx = data.applications.findIndex((item) => {
|
||||||
|
return item.name.toLowerCase().startsWith('midjourney')
|
||||||
|
})
|
||||||
|
if (mj.index != -1) {
|
||||||
|
mjSetting.value.mj.botId = data.applications[mj_inedx].id
|
||||||
|
let f = data.application_commands.find((a) => {
|
||||||
|
return a.name == 'imagine' && a.application_id == data.applications[mj_inedx].id
|
||||||
|
})
|
||||||
|
mjSetting.value.mj.commandId = f?.id
|
||||||
|
mjSetting.value.mj.commandName = 'imagine'
|
||||||
|
mjSetting.value.mj.versionId = f?.version
|
||||||
|
}
|
||||||
|
|
||||||
|
let niji_inedx = data.applications.findIndex((item) => {
|
||||||
|
return item.name.toLowerCase().startsWith('niji')
|
||||||
|
})
|
||||||
|
if (mj.index != -1) {
|
||||||
|
mjSetting.value.niji.botId = data.applications[niji_inedx].id
|
||||||
|
let f = data.application_commands.find((a) => {
|
||||||
|
return a.name == 'imagine' && a.application_id == data.applications[niji_inedx].id
|
||||||
|
})
|
||||||
|
mjSetting.value.niji.commandId = f?.id
|
||||||
|
mjSetting.value.niji.commandName = 'imagine'
|
||||||
|
mjSetting.value.niji.versionId = f?.version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
window.api.showGlobalNotificationDialog({
|
||||||
|
code: 0,
|
||||||
|
message: '获取频道机器人请求失败,错误信息如下: ' + error.message.toString()
|
||||||
|
})
|
||||||
|
return
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存MJ配置
|
||||||
|
*/
|
||||||
|
async function SaveMjSetting(e) {
|
||||||
|
e.preventDefault()
|
||||||
|
formRef.value?.validate(async (errors) => {
|
||||||
|
if (errors) {
|
||||||
|
message.error('请检查必填字段')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mjSetting.value.image_suffix = image_suffix.value
|
||||||
|
await window.api.SaveDefineConfigJsonByProperty(
|
||||||
|
JSON.stringify(['img_base', 'mj_config', toRaw(mjSetting.value), false]),
|
||||||
|
(value) => {
|
||||||
|
debugger
|
||||||
|
console.log(value)
|
||||||
|
if (value.code == 0) {
|
||||||
|
message.error(value.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
message.success(value.message)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let ruleObj = (errorMessage) => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator(rule, value) {
|
||||||
|
if (value == null || value == '') return new Error(errorMessage)
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
trigger: ['input', 'blur', 'change']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
let rules = {
|
||||||
|
serviceID: ruleObj('必填服务器ID'),
|
||||||
|
channelID: ruleObj('必填频道ID'),
|
||||||
|
'mj.botId': ruleObj('必填MJ机器人ID'),
|
||||||
|
'mj.commandId': ruleObj('必填MJ命令ID'),
|
||||||
|
'mj.commandName': ruleObj('必填Mj命令名称'),
|
||||||
|
'mj.versionId': ruleObj('必填MJ版本ID'),
|
||||||
|
'niji.botId': ruleObj('必填NIJI机器人ID'),
|
||||||
|
'niji.commandId': ruleObj('必填NIJI命令ID'),
|
||||||
|
'niji.commandName': ruleObj('必填NIJI命令名称'),
|
||||||
|
'niji.versionId': ruleObj('必填NIJI版本ID'),
|
||||||
|
token: ruleObj('必填用户token'),
|
||||||
|
'userAgent.userAgent': ruleObj('必填用户Agent'),
|
||||||
|
select_robot: ruleObj('必填选择生图机器人'),
|
||||||
|
image_scale: ruleObj('必填生图尺寸'),
|
||||||
|
image_model: ruleObj('必填机器人模型'),
|
||||||
|
image_suffix: ruleObj('必填命令后缀'),
|
||||||
|
task_count: ruleObj('必填生图任务量'),
|
||||||
|
space_time: ruleObj('必填间隔时间(s)'),
|
||||||
|
request_model: ruleObj('必填出图模式'),
|
||||||
|
mj_api_url: ruleObj('必填选择出图的API'),
|
||||||
|
mj_speed: ruleObj('必填选择出图速度模式')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新选择的机器人时触发的方法
|
||||||
|
*/
|
||||||
|
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.image_model
|
||||||
|
}) == -1
|
||||||
|
) {
|
||||||
|
mjSetting.value.image_model =
|
||||||
|
image_model_options.value.length > 0 ? image_model_options.value[0].value : null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开购买GPT的地址
|
||||||
|
*/
|
||||||
|
async function openGptBuyUrl() {
|
||||||
|
debugger
|
||||||
|
let tmp_gb = mj_api_options.value.filter((item) => item.value == mjSetting.value.mj_api_url)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
OpenDiscordWindow,
|
||||||
|
mjSetting,
|
||||||
|
select_robot_options,
|
||||||
|
GetChannelRobots,
|
||||||
|
SaveMjSetting,
|
||||||
|
rules,
|
||||||
|
formRef,
|
||||||
|
image_scale_options,
|
||||||
|
image_model_options,
|
||||||
|
UpdateSelectRobot,
|
||||||
|
image_suffix,
|
||||||
|
request_model_options,
|
||||||
|
mj_api_options,
|
||||||
|
mj_speed_options,
|
||||||
|
openGptBuyUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@ -197,6 +197,7 @@ import {
|
|||||||
import AddGptOption from './Components/AddGptOption.vue'
|
import AddGptOption from './Components/AddGptOption.vue'
|
||||||
import { FolderOpenSharp as FolderOpen } from '@vicons/ionicons5'
|
import { FolderOpenSharp as FolderOpen } from '@vicons/ionicons5'
|
||||||
import AddGptPrompts from './Components/AddGptPrompts.vue'
|
import AddGptPrompts from './Components/AddGptPrompts.vue'
|
||||||
|
import { isEmpty } from 'lodash'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
@ -250,7 +251,7 @@ export default defineComponent({
|
|||||||
message.error(value.message)
|
message.error(value.message)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gpt_options.value = value.data
|
gpt_options.value = value.data.filter((item) => item.gpt_url)
|
||||||
})
|
})
|
||||||
|
|
||||||
await window.api.getGptModelOption('all', (value) => {
|
await window.api.getGptModelOption('all', (value) => {
|
||||||
@ -367,7 +368,18 @@ export default defineComponent({
|
|||||||
* 打开购买GPT的地址
|
* 打开购买GPT的地址
|
||||||
*/
|
*/
|
||||||
async function openGptBuyUrl() {
|
async function openGptBuyUrl() {
|
||||||
window.api.openGptBuyUrl(toRaw(formValue.value.gpt_business))
|
debugger
|
||||||
|
let tmp_gb = gpt_options.value.filter((item) => item.value == formValue.value.gpt_business)
|
||||||
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user