V 3.2.4(2025.02.24)
1. 新增MJ(API,代理模式)国内转发接口(不包括反推),解决部分用户不能访问外部网络 2. 新增 FLUX-API 国内转发接口,解决部分用户不能访问外部网络(可能出现超时报错) 3. 动态设置FLUX模型,统一后台管理 4. 新增图转视频国内(Kling,Luma,Runway)转发接口,解决部分用户不能访问外部网络 5. 新增支持 Luma 慢速模型 6. 优化MJ设置及MJ请求,减少出错 7. MJ代理模式取消账号生图速度校验 注意:本次更新需要重新设置MJ设置(代理账号不用)
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
import { define } from "@/define/define"
|
||||
import { OptionKeyName } from "@/define/enum/option";
|
||||
import { ValidateJson } from "@/define/Tools/validate";
|
||||
import axios from "axios";
|
||||
import { isEmpty } from "lodash";
|
||||
/**
|
||||
* 远程的FLUX模型列表
|
||||
* @returns
|
||||
*/
|
||||
async function GetRemoteFluxModelList() {
|
||||
debugger
|
||||
let res = await axios.get(define.lms + `/lms/LaitoolOptions/GetSimpleOptions/LaitoolFluxApiModelList`);
|
||||
if (res.data.code != 1) {
|
||||
throw new Error(res.data.message)
|
||||
}
|
||||
let data = res.data.data.filter(item => item.key == "LaitoolFluxApiModelList")
|
||||
if (data.length != 1) {
|
||||
throw new Error("获取远程FLUX API模型列表失败")
|
||||
}
|
||||
if (isEmpty(data[0].value) || !ValidateJson(data[0].value)) {
|
||||
throw new Error("FLUX API模型列表数据异常,请联系管理员!")
|
||||
}
|
||||
return JSON.parse(data[0].value)
|
||||
}
|
||||
|
||||
let SDFluxCommon = {
|
||||
GetRemoteFluxModelList
|
||||
}
|
||||
|
||||
export default SDFluxCommon
|
||||
@@ -1,6 +1,7 @@
|
||||
// @ts-nocheck
|
||||
import { OptionKeyName, OptionType } from '@/define/enum/option'
|
||||
import { useOptionStore } from '@/stores/option'
|
||||
import SDFluxCommon from './SDFluxCommon'
|
||||
|
||||
/**
|
||||
* 初始化特殊字符数据,用于文案的相关处理
|
||||
@@ -90,8 +91,54 @@ async function InitTTSGlobalSetting() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化模型列表
|
||||
* @returns
|
||||
*/
|
||||
async function InitFluxModelList(isMust: boolean = false): Promise<Array<{ label: string, value: string }>> {
|
||||
debugger
|
||||
let initData = []
|
||||
if (!isMust) {
|
||||
let FLUX_APIModelListData = await window.options.GetOptionByKey(OptionKeyName.FLUX_APIModelList);
|
||||
if (FLUX_APIModelListData.code == 0) {
|
||||
window.api.showGlobalMessageDialog(FLUX_APIModelListData);
|
||||
return initData;
|
||||
}
|
||||
if (FLUX_APIModelListData.data == null) {
|
||||
initData = await SDFluxCommon.GetRemoteFluxModelList()
|
||||
let saveRes = await window.options.ModifyOptionByKey(
|
||||
OptionKeyName.FLUX_APIModelList,
|
||||
JSON.stringify(initData),
|
||||
OptionType.JOSN
|
||||
)
|
||||
if (saveRes.code == 0) {
|
||||
window.api.showGlobalMessageDialog(saveRes)
|
||||
return initData
|
||||
} else {
|
||||
return initData
|
||||
}
|
||||
} else {
|
||||
return JSON.parse(FLUX_APIModelListData.data.value)
|
||||
}
|
||||
} else {
|
||||
initData = await SDFluxCommon.GetRemoteFluxModelList()
|
||||
let saveRes = await window.options.ModifyOptionByKey(
|
||||
OptionKeyName.FLUX_APIModelList,
|
||||
JSON.stringify(initData),
|
||||
OptionType.JOSN
|
||||
)
|
||||
if (saveRes.code == 0) {
|
||||
window.api.showGlobalMessageDialog(saveRes)
|
||||
return initData
|
||||
} else {
|
||||
return initData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let InitCommon = {
|
||||
InitSpecialCharacters,
|
||||
InitTTSGlobalSetting
|
||||
InitTTSGlobalSetting,
|
||||
InitFluxModelList
|
||||
}
|
||||
export default InitCommon
|
||||
|
||||
@@ -95,6 +95,8 @@ async function GetBookTaskDetailOption() {
|
||||
}
|
||||
if (ValidateJson(videoMessage.value.lumaOptions)) {
|
||||
lumaOptions.value = JSON.parse(videoMessage.value.lumaOptions)
|
||||
lumaOptions.value.request_model =
|
||||
lumaOptions.value.request_model == null ? 'fast' : lumaOptions.value.request_model
|
||||
lumaOptions.value.image_url = videoMessage.value.imageUrl
|
||||
}
|
||||
if (ValidateJson(videoMessage.value.klingOptions)) {
|
||||
|
||||
@@ -30,6 +30,16 @@
|
||||
<n-form-item-gi :span="12">
|
||||
<n-image width="100" :src="lumaOptions.image_end_url"></n-image>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="4" label="速度模式">
|
||||
<n-select
|
||||
v-model:value="lumaOptions.request_model"
|
||||
:options="[
|
||||
{ label: 'FAST', value: 'fast' },
|
||||
{ label: 'RELAX', value: 'relax' }
|
||||
]"
|
||||
placeholder="请选择速度"
|
||||
></n-select>
|
||||
</n-form-item-gi>
|
||||
</n-grid>
|
||||
</n-form>
|
||||
</div>
|
||||
@@ -37,7 +47,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { NForm, NImage, NGrid, NFormItemGi, NInput, NCheckbox } from 'naive-ui'
|
||||
import { NForm, NImage, NSelect, NGrid, NFormItemGi, NInput, NCheckbox } from 'naive-ui'
|
||||
|
||||
let props = defineProps({
|
||||
lumaOptions: undefined
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
pane-wrapper-style="margin: 0 -4px"
|
||||
pane-style="padding-left: 4px; padding-right: 4px; box-sizing: border-box;"
|
||||
>
|
||||
<n-tab-pane name="mj_setting" tab="MJ设置"> <MJSetting /> </n-tab-pane>
|
||||
<n-tab-pane name="mj_setting" tab="MJ设置"> <MJSettingHome /> </n-tab-pane>
|
||||
<n-tab-pane name="sd_setting" tab="SD设置"> <SDSetting /> </n-tab-pane>
|
||||
<n-tab-pane name="export_video_setting" tab="导出视频设置">
|
||||
<VideoGenerateSetting />
|
||||
@@ -28,7 +28,7 @@
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NTabPane, NTabs, NCard } from 'naive-ui'
|
||||
import MJSetting from '../../Setting/MJSetting.vue'
|
||||
import MJSettingHome from '../../Setting/MJSetting/MJSettingHome.vue'
|
||||
import SDSetting from '../../Setting/SDSetting.vue'
|
||||
import VideoGenerateSetting from '../../Setting/VideoGenerateSetting.vue'
|
||||
import WatermarkSetting from '../../Setting/WatermarkSetting.vue'
|
||||
@@ -39,7 +39,7 @@ export default defineComponent({
|
||||
NTabPane,
|
||||
NTabs,
|
||||
NCard,
|
||||
MJSetting,
|
||||
MJSettingHome,
|
||||
SDSetting,
|
||||
VideoGenerateSetting,
|
||||
WatermarkSetting,
|
||||
|
||||
@@ -1,522 +0,0 @@
|
||||
<template>
|
||||
<div style="overflow: auto; height: 100%">
|
||||
<n-card title="基础设置" size="medium" hoverable style="min-width: 850px">
|
||||
<n-form :model="mjSetting" ref="sampleRef" :rules="sampleRules">
|
||||
<div style="display: flex; align-items: center">
|
||||
<n-form-item label="出图模式" style="width: 150px" path="requestModel">
|
||||
<n-select
|
||||
:options="request_model_options"
|
||||
v-model:value="mjSetting.requestModel"
|
||||
placeholder="请选择出图模式"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="选择生图机器人"
|
||||
path="selectRobot"
|
||||
style="width: 120px; margin-left: 10px"
|
||||
>
|
||||
<n-select
|
||||
:options="select_robot_options"
|
||||
v-model:value="mjSetting.selectRobot"
|
||||
@update:value="UpdateSelectRobot"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item label="机器人模型" style="width: 120px; margin-left: 10px" path="imageModel">
|
||||
<n-select
|
||||
placeholder="请选择机器人模型"
|
||||
:options="image_model_options"
|
||||
v-model:value="mjSetting.imageModel"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item label="生图尺寸" style="width: 120px; margin-left: 10px" path="imageScale">
|
||||
<n-select
|
||||
placeholder="请选择生图尺寸"
|
||||
:options="image_scale_options"
|
||||
v-model:value="mjSetting.imageScale"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item label="命令后缀" style="width: 160px; margin-left: 10px" path="imageSuffix">
|
||||
<n-input v-model:value="mjSetting.imageSuffix" placeholder="请输入后缀命令"></n-input>
|
||||
</n-form-item>
|
||||
<n-form-item label="生图任务量" style="width: 100px; margin-left: 10px" path="taskCount">
|
||||
<n-input-number
|
||||
v-model:value="mjSetting.taskCount"
|
||||
:show-button="false"
|
||||
placeholder="MJ并发出图数量"
|
||||
:min="1"
|
||||
:max="20"
|
||||
></n-input-number>
|
||||
</n-form-item>
|
||||
<n-form-item label="间隔时间(s)" style="width: 100px; margin-left: 10px" path="spaceTime">
|
||||
<n-input-number
|
||||
v-model:value="mjSetting.spaceTime"
|
||||
:show-button="false"
|
||||
placeholder="请输入间隔时间(s)"
|
||||
:min="1"
|
||||
:max="30"
|
||||
></n-input-number>
|
||||
</n-form-item>
|
||||
</div>
|
||||
</n-form>
|
||||
</n-card>
|
||||
<n-card title="API模式设置" hoverable style="margin-top: 10px; min-width: 850px" size="medium">
|
||||
<n-form :model="mjSetting.apiSetting">
|
||||
<div style="display: flex">
|
||||
<n-form-item
|
||||
label="选择出图的API"
|
||||
style="width: 160px; margin-left: 10px"
|
||||
path="mjApiUrl"
|
||||
>
|
||||
<n-select
|
||||
:options="mj_api_options"
|
||||
v-model:value="mjSetting.apiSetting.mjApiUrl"
|
||||
placeholder="选择出图的中转API"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item style="margin-left: 10px" path="mj_api_url">
|
||||
<n-button type="success" @click="openGptBuyUrl">购买</n-button>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="选择出图速度模式"
|
||||
style="width: 160px; margin-left: 10px"
|
||||
path="mjSpeed"
|
||||
>
|
||||
<n-select
|
||||
:options="mj_speed_options"
|
||||
v-model:value="mjSetting.apiSetting.mjSpeed"
|
||||
placeholder="选择出图速度模式"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="输入API密钥" style="width: 160px; margin-left: 10px" path="apiKey">
|
||||
<n-input
|
||||
type="password"
|
||||
placeholder="请输入密钥"
|
||||
show-password-on="mousedown"
|
||||
v-model:value="mjSetting.apiSetting.apiKey"
|
||||
></n-input>
|
||||
</n-form-item>
|
||||
</div>
|
||||
</n-form>
|
||||
</n-card>
|
||||
|
||||
<n-card title="代理模式设置" hoverable style="margin-top: 10px; min-width: 850px">
|
||||
<n-button type="info" @click="AddMultiMjAccount()">账号管理</n-button>
|
||||
</n-card>
|
||||
|
||||
<n-card title="浏览器模式设置" hoverable style="margin-top: 10px; min-width: 850px">
|
||||
<n-form :model="mjSetting.browserSetting">
|
||||
<div style="display: flex; margin-top: 10px">
|
||||
<n-form-item>
|
||||
<n-button type="info" @click="OpenDiscordWindow">打开登录MJ</n-button>
|
||||
</n-form-item>
|
||||
<n-form-item label="服务器ID" style="width: 200px; margin-left: 5px" path="serviceId">
|
||||
<n-input
|
||||
v-model:value="mjSetting.browserSetting.serviceId"
|
||||
placeholder="登录MJ后切换服务器自动获取"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="频道ID" style="width: 200px; margin-left: 10px" path="channelId">
|
||||
<n-input
|
||||
v-model:value="mjSetting.browserSetting.channelId"
|
||||
placeholder="登录MJ后切换频道自动获取"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="用户token" style="width: 300px; margin-left: 10px" path="token">
|
||||
<n-input
|
||||
v-model:value="mjSetting.browserSetting.token"
|
||||
placeholder="登录MJ后切换服务器自动获取"
|
||||
/>
|
||||
</n-form-item>
|
||||
</div>
|
||||
<n-form-item label="用户Agent" style="width: 810px" path="userAgent">
|
||||
<n-input
|
||||
v-model:value="mjSetting.browserSetting.userAgent"
|
||||
placeholder="登录MJ后切换服务器自动获取(可自定义)"
|
||||
style="margin-right: 10px"
|
||||
/>
|
||||
<n-tooltip trigger="hover" style="background-color: aliceblue; color: black">
|
||||
<template #trigger>
|
||||
<n-checkbox
|
||||
v-model:checked="mjSetting.browserSetting.userAgentCustom"
|
||||
style="width: 100px"
|
||||
>
|
||||
自定义
|
||||
</n-checkbox>
|
||||
</template>
|
||||
开启自定义需要手动填写userAgent。可以填入浏览器的userAgent
|
||||
</n-tooltip>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</n-card>
|
||||
<n-button type="info" round @click="SaveMjSetting" style="margin-top: 10px"
|
||||
>保存MJ配置</n-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineComponent, ref, onMounted, computed, toRaw, h } from 'vue'
|
||||
import {
|
||||
NButton,
|
||||
useMessage,
|
||||
useDialog,
|
||||
NDataTable,
|
||||
NForm,
|
||||
NFormItem,
|
||||
NInput,
|
||||
NDivider,
|
||||
NCheckbox,
|
||||
NSelect,
|
||||
NTooltip,
|
||||
NIcon,
|
||||
NInputNumber,
|
||||
NCard,
|
||||
NSpin
|
||||
} from 'naive-ui'
|
||||
import { DEFINE_STRING } from '../../../../define/define_string'
|
||||
import { Reload } from '@vicons/ionicons5'
|
||||
import { isEmpty, max, min } from 'lodash'
|
||||
import { MJImageType } from '../../../../define/enum/mjEnum'
|
||||
import AddMultiRemoteMj from './Components/AddMultiRemoteMj.vue'
|
||||
|
||||
let message = useMessage()
|
||||
let dialog = useDialog()
|
||||
let sampleRef = ref(null)
|
||||
let select_robot_options = ref([
|
||||
{
|
||||
label: 'MJ',
|
||||
value: 'mj'
|
||||
},
|
||||
{
|
||||
label: 'NIJI',
|
||||
value: 'niji'
|
||||
}
|
||||
])
|
||||
|
||||
let mj_speed_options = ref([
|
||||
{
|
||||
label: 'RELAXED',
|
||||
value: 'relaxed'
|
||||
},
|
||||
{
|
||||
label: 'FAST',
|
||||
value: 'fast'
|
||||
}
|
||||
])
|
||||
|
||||
let mjSetting = ref({
|
||||
id: null,
|
||||
imageModel: null,
|
||||
imageScale: null,
|
||||
imageSuffix: null,
|
||||
requestModel: null,
|
||||
type: null,
|
||||
selectRobot: null,
|
||||
spaceTime: 6,
|
||||
taskCount: 3,
|
||||
createTime: null,
|
||||
updateTime: null,
|
||||
version: null,
|
||||
remoteSetting: {
|
||||
accountId: null,
|
||||
channelId: null,
|
||||
coreSize: 3,
|
||||
guildId: null,
|
||||
mjBotChannelId: null,
|
||||
nijiBotChannelId: null,
|
||||
queueSize: 6,
|
||||
remark: null, // 机器码
|
||||
remixAutoSubmit: false,
|
||||
timeoutMinutes: 6,
|
||||
userAgent: null,
|
||||
userToken: null
|
||||
},
|
||||
apiSetting: {
|
||||
id: null,
|
||||
mjApiUrl: null,
|
||||
mjSpeed: null,
|
||||
apiKey: null
|
||||
},
|
||||
browserSetting: {
|
||||
id: null,
|
||||
serviceId: null,
|
||||
channelId: null,
|
||||
mjBotId: null,
|
||||
nijBotId: null,
|
||||
token: null,
|
||||
userAgent: null,
|
||||
userAgentCustom: false
|
||||
}
|
||||
})
|
||||
|
||||
let image_scale_options = ref([])
|
||||
let image_model_options = ref([])
|
||||
let tmp_image_model_options = []
|
||||
let request_model_options = ref([])
|
||||
let mj_api_options = ref([])
|
||||
|
||||
let computedSuffix = () => {
|
||||
let text = image_model_options.value.findIndex((item) => {
|
||||
return item.value == mjSetting.value.imageModel
|
||||
})
|
||||
if (text == -1) {
|
||||
return
|
||||
}
|
||||
let sc = image_scale_options.value.findIndex((item) => {
|
||||
return item.value == mjSetting.value.imageScale
|
||||
})
|
||||
let dd = ` --${image_model_options.value[text].text} --ar ${image_scale_options.value[sc].text}`
|
||||
mjSetting.value.imageSuffix = dd
|
||||
return dd
|
||||
}
|
||||
|
||||
// 初始化现在设置的数据
|
||||
async function InitData() {
|
||||
// 获取到的是当前的配置信息
|
||||
let res = await window.setting.GetMJSettingTreeData()
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
|
||||
if (!res.data.apiSetting) {
|
||||
delete res.data.apiSetting
|
||||
}
|
||||
if (!res.data.remoteSetting) {
|
||||
delete res.data.remoteSetting
|
||||
}
|
||||
if (!res.data.browserSetting) {
|
||||
delete res.data.browserSetting
|
||||
}
|
||||
|
||||
mjSetting.value = Object.assign(mjSetting.value, res.data)
|
||||
|
||||
console.log(res)
|
||||
|
||||
await window.mj.GetMJImageScale((value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
image_scale_options.value = value.data
|
||||
if (image_scale_options.value.length > 0 && mjSetting.value.imageScale == null) {
|
||||
mjSetting.value.imageScale = image_scale_options.value[0].value
|
||||
}
|
||||
})
|
||||
|
||||
await window.mj.GetMJImageRobotModel((value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
image_model_options.value = value.data
|
||||
tmp_image_model_options = value.data
|
||||
if (image_model_options.value.length > 0 && mjSetting.value.imageModel == null) {
|
||||
mjSetting.value.imageModel = image_model_options.value[0].value
|
||||
}
|
||||
})
|
||||
|
||||
await window.mj.GetMJGenerateCategory((value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
request_model_options.value = value.data.filter((item) => !item.disable)
|
||||
if (request_model_options.value.length > 0 && mjSetting.value.requestModel == null) {
|
||||
mjSetting.value.requestModel = request_model_options.value[0].value
|
||||
}
|
||||
})
|
||||
|
||||
await window.api.getGptBusinessOption('all', (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
mj_api_options.value = value.data.filter((item) => item.mj_url)
|
||||
if (mj_api_options.value.length > 0 && mjSetting.value.apiSetting.mjApiUrl == null) {
|
||||
mjSetting.value.apiSetting.mjApiUrl = mj_api_options.value[0].value
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
// 监听浏览器设置的中信息
|
||||
window.api.setEventListen([DEFINE_STRING.DISCORD.OPERATE_REFRASH_DISCORD_URL], (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
// 保存数据
|
||||
console.log(value)
|
||||
if (value.type == DEFINE_STRING.DISCORD_SIMPLE_DATA_TYPE.URL) {
|
||||
mjSetting.value.browserSetting.serviceId = value.data.serviceID
|
||||
mjSetting.value.browserSetting.channelId = value.data.channelID
|
||||
} else if (value.type == DEFINE_STRING.DISCORD_SIMPLE_DATA_TYPE.TOKEN) {
|
||||
mjSetting.value.browserSetting.token = value.data.authorization
|
||||
if (!mjSetting.value.browserSetting.userAgentCustom) {
|
||||
mjSetting.value.browserSetting.userAgent = value.data.userAgent
|
||||
}
|
||||
} else {
|
||||
message.error('未知的数据类型')
|
||||
}
|
||||
})
|
||||
|
||||
await InitData()
|
||||
|
||||
if (mjSetting.value.apiSetting.mjSpeed == null) {
|
||||
mjSetting.value.apiSetting.mjSpeed = mj_speed_options.value[0].value
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 打开discord窗口
|
||||
*/
|
||||
async function OpenDiscordWindow() {
|
||||
await window.api.OpenDiscordWindow((value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 基础配置的必填检测
|
||||
let sampleRules = {
|
||||
imageModel: [{ required: true, message: '请选择机器人模型', trigger: 'blur' }],
|
||||
imageScale: [{ required: true, message: '请选择生图尺寸', trigger: 'blur' }],
|
||||
requestModel: [{ required: true, message: '请选择出图模式', trigger: 'blur' }],
|
||||
selectRobot: [{ required: true, message: '请选择生图机器人', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存MJ配置
|
||||
*/
|
||||
async function SaveMjSetting(e) {
|
||||
// 在保存的时候要进行数据保存
|
||||
|
||||
e.preventDefault()
|
||||
sampleRef.value?.validate(async (errors) => {
|
||||
if (errors) {
|
||||
message.error('请检查必填字段')
|
||||
return
|
||||
}
|
||||
// mjSetting.value.imageSuffix = image_suffix.value
|
||||
|
||||
// 通过选择的请求模式判断哪些是要校验的
|
||||
let request_model = mjSetting.value.requestModel
|
||||
if (request_model == MJImageType.API_MJ) {
|
||||
// API模式,检查必填数据
|
||||
if (
|
||||
mjSetting.value.apiSetting == null ||
|
||||
mjSetting.value.apiSetting.mjApiUrl == null ||
|
||||
mjSetting.value.apiSetting.mjSpeed == null ||
|
||||
mjSetting.value.apiSetting.apiKey == null
|
||||
) {
|
||||
message.error('请检查API模式设置的必填字段')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (request_model == MJImageType.REMOTE_MJ) {
|
||||
// 检查是不是有代理账号
|
||||
let remoteMjRes = await window.setting.GetRemoteMJSettings()
|
||||
if (remoteMjRes.code == 0) {
|
||||
message.error('获取代理MJ配置失败')
|
||||
return
|
||||
}
|
||||
|
||||
if (remoteMjRes.data.length <= 0) {
|
||||
message.error('请先添加代理模式的配置')
|
||||
return
|
||||
}
|
||||
}
|
||||
if (request_model == MJImageType.BROWSER_MJ) {
|
||||
// 浏览器模式,检查必填数据
|
||||
if (
|
||||
mjSetting.value.browserSetting == null ||
|
||||
mjSetting.value.browserSetting.serviceId == null ||
|
||||
mjSetting.value.browserSetting.channelId == null ||
|
||||
mjSetting.value.browserSetting.token == null ||
|
||||
mjSetting.value.browserSetting.userAgent == null
|
||||
) {
|
||||
message.error('请检查浏览器模式设置的必填字段')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 开始保存数据
|
||||
let res = await window.setting.SaveMJSettingTreeData(toRaw(mjSetting.value))
|
||||
if (res.code == 0) {
|
||||
window.api.showGlobalMessageDialog({ code: 0, message: res.message })
|
||||
return
|
||||
}
|
||||
mjSetting.value = res.data
|
||||
// 判断当前的模式
|
||||
if (mjSetting.value.requestModel == MJImageType.REMOTE_MJ) {
|
||||
window.api.showGlobalMessageDialog({
|
||||
code: 1,
|
||||
message: `数据保存成功,当前模式为代理模式`
|
||||
})
|
||||
} else {
|
||||
window.api.showGlobalMessageDialog({ code: 1, message: '添加成功' })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新选择的机器人时触发的方法
|
||||
*/
|
||||
async function UpdateSelectRobot(value) {
|
||||
// 刷新数据
|
||||
image_model_options.value = tmp_image_model_options.filter((item) => {
|
||||
return item.type == value
|
||||
})
|
||||
|
||||
// 判断当前选中的机器人是不是在当前的数据中
|
||||
if (
|
||||
image_model_options.value.findIndex((item) => {
|
||||
return item.value == mjSetting.value.imageModel
|
||||
}) == -1
|
||||
) {
|
||||
mjSetting.value.imageModel =
|
||||
image_model_options.value.length > 0 ? image_model_options.value[0].value : null
|
||||
}
|
||||
|
||||
// 刷新命令后缀
|
||||
mjSetting.value.imageSuffix = computedSuffix()
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开购买GPT的地址
|
||||
*/
|
||||
async function openGptBuyUrl() {
|
||||
let tmp_gb = mj_api_options.value.filter(
|
||||
(item) => item.value == mjSetting.value.apiSetting.mjApiUrl
|
||||
)
|
||||
if (tmp_gb.length == 0) {
|
||||
message.error('当前选择的服务商没有购买地址!')
|
||||
return
|
||||
}
|
||||
let buy_url = tmp_gb[0].buy_url
|
||||
if (isEmpty(buy_url)) {
|
||||
message.error('当前选择的服务商没有购买地址!')
|
||||
} else {
|
||||
window.api.openGptBuyUrl(buy_url)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加多个账号,这样可以同时跑多个账号
|
||||
*/
|
||||
async function AddMultiMjAccount() {
|
||||
let dW = window.innerWidth * 0.9
|
||||
let dH = window.innerHeight * 0.9
|
||||
dialog.create({
|
||||
showIcon: false,
|
||||
title: '管理代理模式MJ账号',
|
||||
content: () => h(AddMultiRemoteMj, { height: dH }),
|
||||
style: `min-width : 600px; width : ${dW}px; height : ${dH}px; padding-right : 5px;`,
|
||||
maskClosable: false
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<div class="mj-api-setting">
|
||||
<n-card title="API模式设置" hoverable style="margin-top: 10px; min-width: 850px" size="medium">
|
||||
<n-form :model="optionStore.MJ_GlobalSetting.mj_apiSetting">
|
||||
<div style="display: flex">
|
||||
<n-form-item
|
||||
label="选择出图的API"
|
||||
style="width: 160px; margin-left: 10px"
|
||||
path="mjApiUrl"
|
||||
>
|
||||
<n-select
|
||||
:options="mjAPIURLOptions"
|
||||
v-model:value="optionStore.MJ_GlobalSetting.mj_apiSetting.mjApiUrl"
|
||||
placeholder="选择出图的中转API"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item style="margin-left: 10px" path="mj_api_url">
|
||||
<n-button type="success" @click="openGptBuyUrl">购买</n-button>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="选择出图速度模式"
|
||||
style="width: 160px; margin-left: 10px"
|
||||
path="mjSpeed"
|
||||
>
|
||||
<n-select
|
||||
:options="mjImageSpeedOptions"
|
||||
v-model:value="optionStore.MJ_GlobalSetting.mj_apiSetting.mjSpeed"
|
||||
placeholder="选择出图速度模式"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="输入API密钥" style="width: 160px; margin-left: 10px" path="apiKey">
|
||||
<n-input
|
||||
type="password"
|
||||
placeholder="请输入密钥"
|
||||
show-password-on="mousedown"
|
||||
v-model:value="optionStore.MJ_GlobalSetting.mj_apiSetting.apiKey"
|
||||
></n-input>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
style="width: 120px; margin-left: 30px"
|
||||
path="useTransfer"
|
||||
label="是否国内转发"
|
||||
>
|
||||
<n-select
|
||||
v-model:value="optionStore.MJ_GlobalSetting.mj_apiSetting.useTransfer"
|
||||
:options="[
|
||||
{ label: '是', value: true },
|
||||
{ label: '否', value: false }
|
||||
]"
|
||||
style="width: 100px"
|
||||
/>
|
||||
</n-form-item>
|
||||
</div>
|
||||
</n-form>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { NCard, NForm, NFormItem, NInput, NSelect, NButton, useMessage } from 'naive-ui'
|
||||
import { useOptionStore } from '@/stores/option'
|
||||
import MJDefine from '@/main/Service/MJ/mjDefine'
|
||||
import { isEmpty } from 'lodash'
|
||||
|
||||
let optionStore = useOptionStore()
|
||||
let message = useMessage()
|
||||
|
||||
let mjAPIURLOptions = ref([])
|
||||
let mjImageSpeedOptions = ref([])
|
||||
|
||||
onMounted(() => {
|
||||
mjAPIURLOptions.value = MJDefine.GetMJAPIUrlOptions()
|
||||
mjImageSpeedOptions.value = MJDefine.GetMJSpeedOptions()
|
||||
})
|
||||
|
||||
/**
|
||||
* 打开购买GPT的地址
|
||||
*/
|
||||
async function openGptBuyUrl() {
|
||||
let selectAPIUrl = mjAPIURLOptions.value.filter(
|
||||
(item) => item.value == optionStore.MJ_GlobalSetting.mj_apiSetting.mjApiUrl
|
||||
)
|
||||
if (selectAPIUrl.length == 0) {
|
||||
message.error('当前选择的服务商没有购买地址!')
|
||||
return
|
||||
}
|
||||
let buy_url = selectAPIUrl[0].buy_url
|
||||
if (isEmpty(buy_url)) {
|
||||
message.error('当前选择的服务商没有购买地址!')
|
||||
} else {
|
||||
window.api.OpenUrl(buy_url)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div class="mj-browser-setting">
|
||||
<n-card title="浏览器模式设置" hoverable style="margin-top: 10px; min-width: 850px">
|
||||
<n-form :model="optionStore.MJ_GlobalSetting.mj_browserSetting">
|
||||
<div style="display: flex; margin-top: 10px">
|
||||
<n-form-item>
|
||||
<n-button type="info" @click="OpenDiscordWindow">打开登录MJ</n-button>
|
||||
</n-form-item>
|
||||
<n-form-item label="服务器ID" style="width: 200px; margin-left: 5px" path="serviceId">
|
||||
<n-input
|
||||
v-model:value="optionStore.MJ_GlobalSetting.mj_browserSetting.serviceId"
|
||||
placeholder="登录MJ后切换服务器自动获取"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="频道ID" style="width: 200px; margin-left: 10px" path="channelId">
|
||||
<n-input
|
||||
v-model:value="optionStore.MJ_GlobalSetting.mj_browserSetting.channelId"
|
||||
placeholder="登录MJ后切换频道自动获取"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="用户token" style="width: 300px; margin-left: 10px" path="token">
|
||||
<n-input
|
||||
v-model:value="optionStore.MJ_GlobalSetting.mj_browserSetting.token"
|
||||
placeholder="登录MJ后切换服务器自动获取"
|
||||
/>
|
||||
</n-form-item>
|
||||
</div>
|
||||
<n-form-item label="用户Agent" style="width: 810px" path="userAgent">
|
||||
<n-input
|
||||
v-model:value="optionStore.MJ_GlobalSetting.mj_browserSetting.userAgent"
|
||||
placeholder="登录MJ后切换服务器自动获取(可自定义)"
|
||||
style="margin-right: 10px"
|
||||
/>
|
||||
<n-tooltip trigger="hover" style="background-color: aliceblue; color: black">
|
||||
<template #trigger>
|
||||
<n-checkbox
|
||||
v-model:checked="optionStore.MJ_GlobalSetting.mj_browserSetting.customUserAgent"
|
||||
style="width: 100px"
|
||||
>
|
||||
自定义
|
||||
</n-checkbox>
|
||||
</template>
|
||||
开启自定义需要手动填写userAgent。可以填入浏览器的userAgent
|
||||
</n-tooltip>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { NCard, NForm, NFormItem, NTooltip, NCheckbox, NInput, NButton } from 'naive-ui'
|
||||
|
||||
import { useOptionStore } from '@/stores/option'
|
||||
|
||||
let optionStore = useOptionStore()
|
||||
|
||||
/**
|
||||
* 打开discord窗口
|
||||
*/
|
||||
async function OpenDiscordWindow() {
|
||||
await window.api.OpenDiscordWindow((value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div class="mj-remote-setting">
|
||||
<n-card title="代理模式设置" hoverable style="margin-top: 10px; min-width: 850px">
|
||||
<n-form inline>
|
||||
<n-form-item style="width: 120px" path="useTransfer" label="是否国内转发">
|
||||
<n-select
|
||||
v-model:value="optionStore.MJ_GlobalSetting.mj_remoteSimpleSetting.useTransfer"
|
||||
:options="[
|
||||
{ label: '是', value: true },
|
||||
{ label: '否', value: false }
|
||||
]"
|
||||
style="width: 100px"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item style="width: 120px; margin-left: 30px" path="useTransfer">
|
||||
<n-button type="info" @click="AddMultiMjAccount">账号管理</n-button>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, h } from 'vue'
|
||||
import { NCard, NButton, useDialog, NForm, NFormItem, NSelect } from 'naive-ui'
|
||||
import AddMultiRemoteMj from '../Components/AddMultiRemoteMj.vue'
|
||||
import { useOptionStore } from '@/stores/option'
|
||||
|
||||
let optionStore = useOptionStore()
|
||||
|
||||
let dialog = useDialog()
|
||||
|
||||
/**
|
||||
* 添加多个账号,这样可以同时跑多个账号
|
||||
*/
|
||||
async function AddMultiMjAccount() {
|
||||
let dW = window.innerWidth * 0.9
|
||||
let dH = window.innerHeight * 0.9
|
||||
dialog.create({
|
||||
showIcon: false,
|
||||
title: '管理代理模式MJ账号',
|
||||
content: () => h(AddMultiRemoteMj, { height: dH }),
|
||||
style: `min-width : 600px; width : ${dW}px; height : ${dH}px; padding-right : 5px;`,
|
||||
maskClosable: false
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<div class="mj-setting-home">
|
||||
<MJSimpleSetting />
|
||||
<MJAPISetting />
|
||||
<MJRemoteSetting />
|
||||
<MJBrowserSetting />
|
||||
<n-button type="info" @click="SaveMjSetting" style="margin-top: 10px">保存MJ配置</n-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useMessage, NButton } from 'naive-ui'
|
||||
import { useSoftwareStore } from '@/stores/software'
|
||||
import { useOptionStore } from '@/stores/option'
|
||||
import { TimeDelay } from '@/define/Tools/time'
|
||||
import { OptionKeyName, OptionType } from '@/define/enum/option'
|
||||
import MJSimpleSetting from './MJSimpleSetting.vue'
|
||||
import MJAPISetting from './MJAPISetting.vue'
|
||||
import MJRemoteSetting from './MJRemoteSetting.vue'
|
||||
import MJBrowserSetting from './MJBrowserSetting.vue'
|
||||
import { MJImageType } from '@/define/enum/mjEnum'
|
||||
import { isEmpty } from 'lodash'
|
||||
|
||||
let softwareStore = useSoftwareStore()
|
||||
let optionStore = useOptionStore()
|
||||
let message = useMessage()
|
||||
|
||||
onMounted(async () => {
|
||||
await InitMJSettingData()
|
||||
})
|
||||
|
||||
/**
|
||||
* 初始化MJSetting数据
|
||||
*/
|
||||
async function InitMJSettingData() {
|
||||
try {
|
||||
softwareStore.spin.spinning = true
|
||||
softwareStore.spin.tip = '正在加载数据,请稍等...'
|
||||
|
||||
let mjRes = await window.options.GetOptionByKey(OptionKeyName.MJ_GlobalSetting)
|
||||
if (mjRes.code == 0) {
|
||||
window.api.showGlobalMessageDialog({
|
||||
code: 0,
|
||||
message: '加载或者是初始化MJSetting信息失败,失败原因:' + mjRes.message
|
||||
})
|
||||
return
|
||||
}
|
||||
if (mjRes.data == null) {
|
||||
let saveRes = await window.options.ModifyOptionByKey(
|
||||
OptionKeyName.MJ_GlobalSetting,
|
||||
JSON.stringify(optionStore.MJ_GlobalSetting),
|
||||
OptionType.JSON
|
||||
)
|
||||
if (saveRes.code == 0) {
|
||||
window.api.showGlobalMessageDialog({
|
||||
code: 0,
|
||||
message: '加载或者是初始化MJSetting信息失败,失败原因:' + saveRes.message
|
||||
})
|
||||
return
|
||||
} else {
|
||||
message.success('初始化MJSetting信息成功')
|
||||
return
|
||||
}
|
||||
} else {
|
||||
optionStore.MJ_GlobalSetting = JSON.parse(mjRes.data.value)
|
||||
message.success('加载MJSetting信息成功')
|
||||
}
|
||||
|
||||
await TimeDelay(1000)
|
||||
} catch (error) {
|
||||
window.api.showGlobalMessageDialog({
|
||||
code: 0,
|
||||
message: '加载或者是初始化MJSetting信息失败,失败原因:' + error.toString()
|
||||
})
|
||||
} finally {
|
||||
softwareStore.spin.spinning = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存MJ配置
|
||||
*/
|
||||
async function SaveMjSetting() {
|
||||
// 在保存的时候要进行数据保存
|
||||
debugger
|
||||
// 通过选择的请求模式判断哪些是要校验的
|
||||
let request_model = optionStore.MJ_GlobalSetting.mj_simpleSetting.requestModel
|
||||
if (request_model == MJImageType.API_MJ) {
|
||||
// API模式,检查必填数据
|
||||
if (
|
||||
optionStore.MJ_GlobalSetting.mj_simpleSetting == null ||
|
||||
isEmpty(optionStore.MJ_GlobalSetting.mj_apiSetting.mjApiUrl) ||
|
||||
isEmpty(optionStore.MJ_GlobalSetting.mj_apiSetting.mjSpeed) ||
|
||||
isEmpty(optionStore.MJ_GlobalSetting.mj_apiSetting.apiKey)
|
||||
) {
|
||||
message.error('请检查API模式设置的必填字段')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (request_model == MJImageType.REMOTE_MJ) {
|
||||
// 检查是不是有代理账号
|
||||
let remoteMjRes = await window.setting.GetRemoteMJSettings()
|
||||
if (remoteMjRes.code == 0) {
|
||||
message.error('获取代理MJ配置失败')
|
||||
return
|
||||
}
|
||||
|
||||
if (remoteMjRes.data.length <= 0) {
|
||||
message.error('请先添加代理模式的配置')
|
||||
return
|
||||
}
|
||||
}
|
||||
if (request_model == MJImageType.BROWSER_MJ) {
|
||||
// 浏览器模式,检查必填数据
|
||||
if (
|
||||
optionStore.MJ_GlobalSetting.mj_browserSetting == null ||
|
||||
isEmpty(optionStore.MJ_GlobalSetting.mj_browserSetting.serviceId) ||
|
||||
isEmpty(optionStore.MJ_GlobalSetting.mj_browserSetting.channelId) ||
|
||||
isEmpty(optionStore.MJ_GlobalSetting.mj_browserSetting.token) ||
|
||||
isEmpty(optionStore.MJ_GlobalSetting.mj_browserSetting.userAgent)
|
||||
) {
|
||||
message.error('请检查浏览器模式设置的必填字段')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
optionStore.MJ_GlobalSetting.mj_simpleSetting.type =
|
||||
optionStore.MJ_GlobalSetting.mj_simpleSetting.requestModel
|
||||
|
||||
let saveRes = await window.options.ModifyOptionByKey(
|
||||
OptionKeyName.MJ_GlobalSetting,
|
||||
JSON.stringify(optionStore.MJ_GlobalSetting),
|
||||
OptionType.JSON
|
||||
)
|
||||
|
||||
if (saveRes.code == 0) {
|
||||
window.api.showGlobalMessageDialog(saveRes)
|
||||
} else {
|
||||
window.api.showGlobalMessageDialog({
|
||||
code: 1,
|
||||
message: '保存数据成功'
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<div class="mj-simple-setting">
|
||||
<n-card title="基础设置" size="medium" hoverable style="min-width: 850px">
|
||||
<n-form
|
||||
:model="optionStore.MJ_GlobalSetting.mj_simpleSetting"
|
||||
ref="sampleRef"
|
||||
:rules="sampleRules"
|
||||
>
|
||||
<div style="display: flex; align-items: center">
|
||||
<n-form-item label="出图模式" style="width: 150px" path="requestModel">
|
||||
<n-select
|
||||
:options="mjRequestModelOptions"
|
||||
v-model:value="optionStore.MJ_GlobalSetting.mj_simpleSetting.requestModel"
|
||||
placeholder="请选择出图模式"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
label="选择生图机器人"
|
||||
path="selectRobot"
|
||||
style="width: 120px; margin-left: 10px"
|
||||
>
|
||||
<n-select
|
||||
:options="mjRobotOptions"
|
||||
v-model:value="optionStore.MJ_GlobalSetting.mj_simpleSetting.selectRobot"
|
||||
@update:value="UpdateSelectRobot"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item label="机器人模型" style="width: 120px; margin-left: 10px" path="imageModel">
|
||||
<n-select
|
||||
placeholder="请选择机器人模型"
|
||||
:options="mjRobotModelOptions"
|
||||
v-model:value="optionStore.MJ_GlobalSetting.mj_simpleSetting.imageModel"
|
||||
@update:value="UpdateRobotModel"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item label="生图尺寸" style="width: 120px; margin-left: 10px" path="imageScale">
|
||||
<n-select
|
||||
placeholder="请选择生图尺寸"
|
||||
:options="mjImageScaleOptions"
|
||||
v-model:value="optionStore.MJ_GlobalSetting.mj_simpleSetting.imageScale"
|
||||
@update:value="UpdateImageScale"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item label="命令后缀" style="width: 160px; margin-left: 10px" path="imageSuffix">
|
||||
<n-input
|
||||
v-model:value="optionStore.MJ_GlobalSetting.mj_simpleSetting.imageSuffix"
|
||||
placeholder="请输入后缀命令"
|
||||
></n-input>
|
||||
</n-form-item>
|
||||
<n-form-item label="生图任务量" style="width: 100px; margin-left: 10px" path="taskCount">
|
||||
<n-input-number
|
||||
v-model:value="optionStore.MJ_GlobalSetting.mj_simpleSetting.taskCount"
|
||||
:show-button="false"
|
||||
placeholder="MJ并发出图数量"
|
||||
:min="1"
|
||||
:max="20"
|
||||
></n-input-number>
|
||||
</n-form-item>
|
||||
<n-form-item label="间隔时间(s)" style="width: 100px; margin-left: 10px" path="spaceTime">
|
||||
<n-input-number
|
||||
v-model:value="optionStore.MJ_GlobalSetting.mj_simpleSetting.spaceTime"
|
||||
:show-button="false"
|
||||
placeholder="请输入间隔时间(s)"
|
||||
:min="1"
|
||||
:max="30"
|
||||
></n-input-number>
|
||||
</n-form-item>
|
||||
</div>
|
||||
</n-form>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { NCard, NForm, NFormItem, NInputNumber, NSelect, NInput } from 'naive-ui'
|
||||
import { useOptionStore } from '@/stores/option'
|
||||
import MJDefine from '@/main/Service/MJ/mjDefine'
|
||||
|
||||
let optionStore = useOptionStore()
|
||||
|
||||
let mjRequestModelOptions = ref([])
|
||||
let mjRobotOptions = ref([])
|
||||
let mjRobotModelOptions = ref([])
|
||||
let mjImageScaleOptions = ref([])
|
||||
|
||||
// 基础配置的必填检测
|
||||
let sampleRules = {
|
||||
imageModel: [{ required: true, message: '请选择机器人模型', trigger: 'blur' }],
|
||||
imageScale: [{ required: true, message: '请选择生图尺寸', trigger: 'blur' }],
|
||||
requestModel: [{ required: true, message: '请选择出图模式', trigger: 'blur' }],
|
||||
selectRobot: [{ required: true, message: '请选择生图机器人', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
mjRequestModelOptions.value = MJDefine.GetMJRequestModelOptions()
|
||||
mjRobotOptions.value = MJDefine.GetMJRobotOptions()
|
||||
mjRobotModelOptions.value = MJDefine.GetMJRobotModelOptions(
|
||||
optionStore.MJ_GlobalSetting.mj_simpleSetting.selectRobot
|
||||
)
|
||||
mjImageScaleOptions.value = MJDefine.GetMJImageScaleOptions()
|
||||
})
|
||||
|
||||
let computedSuffix = () => {
|
||||
let text = mjRobotModelOptions.value.findIndex((item) => {
|
||||
return item.value == optionStore.MJ_GlobalSetting.mj_simpleSetting.imageModel
|
||||
})
|
||||
if (text == -1) {
|
||||
return
|
||||
}
|
||||
let sc = mjImageScaleOptions.value.findIndex((item) => {
|
||||
return item.value == optionStore.MJ_GlobalSetting.mj_simpleSetting.imageScale
|
||||
})
|
||||
let dd = ` --${mjRobotModelOptions.value[text].text} --ar ${mjImageScaleOptions.value[sc].text}`
|
||||
optionStore.MJ_GlobalSetting.mj_simpleSetting.imageSuffix = dd
|
||||
return dd
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新选择的机器人时触发的方法
|
||||
*/
|
||||
function UpdateSelectRobot() {
|
||||
mjRobotModelOptions.value = MJDefine.GetMJRobotModelOptions(
|
||||
optionStore.MJ_GlobalSetting.mj_simpleSetting.selectRobot
|
||||
)
|
||||
|
||||
optionStore.MJ_GlobalSetting.mj_simpleSetting.imageModel =
|
||||
mjRobotModelOptions.value.length > 0 ? mjRobotModelOptions.value[0].value : undefined
|
||||
|
||||
// 刷新命令后缀
|
||||
computedSuffix()
|
||||
}
|
||||
|
||||
function UpdateImageScale() {
|
||||
computedSuffix()
|
||||
}
|
||||
|
||||
function UpdateRobotModel() {
|
||||
computedSuffix()
|
||||
}
|
||||
</script>
|
||||
@@ -111,18 +111,41 @@
|
||||
placeholder="输入迭代步数"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
style="width: 300px"
|
||||
label="FLXU API模型(和GPT公用一个服务商)"
|
||||
path="flux_model"
|
||||
>
|
||||
<n-select
|
||||
placeholder="请选择FLUX API的生图模型"
|
||||
v-model:value="formValue.flux_model"
|
||||
:options="flux_model_options"
|
||||
<div style="display: flex">
|
||||
<n-form-item
|
||||
style="width: 300px"
|
||||
label="FLXU API模型(和GPT公用一个服务商)"
|
||||
path="flux_model"
|
||||
>
|
||||
</n-select>
|
||||
</n-form-item>
|
||||
<n-select
|
||||
placeholder="请选择FLUX API的生图模型"
|
||||
v-model:value="formValue.flux_model"
|
||||
:options="flux_model_options"
|
||||
>
|
||||
</n-select>
|
||||
<n-button type="primary" style="margin-left: 10px" @click="GetFluxModelList"
|
||||
>加载数据
|
||||
</n-button>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
style="width: 150px; margin-left: 30px"
|
||||
label="是否国内转发"
|
||||
path="useTransfer"
|
||||
>
|
||||
<n-select
|
||||
placeholder="请选择是否转换"
|
||||
v-model:value="formValue.useTransfer"
|
||||
:options="[
|
||||
{ label: '是', value: true },
|
||||
{ label: '否', value: false }
|
||||
]"
|
||||
>
|
||||
</n-select>
|
||||
</n-form-item>
|
||||
<n-form-item style="margin-left: 30px">
|
||||
<div style="color: red">注意:使用国内转发可能会出现服务器超时错误,错误码504</div>
|
||||
</n-form-item>
|
||||
</div>
|
||||
<n-form-item>
|
||||
<n-button attr-type="button" type="primary" @click="SaveSDConfig"> 保存设置 </n-button>
|
||||
</n-form-item>
|
||||
@@ -134,7 +157,7 @@
|
||||
</n-tabs>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { defineComponent, ref, h, onMounted, toRaw } from 'vue'
|
||||
import {
|
||||
NForm,
|
||||
@@ -149,188 +172,164 @@ import {
|
||||
NCheckbox
|
||||
} from 'naive-ui'
|
||||
import SDADetailerSetting from '../Components/SDADetailerSetting.vue'
|
||||
import { FLxuAPIImageType } from '../../../../define/enum/image'
|
||||
import InitCommon from '../../common/initCommon'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NForm,
|
||||
NFormItem,
|
||||
NInput,
|
||||
NButton,
|
||||
NInputNumber,
|
||||
NSelect,
|
||||
NTabs,
|
||||
NTabPane,
|
||||
SDADetailerSetting,
|
||||
NCheckbox
|
||||
},
|
||||
setup() {
|
||||
let formValue = ref({
|
||||
webui_api_url: window.config.webui_api_url,
|
||||
type: null,
|
||||
prompt: null,
|
||||
negative_prompt: null,
|
||||
denoising_strength: 1,
|
||||
sampler_name: null,
|
||||
steps: 15,
|
||||
width: 0,
|
||||
height: 0,
|
||||
adetailer: false,
|
||||
style_weight: 1,
|
||||
cfg_scale: 1,
|
||||
sd_models: null,
|
||||
lora: null,
|
||||
flux_model: FLxuAPIImageType.FLUX
|
||||
})
|
||||
let flux_model_options = ref([])
|
||||
|
||||
let samplers_options = ref([])
|
||||
let lora_options = ref([])
|
||||
let sd_models_options = ref([])
|
||||
|
||||
let modelOption = ref([
|
||||
{
|
||||
label: '文生图',
|
||||
value: 'txt2img'
|
||||
},
|
||||
{
|
||||
label: '图生图',
|
||||
value: 'img2img'
|
||||
}
|
||||
])
|
||||
|
||||
onMounted(async () => {
|
||||
await window.api.InitSDConfig((value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
formValue.value = value.data
|
||||
|
||||
let samplers = value.data.sampler
|
||||
samplers_options.value = []
|
||||
for (let i = 0; i < samplers.length; i++) {
|
||||
const element = samplers[i]
|
||||
samplers_options.value.push({
|
||||
label: element.name,
|
||||
value: element.name
|
||||
})
|
||||
}
|
||||
let loras = value.data.lora
|
||||
lora_options.value = []
|
||||
for (let i = 0; i < loras.length; i++) {
|
||||
const element = loras[i]
|
||||
lora_options.value.push({
|
||||
label: element.name,
|
||||
value: element.name
|
||||
})
|
||||
}
|
||||
let sd_models = value.data.sd_model
|
||||
sd_models_options.value = []
|
||||
for (let i = 0; i < sd_models.length; i++) {
|
||||
const element = sd_models[i]
|
||||
sd_models_options.value.push({
|
||||
label: element.title,
|
||||
value: element.title
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
let message = useMessage()
|
||||
/**
|
||||
* 保存SD设置
|
||||
*/
|
||||
async function SaveSDConfig() {
|
||||
// 保存SD配置
|
||||
await window.api.SaveSDConfig(toRaw(formValue.value), (value) => {
|
||||
if (value.code == 0) {
|
||||
window.api.showGlobalMessageDialog(value)
|
||||
return
|
||||
} else if (value.code == 1) {
|
||||
window.api.showGlobalMessageDialog(value)
|
||||
window.api.getSettingDafultData((value) => {
|
||||
window.config = value
|
||||
})
|
||||
return
|
||||
} else {
|
||||
window.api.showGlobalMessageDialog({ code: 0, message: value.message })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载SD数据
|
||||
*/
|
||||
async function LoadSDServiceData() {
|
||||
await window.sd.LoadSDServiceData(toRaw(formValue.value).webui_api_url, (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
// formValue.value = value.data
|
||||
// 获取当前的配置信息
|
||||
let samplers = value.data.sampler
|
||||
samplers_options.value = []
|
||||
for (let i = 0; i < samplers.length; i++) {
|
||||
const element = samplers[i]
|
||||
samplers_options.value.push({
|
||||
label: element.name,
|
||||
value: element.name
|
||||
})
|
||||
}
|
||||
let loras = value.data.lora
|
||||
lora_options.value = []
|
||||
for (let i = 0; i < loras.length; i++) {
|
||||
const element = loras[i]
|
||||
lora_options.value.push({
|
||||
label: element.name,
|
||||
value: element.name
|
||||
})
|
||||
}
|
||||
let sd_models = value.data.sd_model
|
||||
sd_models_options.value = []
|
||||
for (let i = 0; i < sd_models.length; i++) {
|
||||
const element = sd_models[i]
|
||||
sd_models_options.value.push({
|
||||
label: element.title,
|
||||
value: element.title
|
||||
})
|
||||
}
|
||||
message.success('加载成功')
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
formValue,
|
||||
SaveSDConfig,
|
||||
modelOption,
|
||||
LoadSDServiceData,
|
||||
samplers_options,
|
||||
lora_options,
|
||||
sd_models_options,
|
||||
flux_model_options: [
|
||||
{
|
||||
label: 'FLUX',
|
||||
value: FLxuAPIImageType.FLUX
|
||||
},
|
||||
{
|
||||
label: 'FLUX DEV',
|
||||
value: FLxuAPIImageType.FLUX_DEV
|
||||
},
|
||||
{
|
||||
label: 'FLUX PRO',
|
||||
value: FLxuAPIImageType.FLUX_PRO
|
||||
},
|
||||
{
|
||||
label: 'FLUX PRO MAX',
|
||||
value: FLxuAPIImageType.FLUX_PRO_MAX
|
||||
},
|
||||
{
|
||||
label: 'FLUX SCHNELL',
|
||||
value: FLxuAPIImageType.FLUX_SCHNELL
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
let formValue = ref({
|
||||
webui_api_url: window.config.webui_api_url,
|
||||
type: null,
|
||||
prompt: null,
|
||||
negative_prompt: null,
|
||||
denoising_strength: 1,
|
||||
sampler_name: null,
|
||||
steps: 15,
|
||||
width: 0,
|
||||
height: 0,
|
||||
adetailer: false,
|
||||
style_weight: 1,
|
||||
cfg_scale: 1,
|
||||
sd_models: null,
|
||||
lora: null,
|
||||
flux_model: null,
|
||||
useTransfer: false
|
||||
})
|
||||
|
||||
let samplers_options = ref([])
|
||||
let lora_options = ref([])
|
||||
let sd_models_options = ref([])
|
||||
|
||||
let modelOption = ref([
|
||||
{
|
||||
label: '文生图',
|
||||
value: 'txt2img'
|
||||
},
|
||||
{
|
||||
label: '图生图',
|
||||
value: 'img2img'
|
||||
}
|
||||
])
|
||||
|
||||
onMounted(async () => {
|
||||
await window.api.InitSDConfig((value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
formValue.value = value.data
|
||||
|
||||
let samplers = value.data.sampler
|
||||
samplers_options.value = []
|
||||
for (let i = 0; i < samplers.length; i++) {
|
||||
const element = samplers[i]
|
||||
samplers_options.value.push({
|
||||
label: element.name,
|
||||
value: element.name
|
||||
})
|
||||
}
|
||||
let loras = value.data.lora
|
||||
lora_options.value = []
|
||||
for (let i = 0; i < loras.length; i++) {
|
||||
const element = loras[i]
|
||||
lora_options.value.push({
|
||||
label: element.name,
|
||||
value: element.name
|
||||
})
|
||||
}
|
||||
let sd_models = value.data.sd_model
|
||||
sd_models_options.value = []
|
||||
for (let i = 0; i < sd_models.length; i++) {
|
||||
const element = sd_models[i]
|
||||
sd_models_options.value.push({
|
||||
label: element.title,
|
||||
value: element.title
|
||||
})
|
||||
}
|
||||
})
|
||||
await InitFluxModelList()
|
||||
})
|
||||
|
||||
/**
|
||||
* 初始化FLUX模型列表
|
||||
*/
|
||||
async function InitFluxModelList(isMust = false) {
|
||||
try {
|
||||
flux_model_options.value = await InitCommon.InitFluxModelList(isMust)
|
||||
if (!formValue.value.flux_model) {
|
||||
formValue.value.flux_model =
|
||||
flux_model_options.value.length > 0 ? flux_model_options.value[0].value : undefined
|
||||
}
|
||||
} catch (error) {
|
||||
message.error('加载FLUX模型列表失败')
|
||||
}
|
||||
}
|
||||
|
||||
async function GetFluxModelList() {
|
||||
await InitFluxModelList(true)
|
||||
message.success('加载远程 FLUX API 模型列表成功')
|
||||
}
|
||||
|
||||
let message = useMessage()
|
||||
/**
|
||||
* 保存SD设置
|
||||
*/
|
||||
async function SaveSDConfig() {
|
||||
// 保存SD配置
|
||||
await window.api.SaveSDConfig(toRaw(formValue.value), (value) => {
|
||||
if (value.code == 0) {
|
||||
window.api.showGlobalMessageDialog(value)
|
||||
return
|
||||
} else if (value.code == 1) {
|
||||
window.api.showGlobalMessageDialog(value)
|
||||
window.api.getSettingDafultData((value) => {
|
||||
window.config = value
|
||||
})
|
||||
return
|
||||
} else {
|
||||
window.api.showGlobalMessageDialog({ code: 0, message: value.message })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载SD数据
|
||||
*/
|
||||
async function LoadSDServiceData() {
|
||||
await window.sd.LoadSDServiceData(toRaw(formValue.value).webui_api_url, (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
// formValue.value = value.data
|
||||
// 获取当前的配置信息
|
||||
let samplers = value.data.sampler
|
||||
samplers_options.value = []
|
||||
for (let i = 0; i < samplers.length; i++) {
|
||||
const element = samplers[i]
|
||||
samplers_options.value.push({
|
||||
label: element.name,
|
||||
value: element.name
|
||||
})
|
||||
}
|
||||
let loras = value.data.lora
|
||||
lora_options.value = []
|
||||
for (let i = 0; i < loras.length; i++) {
|
||||
const element = loras[i]
|
||||
lora_options.value.push({
|
||||
label: element.name,
|
||||
value: element.name
|
||||
})
|
||||
}
|
||||
let sd_models = value.data.sd_model
|
||||
sd_models_options.value = []
|
||||
for (let i = 0; i < sd_models.length; i++) {
|
||||
const element = sd_models[i]
|
||||
sd_models_options.value.push({
|
||||
label: element.title,
|
||||
value: element.title
|
||||
})
|
||||
}
|
||||
message.success('加载成功')
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -52,6 +52,7 @@ import { useOptionStore } from '@/stores/option'
|
||||
|
||||
let message = useMessage()
|
||||
let optionStore = useOptionStore()
|
||||
let roleOptions = ref([])
|
||||
|
||||
async function SwitchTTSOptions(key) {
|
||||
console.log('SwitchTTSOptions', key)
|
||||
@@ -65,7 +66,6 @@ async function SwitchTTSOptions(key) {
|
||||
console.log('SwitchTTSOptions', roleOptions.value)
|
||||
}
|
||||
|
||||
let roleOptions = ref([])
|
||||
onMounted(async () => {
|
||||
// 获取配音角色列表
|
||||
await SwitchTTSOptions('edge-tts')
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</n-form>
|
||||
<EdgeTTS v-if="optionStore.TTS_GlobalSetting.selectModel == 'edge-tts'" />
|
||||
<!-- <AzureTTS
|
||||
:azureTTS="settingStore.ttsSetting.azureTTS"
|
||||
:azureTTS=""
|
||||
v-else-if="optionStore.TTS_GlobalSetting.selectModel == 'azure-tts'"
|
||||
/> -->
|
||||
</div>
|
||||
|
||||
@@ -86,7 +86,7 @@ const routes = [
|
||||
{
|
||||
path: '/mj_setting',
|
||||
name: 'mj_setting',
|
||||
component: () => import('./components/Setting/MJSetting.vue')
|
||||
component: () => import('./components/Setting/MJSetting/MJSettingHome.vue')
|
||||
},
|
||||
{
|
||||
path: '/video_setting',
|
||||
|
||||
Reference in New Issue
Block a user