修复聚合推文剪映抽帧时,导入srt没有输入
(聚合推文) SD 反推,MJ反推添加单句洗稿功能
(聚合推文)小说任务列表,添加进入出图文件夹的菜单
(聚合推文)新增一键出图
(聚合推文)新增默认出图方式设置,
5.1只对原创生效,SD反推默认是SD,MJ反推默认是MJ
5.2添加批次的默认出图方式同 a点说明,但是选择了 选择旧批次,新批次的默认出图方式会继承
后台任务,完成后台任务的可视化界面
(聚合推文)小说详情界面,添加小说和批次名称显示
This commit is contained in:
2024-11-02 18:18:55 +08:00
parent 22cfe65dde
commit 51deef0c09
64 changed files with 2051 additions and 1136 deletions
@@ -0,0 +1,19 @@
<script setup>
import { onMounted, ref } from 'vue'
import TaskDataTable from './TaskDataTable.vue'
let props = defineProps({
height: undefined
})
let height = ref(props.height - 220)
onMounted(() => {
// 加载任务数据
// height.value = props.height - 200
console.log(height.value)
})
</script>
<template>
<TaskDataTable :height="height" />
</template>
@@ -0,0 +1,247 @@
<template>
<n-form
ref="formRef"
inline
:label-width="80"
:model="softwareStore.backTask.queryData"
size="small"
style="min-width: 600px"
>
<n-grid x-gap="12" y-gap="0" cols="5">
<n-grid-item>
<n-form-item label="任务名称" path="taskName">
<n-input
v-model:value="softwareStore.backTask.queryData.taskName"
placeholder="请输入任务名称"
/>
</n-form-item>
</n-grid-item>
<n-grid-item>
<n-form-item label="小说名" path="bookId">
<n-input
v-model:value="softwareStore.backTask.queryData.bookName"
placeholder="请输入小说名称"
/>
</n-form-item>
</n-grid-item>
<n-grid-item>
<n-form-item label="小说批次任务" path="bookTaskId">
<n-input
v-model:value="softwareStore.backTask.queryData.bookTaskName"
placeholder="请输入小说批次任务名称"
/>
</n-form-item>
</n-grid-item>
<n-grid-item>
<n-form-item label="小说分镜名称" path="bookTaskId">
<n-input
v-model:value="softwareStore.backTask.queryData.bookTaskDetailName"
placeholder="请输入小说分镜名称"
/>
</n-form-item>
</n-grid-item>
<n-grid-item>
<n-form-item label="任务类型" path="taskType">
<n-select
v-model:value="softwareStore.backTask.queryData.taskType"
placeholder="请选择小说任务类型"
:options="taskTypeOptions"
clearable="true"
>
</n-select>
</n-form-item>
</n-grid-item>
<n-grid-item>
<n-form-item label="任务状态" path="taskStatus">
<n-select
v-model:value="softwareStore.backTask.queryData.taskStatus"
placeholder="请选择小说任务类型"
:options="taskStatusOptions"
clearable="true"
></n-select>
</n-form-item>
</n-grid-item>
<n-grid-item>
<n-form-item label="任务失败原因" path="taskErrorMessage">
<n-input
v-model:value="softwareStore.backTask.queryData.taskErrorMessage"
placeholder="请输入小说失败原因"
/>
</n-form-item>
</n-grid-item>
<n-grid-item>
<n-form-item path="taskErrorMessage">
<n-button type="info" @click="ResetQuery">重置</n-button>
<n-button style="margin-left: 10px" type="info" @click="QueryByByCondition"
>查询</n-button
>
</n-form-item>
</n-grid-item>
</n-grid>
</n-form>
<n-data-table
remote
ref="table"
:columns="columns"
:data="softwareStore.backTask.taskData"
:loading="loading"
:pagination="pagination"
:row-key="rowKey"
@update:page="handlePageChange"
:style="{ height: `${height}px` }"
flex-height
:scroll-x="1000"
/>
</template>
<script setup>
import { h, onMounted, reactive, ref, render } from 'vue'
import {
NDataTable,
useMessage,
NForm,
NFormItem,
NInput,
NButton,
NGrid,
NGridItem,
NSelect
} from 'naive-ui'
import { useSoftwareStore } from '@/stores/software'
import {
BookBackTaskStatus,
BookBackTaskType,
GetBookBackTaskStatusLabel,
GetBookBackTaskTypeLabel
} from '@/define/enum/bookEnum'
let softwareStore = useSoftwareStore()
let message = useMessage()
let loading = ref(true)
let props = defineProps({
height: undefined
})
let height = ref(props.height)
let columns = [
{
title: '任务名(小说名+批次任务名+分镜名+任务类型)',
key: 'name',
width: '350px'
},
{
title: '消息名称',
key: 'messageName',
minWidth: 200,
ellipsis: {
tooltip: true
}
},
{
title: '任务类型',
key: 'type',
minWidth: 100
},
{
title: '状态',
key: 'status',
minWidth: 100
},
{
title: '失败原因',
key: 'errorMessage',
minWidth: 300,
ellipsis: {
tooltip: true
}
}
]
async function ResetQuery() {
softwareStore.ResetBackTaskQueryData()
await query(1, pagination.value.pageSize)
}
async function QueryByByCondition() {
await query(1, pagination.value.pageSize)
}
async function query(page, pageSize = 10) {
try {
loading.value = true
let res = await window.task.GetBackTaskCollection({
page,
pageSize,
...softwareStore.backTask.queryData
})
console.log(res)
if (res.code == 0) {
message.error(res.message)
} else {
softwareStore.backTask.taskData = res.data.data
pagination.value.page = page
pagination.value.pageCount = Math.ceil(res.data.count / pageSize)
pagination.value.itemCount = res.data.count
}
} catch (error) {
message.error(error.message)
} finally {
loading.value = false
}
}
const pagination = ref({
page: 1,
pageCount: 1,
pageSize: 10,
showSizePicker: true,
pageSizes: [10, 20, 50, 100, 200, 500],
prefix({ itemCount }) {
return `Total is ${itemCount}.`
},
onUpdatePageSize: async (pageSize) => {
pagination.value.pageSize = pageSize
await handlePageChange(pagination.value.page)
}
})
onMounted(async () => {
debugger
height.value = props.height
console.log(height.value)
await query(pagination.value.page, pagination.value.pageSize)
})
let rowKey = (rowData) => rowData.column1
async function handlePageChange(currentPage) {
if (!loading.value) {
loading.value = true
await query(currentPage, pagination.value.pageSize)
pagination.value.page = currentPage
pagination.value.pageSize = pagination.value.pageSize
}
}
let GetBookBackTaskType = () => {
let options = []
for (const key in BookBackTaskType) {
options.push({
label: GetBookBackTaskTypeLabel(BookBackTaskType[key]),
value: BookBackTaskType[key]
})
}
return options
}
let taskTypeOptions = GetBookBackTaskType()
let GeBookBackTaskStatus = () => {
let options = []
for (const key in BookBackTaskStatus) {
options.push({
label: GetBookBackTaskStatusLabel(BookBackTaskStatus[key]),
value: BookBackTaskStatus[key]
})
}
return options
}
let taskStatusOptions = GeBookBackTaskStatus()
</script>
@@ -99,7 +99,6 @@ export default defineComponent({
// 处理数据。获取当前的所有的数据
let dialogWidth = window.innerWidth * 0.7
let dialogHeight = window.innerHeight * 0.9
// ImportWordAndSrt
dialog.create({
showIcon: false,
closeOnEsc: false,
@@ -397,7 +397,6 @@ export default defineComponent({
// 处理数据。获取当前的所有的数据
let dialogWidth = window.innerWidth * 0.8
let dialogHeight = window.innerHeight * 0.9
// ImportWordAndSrt
dialog.create({
showIcon: false,
closeOnEsc: false,
@@ -479,7 +478,6 @@ export default defineComponent({
// 处理数据。获取当前的所有的数据
let dialogWidth = 800
let dialogHeight = 600
// ImportWordAndSrt
dialog.create({
showIcon: false,
closeOnEsc: false,
@@ -652,7 +652,6 @@ export default defineComponent({
// 处理数据。获取当前的所有的数据
let dialogWidth = window.innerWidth * 0.7
let dialogHeight = window.innerHeight * 0.9
// ImportWordAndSrt
dialog.create({
showIcon: false,
closeOnEsc: false,
@@ -51,7 +51,6 @@ async function EditBook(e) {
reverseManageStore.SetSelectBook(toRaw(book.value))
// 一个弹窗添加数据
let dialogWidth = 600
// ImportWordAndSrt
dialog.create({
showIcon: false,
closeOnEsc: false,
@@ -83,11 +83,10 @@ export default defineComponent({
reverseManageStore.SetSelectBook({
name: null,
id: null,
type: BookType.MJ_REVERSE
type: BookType.ORIGINAL,
})
// 一个弹窗添加数据
let dialogWidth = 600
// ImportWordAndSrt
dialog.create({
showIcon: false,
closeOnEsc: false,
@@ -103,7 +102,7 @@ export default defineComponent({
*/
async function DataTableStripedUpdate() {
// 修改数据
// 直接提交修改
let res = await softwareStore.SaveSoftware()
console.log(res)
@@ -115,7 +114,6 @@ export default defineComponent({
// 选择下拉菜单
async function SelectDropdown(key) {
console.log(key)
softwareStore.softWare.reverse_data_table_size = key
// 直接提交修改
@@ -7,7 +7,7 @@
</div>
</template>
<template #2>
<div style="margin-left: 20px">
<div style="margin-left: 20px; min-width: 500px; overflow: auto">
<AddCharacterTag
v-if="currentType.startsWith('character')"
:currentCharacter="currentCharacter"
@@ -243,8 +243,6 @@ async function SelectReversePrompt() {
message.error('当前没有反推提示词')
return
}
// ImportWordAndSrt
dialog.create({
showIcon: false,
title: `重选MJ反推提示词 ${data.value.name}`,
@@ -6,7 +6,7 @@
size="tiny"
:options="image_options"
@update:value="UpdateImageGenerateCategory"
v-model:value="reverseManageStore.selectBookTask.imageCategory"
v-model:value="select"
placeholder="选择生图模式"
></n-select>
<div v-if="reverseManageStore.selectBookTask.imageCategory == 'mj'">
@@ -38,7 +38,7 @@
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { ref, onMounted, computed } from 'vue'
import { NSelect, NButton, useMessage, useDialog, NPopover, NIcon } from 'naive-ui'
import { useSoftwareStore } from '../../../../../stores/software'
import { useReverseManageStore } from '../../../../../stores/reverseManage'
@@ -50,6 +50,12 @@ let dialog = useDialog()
let reverseManageStore = useReverseManageStore()
let image_options = ref([])
let select = computed(() =>
reverseManageStore.selectBookTask.imageCategory
? reverseManageStore.selectBookTask.imageCategory
: softwareStore.globalSetting.defaultImageMode
)
onMounted(async () => {
// 获取生图下拉列表的方式
await window.api.GetImageGenerateCategory((value) => {
@@ -68,6 +74,7 @@ async function UpdateImageGenerateCategory(value, options) {
imageCategory: value
})
window.api.showGlobalMessage(res)
reverseManageStore.selectBookTask.imageCategory = value
}
async function DownloadAllImage() {
@@ -172,6 +172,7 @@ async function SelectPromptIndex() {
title: '选择反推提示词',
content: () => h(SelectMJReversePrompt),
style: 'width : 500px',
maskClosable: false,
showIcon: false
})
}
@@ -183,7 +184,6 @@ async function SelectStyle() {
// 处理数据。获取当前的所有的数据
let dialogWidth = window.innerWidth * 0.8
let dialogHeight = window.innerHeight * 0.9
// ImportWordAndSrt
dialog.create({
showIcon: false,
closeOnEsc: false,
@@ -45,11 +45,12 @@ export default defineComponent({
let select = computed(() =>
reverseManageStore.selectBookTask.imageCategory
? reverseManageStore.selectBookTask.imageCategory
: BookImageCategory.MJ
: softwareStore.globalSetting.defaultImageMode
)
let options = ref([])
onMounted(async () => {
debugger
// 获取生图下拉列表的方式
await window.api.GetImageGenerateCategory((value) => {
if (value.code == 0) {
@@ -1,7 +1,14 @@
<template>
<div style="display: flex; justify-content: space-between; align-items: center">
<div style="display: flex; align-items: center">
<n-button strong secondary @click="RetuenMain" size="small"> 返回 </n-button>
<n-button strong secondary @click="RetuenMain" size="small">
{{
'返回 | ' +
reverseManageStore.selectBook?.name +
'_' +
reverseManageStore.selectBookTask?.name
}}
</n-button>
<!-- <n-dropdown trigger="hover" :options="AutoOptions" @select="SelectAutoAction">
<n-button :color="softwareStore.SoftColor.ORANGE" @click="Start" style="margin-left: 5px">
自动开始
@@ -206,6 +213,7 @@ async function ComputeStoryboard() {
async function JianyingFrame() {
let da = dialog.info({
title: '剪映分镜参数',
maskClosable: false,
content: () => h(JianyingFrameOption)
})
}
@@ -403,7 +411,6 @@ async function GetWatermarkPosition() {
// 处理数据。获取当前的所有的数据
let dialogWidth = window.innerWidth * 0.7
let dialogHeight = window.innerHeight * 0.9
// ImportWordAndSrt
dialog.create({
showIcon: false,
closeOnEsc: false,
@@ -806,6 +813,7 @@ async function ImportWordAndSrtFunc() {
let tempData = []
for (let i = 0; i < reverseManageStore.selectBookTaskDetail.length; i++) {
debugger
const element = reverseManageStore.selectBookTaskDetail[i]
tempData.push({
no: element.no,
@@ -820,7 +828,6 @@ async function ImportWordAndSrtFunc() {
})
}
// ImportWordAndSrt
dialog.create({
showIcon: false,
closeOnEsc: false,
@@ -54,6 +54,7 @@ async function OpenGetVideoFrame() {
dialog.create({
title: '获取视频的帧',
style: 'width : 800px;',
maskClosable: false,
content: () =>
h(GetVideoFrame, {
videoPath: data.value.videoPath,
@@ -3,6 +3,9 @@
<n-button :render-icon="renderIcon" size="small" type="info" @click="AddBookDialog()"
>新增</n-button
>
<n-button style="margin-left: 5px" size="small" type="info" @click="GenerateAllTaskImage()"
>一键生图</n-button
>
<n-button style="margin-left: 5px" size="small" type="info" @click="HDImageAll()"
>一键高清</n-button
>
@@ -55,7 +58,7 @@ import {
} from 'naive-ui'
import { useReverseManageStore } from '../../../../stores/reverseManage'
import { useSoftwareStore } from '../../../../stores/software'
import { AddSharp } from '@vicons/ionicons5'
import { AddSharp, Open } from '@vicons/ionicons5'
import BookTaskListAction from './Components/ManageBook/BookTaskListAction.vue'
import { useRouter } from 'vue-router'
import { OperateBookType } from '../../../../define/enum/bookEnum'
@@ -63,6 +66,7 @@ import { DEFINE_STRING } from '../../../../define/define_string'
import { ResponseMessageType } from '../../../../define/enum/softwareEnum'
import AddBookTask from './Components/ManageBook/AddBookTask.vue'
import ManageBookTaskGenerateInformation from './Components/ManageBook/ManageBookTaskGenerateInformation.vue'
import { isEmpty } from 'lodash'
let reverseManageStore = useReverseManageStore()
let softwareStore = useSoftwareStore()
@@ -125,6 +129,11 @@ function createColumns() {
key: 'prefix',
width: 130
},
{
title: '出图方式',
key: 'imageCategory',
width: 90
},
{
title: '状态',
key: 'status',
@@ -161,6 +170,10 @@ function createOptions(row) {
label: `合成视频 ${row.name}`,
key: 'generateVideo'
},
{
label: `打开生图文件夹`,
key: 'openImageFolder'
},
{
label: () => h('span', { style: { color: '#f4a534' } }, `重置 ${row.name}`),
key: 'reset'
@@ -263,6 +276,23 @@ async function GenerateVideo(value) {
})
}
async function OpenImageFolder(value) {
debugger
if (isEmpty(value.imageFolder)) {
message.error('没有找到对应的文件夹')
return
}
let res = await window.system.OpenFolder({
folderPath: value.imageFolder,
baseProject: false
})
if (res.code == 0) {
message.error(res.message)
return
}
message.success('打开文件夹成功')
}
/**
* 重置小说数据
* @param e
@@ -328,6 +358,9 @@ async function handleSelect(key) {
case 'generateVideo':
await GenerateVideo(selectRow.value)
break
case 'openImageFolder':
await OpenImageFolder(selectRow.value)
break
case 'reset':
await ReSetBookTaskDetail(selectRow.value)
break
@@ -344,20 +377,31 @@ function onClickoutside() {
showDropdown.value = false
}
// /**
// * 高清数据
// */
// async function hdImageFunc2(id, operateBookType) {
// softwareStore.spin.spinning = true
// softwareStore.spin.tip = '正在高清中。。。'
// let res = await window.book.HDImage(id, 4, operateBookType)
// softwareStore.spin.spinning = false
// if (res.code == 1) {
// message.success('高清成功')
// } else {
// message.error(res.message)
// }
// }
// 一键生图
async function GenerateAllTaskImage() {
if (checkedRowKeysRef.value.length == 0) {
message.error('请选择要生图的数据')
return
}
let da = dialog.warning({
title: '一键生图提示',
content:
'即将开始添加生图任务,会按照每个批次的出图方式添加后台任务,添加之后不可修改,请检查每个批次的出图方式,是否继续?',
positiveText: '继续',
negativeText: '取消',
onPositiveClick: async () => {
da?.destroy()
softwareStore.spin.spinning = true
softwareStore.spin.tip = '正在校验/添加生图任务。。。'
let res = await window.book.GenerateAllTaskImage(
[...checkedRowKeysRef.value],
OperateBookType.ASSIGNBOOKTASK
)
window.api.showGlobalMessageDialog(res);
softwareStore.spin.spinning = false
}
})
}
/**
* 一键高清全部
@@ -406,6 +450,7 @@ async function AddBookDialog() {
dialog.create({
title: '新增小说批次任务',
showIcon: false,
maskClosable: false,
content: () => h(AddBookTask),
style: { width: '600px' }
})
@@ -486,6 +531,7 @@ async function ResetAll() {
return
}
message.success('重置小说任务成功')
checkedRowKeysRef.value = []
} else {
message.error(res.message)
}
@@ -525,6 +571,7 @@ async function DeleteAll() {
}
// 删除成功
message.success('删除小说任务并刷新数据成功')
checkedRowKeysRef.value = []
} else {
message.error(res.message)
}
@@ -274,7 +274,6 @@ async function SelectStyle() {
// 处理数据。获取当前的所有的数据
let dialogWidth = window.innerWidth * 0.8
let dialogHeight = window.innerHeight * 0.9
// ImportWordAndSrt
dialog.create({
showIcon: false,
closeOnEsc: false,
@@ -1,7 +1,12 @@
<template>
<div style="display: flex; align-items: center">
<div style="display: flex">
<n-button strong secondary @click="ReturnMain" size="small">返回</n-button>
<n-button strong secondary @click="ReturnMain" size="small">{{
'返回 | ' +
reverseManageStore.selectBook?.name +
'_' +
reverseManageStore.selectBookTask?.name
}}</n-button>
<n-divider vertical style="height: 30px" />
<!-- <n-button strong secondary @click="ReturnMain" size="small">一键全自动</n-button>
<n-divider vertical style="height: 30px" /> -->
@@ -133,7 +138,6 @@ async function ImportWord() {
})
}
// ImportWordAndSrt
let da = dialog.create({
showIcon: false,
closeOnEsc: false,
@@ -162,10 +166,10 @@ async function ImportWord() {
async function CharacterLibrary() {
// 判断当前数据是不是存在
// 处理数据。获取当前的所有的数据
let dialogWidth = window.innerWidth * 0.6
let dialogWidth = 1000
let dialogHeight = window.innerHeight * 0.9
let word = '' // 这边要拼接一下word
let temp_arr = []
for (let i = 0; i < reverseManageStore.selectBookTaskDetail.length; i++) {
const element = reverseManageStore.selectBookTaskDetail[i]
@@ -235,7 +239,7 @@ async function ResetGPTPrompt() {
onPositiveClick: async () => {
da?.destroy()
softwareStore.spin.spinning = true
softwareStore.spin.tip = '正在重置推理提示词,请稍后。。。'
let res = await window.book.ResetGptReverseData(
reverseManageStore.selectBookTask.id,
@@ -373,7 +377,6 @@ async function GetPromptAll() {
* @param {Boolean} cover - 是否覆盖现有图像
*/
async function AddFluxImageAll(type, cover) {
let messageName = DEFINE_STRING.BOOK.FLUX_API_IMAGE_GENERATE_RETURN
let taskType = BookBackTaskType.FLUX_API_IMAGE
if (type == BookImageCategory.FLUX_FORGE) {
@@ -1,19 +0,0 @@
<script setup>
import { onMounted, ref } from 'vue'
import { useMessage, NButton, NFloatButton, NBadge, NIcon } from 'naive-ui'
import { Layers } from '@vicons/ionicons5'
import { useSoftwareStore } from '../../../../../stores/software'
import QueryButton from './QueryButton.vue'
import TaskDataTable from './TaskDataTable.vue'
let softwareStore = useSoftwareStore()
onMounted(() => {
// 加载任务数据
})
</script>
<template>
<QueryButton />
<TaskDataTable />
</template>
@@ -1,57 +0,0 @@
<script setup>
import { onMounted, ref } from 'vue'
import { useMessage, NForm, NFormItem, NInput, NButton } from 'naive-ui'
import { useSoftwareStore } from '../../../../../stores/software'
let softwareStore = useSoftwareStore()
function handleSubmit() {
alert(123)
}
</script>
<template>
<n-form
ref="formRef"
inline
:label-width="80"
:model="softwareStore.backTask.queryData"
size="small"
>
<n-form-item label="小说" path="bookId">
<n-input v-model:value="softwareStore.backTask.queryData.bookId" placeholder="选择小说任务" />
</n-form-item>
<n-form-item label="小说批次任务" path="bookTaskId">
<n-input
v-model:value="softwareStore.backTask.queryData.bookTaskId"
placeholder="选择小说批次任务"
/>
</n-form-item>
<n-form-item label="任务名字" path="taskName">
<n-input
v-model:value="softwareStore.backTask.queryData.taskName"
placeholder="选择小说批次任务"
/>
</n-form-item>
<n-form-item label="任务类型" path="taskType">
<n-input
v-model:value="softwareStore.backTask.queryData.taskType"
placeholder="选择小说批次任务"
/>
</n-form-item>
<n-form-item label="任务状态" path="taskStatus">
<n-input
v-model:value="softwareStore.backTask.queryData.taskStatus"
placeholder="选择小说批次任务"
/>
</n-form-item>
<n-form-item label="任务失败原因" path="taskErrorMessage">
<n-input
v-model:value="softwareStore.backTask.queryData.taskErrorMessage"
placeholder="选择小说批次任务"
/>
</n-form-item>
<n-form-item path="taskErrorMessage">
<n-button type="info" @click="handleSubmit">查询</n-button>
</n-form-item>
</n-form>
</template>
@@ -1,7 +0,0 @@
<script setup>
</script>
<template>
<div>TaskDataTable</div>
</template>
+3 -2
View File
@@ -64,7 +64,7 @@ import { MD5 } from 'crypto-js'
import InputDialogContent from '../Original/Components/InputDialogContent.vue'
import APIIcon from '../Icon/APIIcon.vue'
import BackTaskIcon from '../Icon/BackTaskIcon.vue'
import BackTask from '../Components/BackTask/BackTask.vue'
import BackTask from '@/renderer/src/components/BackTask/BackTask.vue'
import { useSystemStore } from '../../../../stores/system'
import { TimeDelay } from '../../../../define/Tools/time'
import { BookBackTaskStatus } from '../../../../define/enum/bookEnum'
@@ -603,7 +603,8 @@ function renderIcon(icon) {
}
function OpneBackTask() {
let dialogWidth = window.innerWidth * 0.8
let dialogWidth = window.innerWidth * 0.9
if (dialogWidth < 800) dialogWidth = 800
let dialogHeight = window.innerHeight * 0.95
dialog.create({
title: '后台任务',
File diff suppressed because it is too large Load Diff
@@ -315,7 +315,8 @@ export default defineComponent({
let sdObj = {
batch_size: toRaw(sd_batch_size.value),
width: toRaw(sd_image_width.value),
height: toRaw(sd_image_height.value)
height: toRaw(sd_image_height.value),
seed: toRaw(sd_seed.value)
}
await window.api.SaveSDConfig(sdObj, (value) => {
if (value.code == 0) {
@@ -615,7 +615,6 @@ export default defineComponent({
// 处理数据。获取当前的所有的数据
let dialogWidth = window.innerWidth * 0.8
let dialogHeight = window.innerHeight * 0.9
// ImportWordAndSrt
dialog.create({
showIcon: false,
closeOnEsc: false,
@@ -114,7 +114,6 @@ export default defineComponent({
// 处理数据。获取当前的所有的数据
let dialogWidth = window.innerWidth * 0.95
let dialogHeight = window.innerHeight * 0.95
// ImportWordAndSrt
dialog.create({
showIcon: false,
closeOnEsc: false,
@@ -133,9 +132,8 @@ export default defineComponent({
async function GetCharacter() {
// 判断当前数据是不是存在
// 处理数据。获取当前的所有的数据
let dialogWidth = window.innerWidth * 0.6
let dialogWidth = 1000
let dialogHeight = window.innerHeight * 0.9
// ImportWordAndSrt
dialog.create({
showIcon: false,
closeOnEsc: false,
@@ -217,7 +215,6 @@ export default defineComponent({
* 生成所有的图片
*/
async function GenerateImageAll() {
let tmpData = cloneDeep(toRaw(data.value))
tmpData = tmpData.filter((item) => {
return item.imageLock == null || item.imageLock == false
@@ -363,11 +360,10 @@ export default defineComponent({
message.error(value.message)
return
}
console.log(value.value)
// 拿到提示词文件地址,然后还是获取
await window.pmpt.OpenPromptFileTxt(value.value, (res) => {
console.log(res)
if (res.code == 0) {
message.error(res.message)
@@ -382,7 +378,6 @@ export default defineComponent({
positiveText: '继续',
negativeText: '取消',
onPositiveClick: async () => {
// 开始导入
for (let i = 0; i < data.value.length && i < res.data.length; i++) {
const element = res.data[i]
@@ -36,6 +36,25 @@
placeholder="输入重绘幅度"
/>
</n-form-item>
<n-form-item label="SD批次出图张数" style="margin-right: 30px">
<n-input-number
:min="0"
:max="30"
:step="1"
:default-value="1"
v-model:value="formValue.batch_size"
placeholder="SD批次出图张数"
/>
</n-form-item>
<n-form-item label="种子值" style="margin-right: 30px">
<n-input-number
:min="-1"
:step="1"
:default-value="-1"
v-model:value="formValue.seed"
placeholder="SD批次出图张数"
/>
</n-form-item>
<n-form-item label="重绘幅度" path="denoising_strength">
<n-input-number
:precision="2"
+291 -318
View File
@@ -71,6 +71,16 @@
>
</n-form-item>
</n-form-item>
<n-form-item path="image_setting" label="生图设置">
<n-form-item path="defaultImageMode" label="默认生图模式">
<n-select
v-model:value="formValue.defaultImageMode"
:options="defaultImageModeOptions"
placeholder="选择默认的生图模式"
style="width: 200px"
/>
</n-form-item>
</n-form-item>
<n-form-item path="gpt_setting" label="GPT设置">
<n-form-item path="gpt_business" label="GPT接口服务商">
<n-select
@@ -161,7 +171,7 @@
</NSpace>
</template>
<script>
<script setup>
import { ref, toRaw, onMounted, defineComponent, h } from 'vue'
import {
NForm,
@@ -183,337 +193,300 @@ import { FolderOpenSharp as FolderOpen } from '@vicons/ionicons5'
import AddGptPrompts from './Components/AddGptPrompts.vue'
import { isEmpty } from 'lodash'
import { useSoftwareStore } from '../../../../stores/software'
import { TranslateAPIType } from '../../../../define/enum/translate'
import TranslateSetting from './TranslateSetting.vue'
import { LaiAPIType } from '../../../../define/enum/softwareEnum'
export default defineComponent({
components: {
NForm,
NFormItem,
NInput,
NInputNumber,
NButton,
NSpace,
NSpin,
NSelect,
NCheckbox,
NSwitch,
FolderOpen,
NIcon
let formRef = ref(null)
let softwareStore = useSoftwareStore()
let message = useMessage()
let formValue = ref({
draft_path: window.config.draft_path,
project_path: window.config.project_path,
project_name: window.config.project_name,
gpt_business: window.config.gpt_business,
gpt_key: window.config.gpt_key,
gpt_model: window.config.gpt_model,
gpt_count: window.config.gpt_count,
task_number: window.config.task_number,
translation_business: window.config.translation_business,
translation_app_id: window.config.translation_app_id,
translation_secret: window.config.translation_secret,
translation_auto: window.config.translation_auto,
theme: softwareStore.globalSetting.theme,
character_select_model: window.config.character_select_model,
window_wh_bm_remember: window.config.window_wh_bm_remember,
laiApiSelect: window.config.laiApiSelect ? window.config.laiApiSelect : LaiAPIType.MAIN,
hdScale: window.config.hdScale ?? 2,
defaultImageMode: window.config.defaultImageMode ?? 'mj'
})
let show = ref(false)
let gpt_options = ref([])
let gpt_model_options = ref([])
let character_select_model_options = ref([])
let hdSelectOptions = ref([
{
label: '2倍',
value: 2
},
setup() {
let formRef = ref(null)
let softwareStore = useSoftwareStore()
let message = useMessage()
let formValue = ref({
draft_path: window.config.draft_path,
project_path: window.config.project_path,
project_name: window.config.project_name,
gpt_business: window.config.gpt_business,
gpt_key: window.config.gpt_key,
gpt_model: window.config.gpt_model,
gpt_count: window.config.gpt_count,
task_number: window.config.task_number,
translation_business: window.config.translation_business,
translation_app_id: window.config.translation_app_id,
translation_secret: window.config.translation_secret,
translation_auto: window.config.translation_auto,
theme: softwareStore.globalSetting.theme,
character_select_model: window.config.character_select_model,
window_wh_bm_remember: window.config.window_wh_bm_remember,
laiApiSelect: window.config.laiApiSelect ? window.config.laiApiSelect : LaiAPIType.MAIN,
hdScale: window.config.hdScale ?? 2
})
let show = ref(false)
let gpt_options = ref([])
let gpt_model_options = ref([])
let character_select_model_options = ref([])
let hdSelectOptions = ref([
{
label: '2倍',
value: 2
{
label: '3倍',
value: 3
},
{
label: '4倍',
value: 4
}
])
let dialog = useDialog()
let loading = ref(false)
let defaultImageModeOptions = ref([])
/**
* 加载GPT的配置信息
*/
async function InitGptOptions() {
await window.api.getGptBusinessOption('all', (value) => {
if (value.code == 0) {
message.error(value.message)
return
}
gpt_options.value = value.data.filter((item) => item.gpt_url)
})
await window.api.getGptModelOption('all', (value) => {
if (value.code == 0) {
message.error(value.message)
return
}
gpt_model_options.value = value.data
})
await window.mj.GetTagSelectModel((value) => {
character_select_model_options.value = value.data
})
}
onMounted(async () => {
await InitGptOptions()
// 获取生图下拉列表的方式
await window.api.GetImageGenerateCategory((value) => {
if (value.code == 0) {
message.error(value.message)
return
}
defaultImageModeOptions.value = value.data
})
})
// 切换翻译服务商事件
function SwitchTranslate(value, option) {
// 将之前的数据全部删除
formValue.value.translation_app_id = null
formValue.value.translation_secret = null
}
let ruleObj = (errorMessage) => {
return [
{
required: true,
validator(rule, value) {
if (value == null || value == '') return new Error(errorMessage)
return true
},
{
label: '3倍',
value: 3
},
{
label: '4倍',
value: 4
}
])
let dialog = useDialog()
let loading = ref(false)
/**
* 加载GPT的配置信息
*/
async function InitGptOptions() {
await window.api.getGptBusinessOption('all', (value) => {
if (value.code == 0) {
message.error(value.message)
return
}
gpt_options.value = value.data.filter((item) => item.gpt_url)
})
await window.api.getGptModelOption('all', (value) => {
if (value.code == 0) {
message.error(value.message)
return
}
gpt_model_options.value = value.data
})
await window.mj.GetTagSelectModel((value) => {
character_select_model_options.value = value.data
})
trigger: ['input', 'blur', 'change']
}
]
}
onMounted(async () => {
await InitGptOptions()
let rules = {
draft_path: ruleObj('必填剪映草稿地址'),
project_path: ruleObj('必填项目地址'),
project_name: ruleObj('必填项目名称'),
task_number: ruleObj('必填后台并行任务数'),
gpt_business: ruleObj('必填GPT接口服务商'),
gpt_key: ruleObj('必填GPT Key'),
gpt_model: ruleObj('必填GPT模型'),
gpt_count: ruleObj('必填自动推理上下文行数'),
translation_secret: ruleObj('必填产品密钥'),
translation_app_id: ruleObj('必填APP ID'),
translation_business: ruleObj('必填翻译服务商')
}
/**
* 保存配置信息
*/
async function handleValidateButtonClick(e) {
e.preventDefault()
formRef.value?.validate(async (errors) => {
if (errors) {
message.error('请检查必填字段')
return
}
// 同步修改下数据库文件
let saveRes = await window.setting.SaveSoftWareSetting({
globalSetting: JSON.stringify(toRaw(formValue.value))
})
// 切换翻译服务商事件
function SwitchTranslate(value, option) {
// 将之前的数据全部删除
formValue.value.translation_app_id = null
formValue.value.translation_secret = null
if (saveRes.code == 0) {
message.error(saveRes.message)
return
}
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 = {
draft_path: ruleObj('必填剪映草稿地址'),
project_path: ruleObj('必填项目地址'),
project_name: ruleObj('必填项目名称'),
task_number: ruleObj('必填后台并行任务数'),
gpt_business: ruleObj('必填GPT接口服务商'),
gpt_key: ruleObj('必填GPT Key'),
gpt_model: ruleObj('必填GPT模型'),
gpt_count: ruleObj('必填自动推理上下文行数'),
translation_secret: ruleObj('必填产品密钥'),
translation_app_id: ruleObj('必填APP ID'),
translation_business: ruleObj('必填翻译服务商')
}
/**
* 保存配置信息
*/
async function handleValidateButtonClick(e) {
e.preventDefault()
formRef.value?.validate(async (errors) => {
if (errors) {
message.error('请检查必填字段')
return
}
// 同步修改下数据库文件
let saveRes = await window.setting.SaveSoftWareSetting({
globalSetting: JSON.stringify(toRaw(formValue.value))
softwareStore.globalSetting = toRaw(formValue.value)
// 保存文件
window.api.ModifySampleSetting(JSON.stringify(toRaw(formValue.value)), (value) => {
if (value.code == 1) {
window.api.getSettingDafultData((value) => {
window.config = value
})
if (saveRes.code == 0) {
message.error(saveRes.message)
return
}
softwareStore.globalSetting = toRaw(formValue.value)
// 保存文件
window.api.ModifySampleSetting(JSON.stringify(toRaw(formValue.value)), (value) => {
if (value.code == 1) {
window.api.getSettingDafultData((value) => {
window.config = value
})
window.api.showGlobalMessageDialog({ code: 1, message: value.message })
} else {
window.api.showGlobalMessageDialog({ code: 0, message: value.message })
}
})
softwareStore.SetSoftware({ theme: formValue.value.theme })
})
}
let railStyle = (focused, checked) => {
const style = {}
if (checked) {
style.background = '#f3a694'
if (focused) {
style.boxShadow = '0 0 0 2px #f3a694'
}
window.api.showGlobalMessageDialog({ code: 1, message: value.message })
} else {
style.background = '#775039'
if (focused) {
style.boxShadow = '0 0 0 2px #775039'
}
window.api.showGlobalMessageDialog({ code: 0, message: value.message })
}
return style
}
})
softwareStore.SetSoftware({ theme: formValue.value.theme })
})
}
/**
* 打开购买GPT的地址
*/
async function openGptBuyUrl() {
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)
}
let railStyle = (focused, checked) => {
const style = {}
if (checked) {
style.background = '#f3a694'
if (focused) {
style.boxShadow = '0 0 0 2px #f3a694'
}
/**
* 切换主题
* @param {*} value 主题名称
*/
async function ChangeMode(value) {
console.log(value)
const isDarkMode = await window.darkMode.toggle(value)
}
/**
* 添加GPT地址或者模型
*/
async function addGptOption() {
// 判断当前数据是不是存在
// 处理数据。获取当前的所有的数据
let dialogWidth = 600
let dialogHeight = 450
// ImportWordAndSrt
dialog.create({
showIcon: false,
closeOnEsc: false,
title: '添加GPT地址或者模型',
content: () => h(AddGptOption, {}),
style: `width : ${dialogWidth}px; min-height : ${dialogHeight}px`,
maskClosable: false,
onClose: async () => {
// 刷新界面数据
await InitGptOptions()
}
})
}
/**
* 测试当前GPT是不是可以链接成功
*/
async function TestGPTConnection() {
loading.value = true
// 测试链接
await window.api.TestGPTConnection(JSON.stringify(formValue.value), (value) => {
loading.value = false
if (value.code == 0) {
window.api.showGlobalMessageDialog({
code: 0,
message: 'GPT链接失败,错误信息: ' + value.message
})
return
}
window.api.showGlobalMessageDialog({ code: 1, message: 'gpt链接测试成功,可以正常使用!' })
})
}
/**
* 选择项目文件夹
*/
async function SelectProjectFolder() {
await window.api.selectFolder(
{ default_paht: toRaw(formValue.value).project_path },
(value) => {
if (value.length > 0) {
formValue.value.project_path = value[0]
}
}
)
}
/**
* 添加GPT提示词预设
*/
async function AddGptPrompt() {
// 判断当前数据是不是存在
// 处理数据。获取当前的所有的数据
let dialogWidth = 600
let dialogHeight = window.innerHeight * 0.9
// ImportWordAndSrt
dialog.create({
showIcon: false,
closeOnEsc: false,
title: '添加GPT提示词预设',
content: () => h(AddGptPrompts, { height: dialogHeight }),
style: `width : ${dialogWidth}px; height : ${dialogHeight}px; padding-right : 3px `,
maskClosable: false,
onClose: () => {}
})
}
/**
* 进行翻译设置
*/
async function ModifyTranslateSetting() {
// 判断当前数据是不是存在
// 处理数据。获取当前的所有的数据
let dialogWidth = window.innerWidth * 0.8
let dialogHeight = window.innerHeight * 0.9
// ImportWordAndSrt
dialog.create({
showIcon: false,
title: '翻译设置',
content: () => h(TranslateSetting, { height: dialogHeight }),
style: `width : ${dialogWidth}px; height : ${dialogHeight}px`,
maskClosable: false
})
}
return {
formRef,
ChangeMode,
openGptBuyUrl,
railStyle,
handleValidateButtonClick,
rules,
SwitchTranslate,
gpt_model_options,
gpt_options,
show,
formValue,
addGptOption,
TestGPTConnection,
loading,
SelectProjectFolder,
AddGptPrompt,
character_select_model_options,
softwareStore,
hdSelectOptions,
ModifyTranslateSetting,
laiApiOptions: [
{
label: '主站点',
value: LaiAPIType.MAIN
},
{
label: '香港站点',
value: LaiAPIType.HK_PROXY
},
{
label: '备用主站点',
value: LaiAPIType.BAK_MAIN
}
]
} else {
style.background = '#775039'
if (focused) {
style.boxShadow = '0 0 0 2px #775039'
}
}
})
return style
}
/**
* 打开购买GPT的地址
*/
async function openGptBuyUrl() {
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)
}
}
/**
* 切换主题
* @param {*} value 主题名称
*/
async function ChangeMode(value) {
console.log(value)
const isDarkMode = await window.darkMode.toggle(value)
}
/**
* 添加GPT地址或者模型
*/
async function addGptOption() {
// 判断当前数据是不是存在
// 处理数据。获取当前的所有的数据
let dialogWidth = 600
let dialogHeight = 450
dialog.create({
showIcon: false,
closeOnEsc: false,
title: '添加GPT地址或者模型',
content: () => h(AddGptOption, {}),
style: `width : ${dialogWidth}px; min-height : ${dialogHeight}px`,
maskClosable: false,
onClose: async () => {
// 刷新界面数据
await InitGptOptions()
}
})
}
/**
* 测试当前GPT是不是可以链接成功
*/
async function TestGPTConnection() {
loading.value = true
// 测试链接
await window.api.TestGPTConnection(JSON.stringify(formValue.value), (value) => {
loading.value = false
if (value.code == 0) {
window.api.showGlobalMessageDialog({
code: 0,
message: 'GPT链接失败,错误信息: ' + value.message
})
return
}
window.api.showGlobalMessageDialog({ code: 1, message: 'gpt链接测试成功,可以正常使用!' })
})
}
/**
* 选择项目文件夹
*/
async function SelectProjectFolder() {
await window.api.selectFolder({ default_paht: toRaw(formValue.value).project_path }, (value) => {
if (value.length > 0) {
formValue.value.project_path = value[0]
}
})
}
/**
* 添加GPT提示词预设
*/
async function AddGptPrompt() {
// 判断当前数据是不是存在
// 处理数据。获取当前的所有的数据
let dialogWidth = 600
let dialogHeight = window.innerHeight * 0.9
dialog.create({
showIcon: false,
closeOnEsc: false,
title: '添加GPT提示词预设',
content: () => h(AddGptPrompts, { height: dialogHeight }),
style: `width : ${dialogWidth}px; height : ${dialogHeight}px; padding-right : 3px `,
maskClosable: false,
onClose: () => {}
})
}
/**
* 进行翻译设置
*/
async function ModifyTranslateSetting() {
// 判断当前数据是不是存在
// 处理数据。获取当前的所有的数据
let dialogWidth = window.innerWidth * 0.8
let dialogHeight = window.innerHeight * 0.9
dialog.create({
showIcon: false,
title: '翻译设置',
content: () => h(TranslateSetting, { height: dialogHeight }),
style: `width : ${dialogWidth}px; height : ${dialogHeight}px`,
maskClosable: false
})
}
let laiApiOptions = [
{
label: '主站点',
value: LaiAPIType.MAIN
},
{
label: '香港站点',
value: LaiAPIType.HK_PROXY
},
{
label: '备用主站点',
value: LaiAPIType.BAK_MAIN
}
]
</script>