Laitool v3.0.1-preview.1
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<n-message-provider>
|
||||
<n-dialog-provider>
|
||||
<n-notification-provider>
|
||||
<n-spin :show="softwareStore.spin.spinning">
|
||||
<n-spin style="z-index: 100;" :show="softwareStore.spin.spinning">
|
||||
<RouterView></RouterView>
|
||||
<template #description> {{ softwareStore.spin.tip }} </template>
|
||||
</n-spin>
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
<script>
|
||||
import { defineComponent, ref, onMounted, toRaw } from "vue";
|
||||
import { NButton, useMessage, NSpin, NSpace, NSelect, NDivider, NInput, NCode, NCard, NCheckbox, NGradientText, NFormItem, NForm, NInputNumber, NTooltip, NDropdown } from "naive-ui"
|
||||
import { DEFINE_STRING } from "../../../../define/define_string.js"
|
||||
import { DEFINE_STRING } from "../../../../define/define_string"
|
||||
import { isEmpty, isNull } from "lodash";
|
||||
export default defineComponent({
|
||||
components: {
|
||||
|
||||
@@ -85,7 +85,7 @@ import {
|
||||
NSlider,
|
||||
NInput
|
||||
} from 'naive-ui'
|
||||
import { DEFINE_STRING } from '../../../../define/define_string.js'
|
||||
import { DEFINE_STRING } from '../../../../define/define_string'
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NSelect,
|
||||
|
||||
@@ -59,7 +59,7 @@ import {
|
||||
NPopover,
|
||||
NImage
|
||||
} from 'naive-ui'
|
||||
import { DEFINE_STRING } from '../../../../define/define_string.js'
|
||||
import { DEFINE_STRING } from '../../../../define/define_string'
|
||||
import SelectImageStyle from '../Components/SelectImageStyle.vue'
|
||||
import ShowImageTag from '../Components/ShowImageTag.vue'
|
||||
import BatchSaveImageSetting from './BatchSaveImageSetting.vue'
|
||||
@@ -317,7 +317,7 @@ export default defineComponent({
|
||||
|
||||
if (row.status == 'ok' || row.status.startsWith('video')) {
|
||||
dialog.warning({
|
||||
title: '确认',
|
||||
title: '确认删除',
|
||||
content: '确定删除?会将生成的图全部删除!',
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
|
||||
+45
-21
@@ -2,19 +2,19 @@
|
||||
<div style="margin: 30px 30px 30px 0">
|
||||
<n-form
|
||||
ref="bookRef"
|
||||
:model="data"
|
||||
:model="reverseManageStore.selectBook"
|
||||
:rules="rules"
|
||||
label-placement="left"
|
||||
label-width="auto"
|
||||
require-mark-placement="right-hanging"
|
||||
>
|
||||
<n-form-item label="书名" path="name">
|
||||
<n-input v-model:value="data.name" placeholder="请输入书名" />
|
||||
<n-input v-model:value="reverseManageStore.selectBook.name" placeholder="请输入书名" />
|
||||
</n-form-item>
|
||||
<n-form-item label="视频文件" path="oldVideoPath">
|
||||
<n-input
|
||||
disabled="true"
|
||||
v-model:value="data.oldVideoPath"
|
||||
v-model:value="reverseManageStore.selectBook.oldVideoPath"
|
||||
placeholder="请选择反推的视频文件"
|
||||
clearable
|
||||
>
|
||||
@@ -32,7 +32,7 @@
|
||||
</n-form-item>
|
||||
<n-form-item label="小说类型" path="type">
|
||||
<n-select
|
||||
v-model:value="data.type"
|
||||
v-model:value="reverseManageStore.selectBook.type"
|
||||
:disabled="reverseManageStore.selectBook.id != null"
|
||||
:options="reverseManageStore.bookType"
|
||||
style="width: 200px"
|
||||
@@ -41,7 +41,7 @@
|
||||
</n-form-item>
|
||||
<n-form-item label="配音地址" path="audioPath">
|
||||
<n-input
|
||||
v-model:value="data.audioPath"
|
||||
v-model:value="reverseManageStore.selectBook.audioPath"
|
||||
disabled="true"
|
||||
placeholder="没有选择的话则使用原视频的"
|
||||
>
|
||||
@@ -58,7 +58,7 @@
|
||||
</n-form-item>
|
||||
<n-form-item label="SRT地址" path="srtPath">
|
||||
<n-input
|
||||
v-model:value="data.srtPath"
|
||||
v-model:value="reverseManageStore.selectBook.srtPath"
|
||||
disabled="true"
|
||||
placeholder="没有选择的话则使用原视频的"
|
||||
>
|
||||
@@ -73,9 +73,12 @@
|
||||
>选择SRT</n-button
|
||||
>
|
||||
</n-form-item>
|
||||
<n-form-item label="背景音乐" path="srtPath">
|
||||
<n-select v-model:value="reverseManageStore.selectBook.backgroundMusic" :options="backgroundMusicOptions" placeholder="请选择背景音乐"> </n-select>
|
||||
</n-form-item>
|
||||
<n-form-item label="小说项目文件夹" path="bookFolderPath">
|
||||
<n-input
|
||||
v-model:value="data.bookFolderPath"
|
||||
v-model:value="reverseManageStore.selectBook.bookFolderPath"
|
||||
disabled="true"
|
||||
placeholder="不用选择,添加小说自动生成"
|
||||
>
|
||||
@@ -86,7 +89,7 @@
|
||||
</n-form-item>
|
||||
<n-form-item label="图片输出文件夹" path="imageFolder">
|
||||
<n-input
|
||||
v-model:value="data.imageFolder"
|
||||
v-model:value="reverseManageStore.selectBook.imageFolder"
|
||||
disabled="true"
|
||||
placeholder="不用选择,添加小说自动生成"
|
||||
>
|
||||
@@ -96,7 +99,9 @@
|
||||
>
|
||||
</n-form-item>
|
||||
<div style="margin-left: 10px; display: flex; justify-content: flex-end">
|
||||
<n-button type="success" @click="AddOrModifyBook">添加</n-button>
|
||||
<n-button type="success" @click="AddOrModifyBook">{{
|
||||
type == 'add' ? '添加' : '保存'
|
||||
}}</n-button>
|
||||
</div>
|
||||
</n-form>
|
||||
</div>
|
||||
@@ -105,7 +110,7 @@
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NButton, NForm, NFormItem, NInput, NSelect, NIcon } from 'naive-ui'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage.js'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage.ts'
|
||||
import { CloseSharp } from '@vicons/ionicons5'
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
@@ -119,12 +124,14 @@ export default defineComponent({
|
||||
NIcon,
|
||||
CloseSharp
|
||||
},
|
||||
|
||||
setup() {
|
||||
props: ['type'],
|
||||
setup(props) {
|
||||
let message = useMessage()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let bookRef = ref(null)
|
||||
let data = ref(cloneDeep(reverseManageStore.selectBook))
|
||||
let backgroundMusicOptions = ref([])
|
||||
// let data = ref(reverseManageStore.selectBook)
|
||||
let type = ref(props.type ? props.type : 'add')
|
||||
onMounted(async () => {
|
||||
// 初始化小说类型
|
||||
let res = await reverseManageStore.SetBookType()
|
||||
@@ -132,6 +139,22 @@ export default defineComponent({
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取初始化的背景音乐列表
|
||||
await window.api.GetBackgroundMusicConfigList((value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
for (let i = 0; i < value.value.length; i++) {
|
||||
const element = value.value[i]
|
||||
let obj = {
|
||||
label: element.name,
|
||||
value: element.id
|
||||
}
|
||||
backgroundMusicOptions.value.push(obj)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
@@ -156,11 +179,11 @@ export default defineComponent({
|
||||
return
|
||||
}
|
||||
if (propertyName == 'oldVideoPath') {
|
||||
data.value.oldVideoPath = value.value
|
||||
reverseManageStore.selectBook.oldVideoPath = value.value
|
||||
} else if (propertyName == 'audioPath') {
|
||||
data.value.UpdateSelectBook = value.value
|
||||
reverseManageStore.selectBook.audioPath = value.value
|
||||
} else if (propertyName == 'srtPath') {
|
||||
data.value.srtPath = value.value
|
||||
reverseManageStore.selectBook.srtPath = value.value
|
||||
} else {
|
||||
message.error('没有找到对应的属性')
|
||||
}
|
||||
@@ -197,14 +220,14 @@ export default defineComponent({
|
||||
return
|
||||
}
|
||||
debugger
|
||||
let res = await reverseManageStore.SaveSelectBook(toRaw(data.value))
|
||||
let res = await reverseManageStore.SaveSelectBook(cloneDeep(reverseManageStore.selectBook))
|
||||
// 判断当前的数据是不是有ID
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
message.success('添加/修改成功')
|
||||
data.value = reverseManageStore.selectBook
|
||||
reverseManageStore.selectBook = reverseManageStore.selectBook
|
||||
})
|
||||
}
|
||||
|
||||
@@ -230,12 +253,12 @@ export default defineComponent({
|
||||
debugger
|
||||
if (param == 'imageFolder') {
|
||||
res = await window.system.OpenFolder({
|
||||
folderPath: data.value.imageFolder,
|
||||
folderPath: reverseManageStore.selectBook.imageFolder,
|
||||
baseProject: false
|
||||
})
|
||||
} else if (param == 'bookFolderPath') {
|
||||
res = await window.system.OpenFolder({
|
||||
folderPath: data.value.bookFolderPath,
|
||||
folderPath: reverseManageStore.selectBook.bookFolderPath,
|
||||
baseProject: false
|
||||
})
|
||||
} else {
|
||||
@@ -251,12 +274,13 @@ export default defineComponent({
|
||||
return {
|
||||
reverseManageStore,
|
||||
rules,
|
||||
type,
|
||||
ClearInputData,
|
||||
SelectMP4File,
|
||||
AddOrModifyBook,
|
||||
bookRef,
|
||||
OpenFolder,
|
||||
data
|
||||
backgroundMusicOptions
|
||||
}
|
||||
}
|
||||
})
|
||||
+4
-6
@@ -37,10 +37,10 @@
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, h, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NButton, useDialog } from 'naive-ui'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage.ts'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import { BookType } from '../../../../../define/enum/bookEnum'
|
||||
import AddBook from './AddBook.vue'
|
||||
import AddBook from '../Components/AddBook.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@@ -63,17 +63,15 @@ export default defineComponent({
|
||||
async function EditBook(e) {
|
||||
e.stopPropagation()
|
||||
// 修改选中的数据
|
||||
debugger
|
||||
reverseManageStore.SetSelectBook(toRaw(book.value))
|
||||
|
||||
// 一个弹窗添加数据
|
||||
let dialogWidth = 600
|
||||
// ImportWordAndSrt
|
||||
dialog.create({
|
||||
showIcon: false,
|
||||
closeOnEsc: false,
|
||||
title: '新增小说',
|
||||
content: () => h(AddBook),
|
||||
title: '编辑小说',
|
||||
content: () => h(AddBook, { type: 'edit' }),
|
||||
style: `width : ${dialogWidth}px;`,
|
||||
maskClosable: false
|
||||
})
|
||||
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<n-button size="tiny" strong secondary type="primary" @click="HDImage">高清</n-button>
|
||||
<n-button size="tiny" strong secondary style="margin-left: 2px" type="info" @click="ClipDraft"
|
||||
>草稿</n-button
|
||||
>
|
||||
<n-button
|
||||
size="tiny"
|
||||
strong
|
||||
secondary
|
||||
style="margin-left: 2px"
|
||||
type="success"
|
||||
@click="GenerateVideo"
|
||||
>视频</n-button
|
||||
>
|
||||
|
||||
<n-button
|
||||
size="tiny"
|
||||
strong
|
||||
secondary
|
||||
style="margin-left: 2px"
|
||||
type="warning"
|
||||
@click="ReSetBookTaskDetail"
|
||||
>重置</n-button
|
||||
>
|
||||
<n-button
|
||||
size="tiny"
|
||||
style="margin-left: 2px"
|
||||
strong
|
||||
secondary
|
||||
@click="DeleteBookTask"
|
||||
type="error"
|
||||
>删除
|
||||
</n-button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, h, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NButton, useDialog } from 'naive-ui'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage.ts'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import { BookType, OperateBookType } from '../../../../../define/enum/bookEnum'
|
||||
import AddBook from '../Components/AddBook.vue'
|
||||
import { DEFINE_STRING } from '../../../../../define/define_string'
|
||||
import { ResponseMessageType } from '../../../../../define/enum/softwareEnum'
|
||||
import ManageBookTaskGenerateInformation from './ManageBookTaskGenerateInformation.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NButton
|
||||
},
|
||||
|
||||
props: ['bookTask'],
|
||||
setup(props) {
|
||||
let message = useMessage()
|
||||
let dialog = useDialog()
|
||||
let bookTask = ref(props.bookTask)
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let softwareStore = useSoftwareStore()
|
||||
|
||||
onMounted(async () => {})
|
||||
|
||||
/**
|
||||
* 重置小说数据
|
||||
* @param e
|
||||
*/
|
||||
async function ReSetBookTaskDetail(e) {
|
||||
debugger
|
||||
e.stopPropagation()
|
||||
dialog.warning({
|
||||
title: '重置小说任务',
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
content:
|
||||
'确定要重置小说任务吗?该操作不可逆,会将对应的批次任务的数据清空,分镜数据全部删除,请谨慎操作!',
|
||||
onPositiveClick: async () => {
|
||||
let res = await window.book.ReSetBookTask(bookTask.value.id)
|
||||
if (res.code == 1) {
|
||||
message.success('重置小说任务成功')
|
||||
} else {
|
||||
message.error(res.message)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除小说任务
|
||||
*/
|
||||
async function DeleteBookTask(e) {
|
||||
e.stopPropagation()
|
||||
dialog.warning({
|
||||
title: '删除小说任务',
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
content:
|
||||
'确定要删除小说任务吗?该操作不可逆,会将对应的批次任务数据和分镜数据全部删除,请谨慎操作!',
|
||||
onPositiveClick: async () => {
|
||||
let res = await window.book.DeleteBookTask(bookTask.value.id)
|
||||
if (res.code == 1) {
|
||||
// 加载任务列表
|
||||
let bookTaskRes = await reverseManageStore.GetBookTaskDataFromDB({
|
||||
bookId: reverseManageStore.selectBook.id
|
||||
})
|
||||
softwareStore.spin.spinning = false
|
||||
if (bookTaskRes.code == 0) {
|
||||
message.error(bookTaskRes.message)
|
||||
return
|
||||
}
|
||||
// 删除成功
|
||||
message.success('删除小说任务并刷新数据成功')
|
||||
} else {
|
||||
message.error(res.message)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function hdImageFunc(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 HDImage(e) {
|
||||
e.stopPropagation()
|
||||
softwareStore.spin.spinning = true
|
||||
softwareStore.spin.tip = '正在进行高清检查。。。'
|
||||
let checkImage = await window.book.CheckImageFileSize(
|
||||
bookTask.value.id,
|
||||
10240,
|
||||
OperateBookType.BOOKTASK
|
||||
)
|
||||
softwareStore.spin.spinning = false
|
||||
if (checkImage.code == 0) {
|
||||
message.error(checkImage.message)
|
||||
return
|
||||
}
|
||||
// 高清检查完成
|
||||
if (checkImage.data && checkImage.data.length > 0) {
|
||||
// 出现了图片大的,用户判断是不是需要高清
|
||||
let msg = checkImage.data.map((item, index) => {
|
||||
return item.outImagePath + '\n'
|
||||
})
|
||||
dialog.warning({
|
||||
title: '高清警告',
|
||||
content: '下面的图片大于10MB,是否继续高清?' + '\n' + msg,
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
maskClosable: false,
|
||||
onPositiveClick: async () => {
|
||||
alert('确认高清')
|
||||
await hdImageFunc(bookTask.value.id, OperateBookType.BOOKTASK)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 没有就直接高清
|
||||
await hdImageFunc(bookTask.value.id, OperateBookType.BOOKTASK)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成草稿
|
||||
*/
|
||||
async function ClipDraft(e) {
|
||||
e.stopPropagation()
|
||||
dialog.info({
|
||||
closeOnEsc: false,
|
||||
title: '生成草稿前检查',
|
||||
maskClosable: false,
|
||||
content: () =>
|
||||
h(ManageBookTaskGenerateInformation, { bookTask: bookTask.value, type: 'bookTask' })
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 合成视频
|
||||
*/
|
||||
async function GenerateVideo(e) {
|
||||
e.stopPropagation()
|
||||
alert('合成视频')
|
||||
}
|
||||
|
||||
return {
|
||||
bookTask,
|
||||
reverseManageStore,
|
||||
ClipDraft,
|
||||
GenerateVideo,
|
||||
softwareStore,
|
||||
ReSetBookTaskDetail,
|
||||
DeleteBookTask,
|
||||
HDImage
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<div v-if="show">
|
||||
<div v-for="(item, index) in data.subValue">
|
||||
<n-input
|
||||
v-model:value="item.srt_value"
|
||||
type="textarea"
|
||||
size="tiny"
|
||||
:autosize="{ minRows: 1, maxRows: 5 }"
|
||||
@input="InputDebounced"
|
||||
>
|
||||
</n-input>
|
||||
</div>
|
||||
</div>
|
||||
<n-input
|
||||
v-else
|
||||
v-model:value="data.afterGpt"
|
||||
type="textarea"
|
||||
size="tiny"
|
||||
:autosize="{ minRows: 6, maxRows: 6 }"
|
||||
@input="InputDebounced"
|
||||
>
|
||||
</n-input>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch, computed } from 'vue'
|
||||
import { useMessage, NInput } from 'naive-ui'
|
||||
import { debounce } from 'lodash'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NInput },
|
||||
props: ['initData', 'index'],
|
||||
setup(props) {
|
||||
let data = ref(props.initData)
|
||||
onMounted(async () => {})
|
||||
let show = computed(() => {
|
||||
debugger
|
||||
return data.value.subValue && data.value.subValue.length > 0
|
||||
})
|
||||
|
||||
let InputDebounced = debounce(handleInput, 1000)
|
||||
|
||||
async function handleInput() {
|
||||
console.log('开始修改')
|
||||
let res = await window.db.UpdateBookTaskDetailData(data.value.id, {
|
||||
afterGpt: data.value.afterGpt,
|
||||
word: data.value.afterGpt
|
||||
})
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
}
|
||||
}
|
||||
|
||||
return { data, InputDebounced, show }
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,276 @@
|
||||
<template>
|
||||
<div style="position: absolute; top: 0">
|
||||
<n-dropdown trigger="hover" :options="reverseOptions" @select="ReverseSelect">
|
||||
<n-button size="tiny" :color="softwareStore.SoftColor.BROWN_YELLOW" @click="AddReversePrompt">
|
||||
单句反推
|
||||
</n-button>
|
||||
</n-dropdown>
|
||||
<n-dropdown trigger="hover" :options="tranlateOptions" @select="ReverseSelect">
|
||||
<n-button
|
||||
style="margin-left: 5px"
|
||||
size="tiny"
|
||||
:color="softwareStore.SoftColor.BROWN_YELLOW"
|
||||
@click="TranslateOne('translate_chinese')"
|
||||
>
|
||||
英文 2 中文
|
||||
</n-button>
|
||||
</n-dropdown>
|
||||
|
||||
<n-button
|
||||
style="margin-left: 5px"
|
||||
size="tiny"
|
||||
:color="softwareStore.SoftColor.BROWN_YELLOW"
|
||||
@click="SelectReversePrompt"
|
||||
>
|
||||
重选反推提示词
|
||||
</n-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch, h } from 'vue'
|
||||
import { useMessage, useDialog, NDropdown, NButton } from 'naive-ui'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import { TranslateType } from '../../../../../define/enum/translate'
|
||||
import { ContainsChineseOrPunctuation } from '../../../../../define/Tools/common'
|
||||
import ReSelectReversePrompt from '../MJReverse/ReSelectReversePrompt.vue'
|
||||
import { isEmpty } from 'lodash'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NDropdown, NButton },
|
||||
props: ['initData', 'index'],
|
||||
setup(props) {
|
||||
let message = useMessage()
|
||||
let dialog = useDialog()
|
||||
let data = ref(props.initData)
|
||||
let index = ref(props.index)
|
||||
let softwareStore = useSoftwareStore()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
onMounted(async () => {})
|
||||
|
||||
/**
|
||||
* 单句反推提示词
|
||||
*/
|
||||
async function AddReversePrompt() {
|
||||
let res = await window.book.AddReversePrompt([data.value.id], null)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
} else {
|
||||
message.success('添加反推任务成功')
|
||||
}
|
||||
}
|
||||
|
||||
async function AddNextReversePrompt() {
|
||||
let res = await window.book.AddReversePrompt(
|
||||
[data.value.id],
|
||||
reverseManageStore.selectBook.type
|
||||
)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
} else {
|
||||
message.success('添加反推任务成功')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 提示词菜单下拉操作
|
||||
*/
|
||||
async function ReverseSelect(key) {
|
||||
debugger
|
||||
switch (key) {
|
||||
case 'remove_reverse': // 删除反推提示词
|
||||
let res = await window.book.RemoveReverseData([data.value.id])
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
} else {
|
||||
reverseManageStore.selectBookTaskDetail[props.index].reversePrompt = undefined
|
||||
message.success('删除反推数据成功')
|
||||
}
|
||||
break
|
||||
case 'translate_english': // 中文 2 英文
|
||||
await TranslateOne('translate_english')
|
||||
break
|
||||
|
||||
case 'down_translate_chinese': // 下翻译中文
|
||||
await TranslateOne('down_translate_chinese')
|
||||
break
|
||||
case 'down_translate_english': // 下翻译英文
|
||||
await TranslateOne('down_translate_english')
|
||||
break
|
||||
case 'down_reverse':
|
||||
await AddNextReversePrompt()
|
||||
break
|
||||
default:
|
||||
message.error('未知的操作类型')
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 处理翻译英文的数据
|
||||
function TranslateOneParams(from, to) {
|
||||
let translateData = []
|
||||
// if (!isEmpty(data.value.prompt)) {
|
||||
// translateData.push({
|
||||
// text: item.prompt,
|
||||
// from: from,
|
||||
// to: to,
|
||||
// type: TranslateType.PROMPT_TRANSLATE,
|
||||
// isSplit: false, // 该参数设置为true时,会将文本按照标点符号分割成多个句子进行翻译
|
||||
// bookTaskDetailId: data.value.id
|
||||
// })
|
||||
// } else {
|
||||
let reversePrompt = data.value.reversePrompt
|
||||
if (reversePrompt) {
|
||||
reversePrompt.forEach((item) => {
|
||||
let temp_obj = undefined
|
||||
if (from == 'zh' && to == 'en') {
|
||||
// 判断是不是有中文
|
||||
if (!ContainsChineseOrPunctuation(item.promptCN ? item.promptCN : item.prompt)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
temp_obj = {
|
||||
text: item.prompt,
|
||||
from: from,
|
||||
to: to,
|
||||
type: TranslateType.REVERSE_PROMPT_TRANSLATE,
|
||||
isSplit: false, // 该参数设置为true时,会将文本按照标点符号分割成多个句子进行翻译
|
||||
bookTaskDetailId: data.value.id,
|
||||
reversePromptId: item.id
|
||||
}
|
||||
|
||||
translateData.push(temp_obj)
|
||||
})
|
||||
}
|
||||
// }
|
||||
return translateData
|
||||
}
|
||||
|
||||
// 处理批次的翻译
|
||||
function TranslateBatchParams(from, to) {
|
||||
let translateData = []
|
||||
for (let i = index.value; i < reverseManageStore.selectBookTaskDetail.length; i++) {
|
||||
const element = reverseManageStore.selectBookTaskDetail[i]
|
||||
let reversePrompt = element.reversePrompt
|
||||
if (reversePrompt) {
|
||||
reversePrompt.forEach((item) => {
|
||||
if (from == 'zh' && to == 'en') {
|
||||
// 判断是不是有中文
|
||||
if (!ContainsChineseOrPunctuation(item.promptCN ? item.promptCN : item.prompt)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
let temp_obj = {
|
||||
text: item.prompt,
|
||||
from: from,
|
||||
to: to,
|
||||
type: TranslateType.REVERSE_PROMPT_TRANSLATE,
|
||||
isSplit: false, // 该参数设置为true时,会将文本按照标点符号分割成多个句子进行翻译
|
||||
bookTaskDetailId: element.id,
|
||||
reversePromptId: item.id
|
||||
}
|
||||
translateData.push(temp_obj)
|
||||
})
|
||||
}
|
||||
}
|
||||
return translateData
|
||||
}
|
||||
|
||||
// 单句翻译
|
||||
async function TranslateOne(key) {
|
||||
debugger
|
||||
let translateData = []
|
||||
switch (key) {
|
||||
case 'translate_english':
|
||||
translateData = TranslateOneParams('zh', 'en')
|
||||
break
|
||||
case 'translate_chinese':
|
||||
translateData = TranslateOneParams('en', 'zh')
|
||||
break
|
||||
case 'down_translate_english':
|
||||
translateData = TranslateBatchParams('zh', 'en')
|
||||
break
|
||||
case 'down_translate_chinese':
|
||||
translateData = TranslateBatchParams('en', 'zh')
|
||||
break
|
||||
default:
|
||||
message.error('未知的操作类型')
|
||||
break
|
||||
}
|
||||
if (translateData.length <= 0) {
|
||||
message.error('没有需要翻译的数据')
|
||||
return
|
||||
}
|
||||
softwareStore.spin.spinning = true
|
||||
softwareStore.spin.tip = `翻译中 ... 0 / ${translateData.length}`
|
||||
// 开始翻译
|
||||
let res = await window.translate.TranslateNowReturn(translateData)
|
||||
softwareStore.spin.spinning = false
|
||||
window.api.showGlobalMessageDialog(res)
|
||||
}
|
||||
|
||||
/**
|
||||
* 重选反推提示词
|
||||
*/
|
||||
async function SelectReversePrompt() {
|
||||
debugger
|
||||
// 判断当前是不是又反推提示词
|
||||
if (!data.value.reversePrompt || data.value.reversePrompt.length <= 0) {
|
||||
message.error('当前没有反推提示词')
|
||||
return
|
||||
}
|
||||
|
||||
// ImportWordAndSrt
|
||||
dialog.create({
|
||||
showIcon: false,
|
||||
title: `重选MJ反推提示词 ${data.value.name}`,
|
||||
closeOnEsc: false,
|
||||
content: () =>
|
||||
h(ReSelectReversePrompt, {
|
||||
reversePrompts: data.value.reversePrompt,
|
||||
index: index.value
|
||||
}),
|
||||
style: `width : 750px;`,
|
||||
maskClosable: false
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
index,
|
||||
data,
|
||||
softwareStore,
|
||||
ReverseSelect,
|
||||
TranslateOne,
|
||||
reverseManageStore,
|
||||
SelectReversePrompt,
|
||||
AddReversePrompt,
|
||||
reverseOptions: [
|
||||
{
|
||||
label: '下推理',
|
||||
key: 'down_reverse'
|
||||
},
|
||||
{
|
||||
label: '删除反推提示词',
|
||||
key: 'remove_reverse'
|
||||
}
|
||||
],
|
||||
tranlateOptions: [
|
||||
{
|
||||
label: '中文 2 英文',
|
||||
key: 'translate_english'
|
||||
},
|
||||
{
|
||||
label: '下翻译英文',
|
||||
key: 'down_translate_english'
|
||||
},
|
||||
{
|
||||
label: '下翻译中文',
|
||||
key: 'down_translate_chinese'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,128 @@
|
||||
<template>
|
||||
<div style="display: flex">
|
||||
<div>反推/GPT提示词</div>
|
||||
<n-button
|
||||
v-if="reverseManageStore.selectBook.type == bookType.MJ_REVERSE"
|
||||
type="text"
|
||||
:color="softwareStore.SoftColor.ZHUYANTUO"
|
||||
size="tiny"
|
||||
style="margin-left: 10px"
|
||||
@click="SelectPromptIndex"
|
||||
>选择提示词</n-button
|
||||
><n-button
|
||||
v-if="reverseManageStore.selectBook.type == bookType.MJ_REVERSE"
|
||||
type="text"
|
||||
:color="softwareStore.SoftColor.ZHUYANTUO"
|
||||
size="tiny"
|
||||
style="margin-left: 5px"
|
||||
@click="SelectStyle"
|
||||
>风格</n-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, h, watch } from 'vue'
|
||||
import { useMessage, useDialog, NButton } from 'naive-ui'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import { BookType } from '../../../../../define/enum/bookEnum'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import SelectMJReversePrompt from '../MJReverse/SelectMJReversePrompt.vue'
|
||||
import SelectImageStyle from '../../Components/SelectImageStyle.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NButton },
|
||||
|
||||
setup() {
|
||||
let message = useMessage()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let softwareStore = useSoftwareStore()
|
||||
let bookType = ref(BookType)
|
||||
let dialog = useDialog()
|
||||
let selectStyleRef = ref(null)
|
||||
onMounted(async () => {})
|
||||
|
||||
/**
|
||||
* 选择MJ反推提示词。用于生图
|
||||
*/
|
||||
async function SelectPromptIndex() {
|
||||
// 判断是不是MJ反推,判断是不是所有的都有提示词
|
||||
if (reverseManageStore.selectBook.type != BookType.MJ_REVERSE) {
|
||||
message.error('只有MJ反推可以使用该按钮')
|
||||
return
|
||||
}
|
||||
let hasReversePrompt = false
|
||||
// 判断是不是所有的都有提示词,只要有一个有,就可以
|
||||
for (let index = 0; index < reverseManageStore.selectBookTaskDetail.length; index++) {
|
||||
const element = reverseManageStore.selectBookTaskDetail[index]
|
||||
if (element.reversePrompt && element.reversePrompt.length > 0) {
|
||||
hasReversePrompt = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!hasReversePrompt) {
|
||||
message.error('请先进行MJ反推')
|
||||
return
|
||||
}
|
||||
dialog.create({
|
||||
title: '选择反推提示词',
|
||||
content: () => h(SelectMJReversePrompt),
|
||||
style: 'width : 500px',
|
||||
showIcon: false
|
||||
})
|
||||
}
|
||||
|
||||
// 选择风格
|
||||
async function SelectStyle() {
|
||||
debugger
|
||||
// 先获取风格
|
||||
// 判断当前数据是不是存在
|
||||
// 处理数据。获取当前的所有的数据
|
||||
let dialogWidth = window.innerWidth * 0.8
|
||||
let dialogHeight = window.innerHeight * 0.9
|
||||
// ImportWordAndSrt
|
||||
dialog.create({
|
||||
showIcon: false,
|
||||
closeOnEsc: false,
|
||||
content: () =>
|
||||
h(SelectImageStyle, {
|
||||
height: dialogHeight,
|
||||
ref: selectStyleRef,
|
||||
imageStyle: reverseManageStore.selectBookTask.imageStyle,
|
||||
customizeImageStyle: reverseManageStore.selectBookTask.customizeImageStyle
|
||||
}),
|
||||
style: `width : ${dialogWidth}px; height : ${dialogHeight}px`,
|
||||
maskClosable: false,
|
||||
onClose: async () => {
|
||||
debugger
|
||||
console.log(selectStyleRef)
|
||||
// 将数据保存到当前的数据中
|
||||
// reverseManageStore.selectBookTask.styleList = toRaw(selectStyleRef.value.selectStyle)
|
||||
|
||||
// 保存当前的风格到数据库
|
||||
let res = await window.book.SaveImageStyle(
|
||||
toRaw(selectStyleRef.value.selectStyle),
|
||||
reverseManageStore.selectBookTask.id
|
||||
)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
reverseManageStore.selectBookTask.imageStyle = res.data.imageStyle
|
||||
reverseManageStore.selectBookTask.customizeImageStyle = res.data.customizeImageStyle
|
||||
message.success('保存成功')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
reverseManageStore,
|
||||
bookType,
|
||||
softwareStore,
|
||||
SelectPromptIndex,
|
||||
SelectStyle,
|
||||
selectStyleRef
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<div style="display: flex; align-items: center">
|
||||
<div>出图</div>
|
||||
<n-select
|
||||
style="width: 70px; margin-left: 5px"
|
||||
size="tiny"
|
||||
v-model:value="select"
|
||||
@update:value="handleUpdateValue"
|
||||
:options="options"
|
||||
/>
|
||||
<n-dropdown trigger="hover" :options="blockOptions" @select="ImageLockOperation">
|
||||
<n-button
|
||||
:color="softwareStore.SoftColor.ZHUYANTUO"
|
||||
@click="ImageLockOperation('lock')"
|
||||
size="tiny"
|
||||
style="margin-left: 5px"
|
||||
>一键锁定</n-button
|
||||
>
|
||||
</n-dropdown>
|
||||
<n-button
|
||||
:color="softwareStore.SoftColor.ZHUYANTUO"
|
||||
@click="OneToFourBookTask"
|
||||
size="tiny"
|
||||
style="margin-left: 5px"
|
||||
>一拆四</n-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch, computed } from 'vue'
|
||||
import { useMessage, useDialog, NSelect, NButton, NDropdown } from 'naive-ui'
|
||||
import { BookImageCategory, OperateBookType } from '../../../../../define/enum/bookEnum'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NSelect, NButton, NDropdown },
|
||||
|
||||
setup() {
|
||||
let message = useMessage()
|
||||
let dialog = useDialog()
|
||||
let softwareStore = useSoftwareStore()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let select = computed(() =>
|
||||
reverseManageStore.selectBookTask.imageCategory
|
||||
? reverseManageStore.selectBookTask.imageCategory
|
||||
: BookImageCategory.MJ
|
||||
)
|
||||
onMounted(async () => {})
|
||||
|
||||
async function handleUpdateValue(value) {
|
||||
if (value == BookImageCategory.D3) {
|
||||
message.error('暂不支持该出图模式')
|
||||
return
|
||||
}
|
||||
// 将值的修改保存进数据库中
|
||||
let res = await window.db.UpdateBookTaskData(reverseManageStore.selectBookTask.id, {
|
||||
imageCategory: value
|
||||
})
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
reverseManageStore.selectBookTask.imageCategory = value
|
||||
message.success('修改成功')
|
||||
}
|
||||
|
||||
/**
|
||||
* 土拍你
|
||||
* @param value
|
||||
*/
|
||||
async function ImageLockOperation(value) {
|
||||
let res = await window.book.ImageLockOperation(
|
||||
reverseManageStore.selectBookTask.id,
|
||||
value,
|
||||
OperateBookType.BOOKTASK
|
||||
)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
for (let i = 0; i < res.data.length; i++) {
|
||||
const element = res.data[i]
|
||||
let index = reverseManageStore.selectBookTaskDetail.findIndex(
|
||||
(item) => item.id == element.id
|
||||
)
|
||||
if (index != -1) {
|
||||
reverseManageStore.selectBookTaskDetail[index].imageLock = element.imageLock
|
||||
}
|
||||
}
|
||||
message.success(res.message)
|
||||
}
|
||||
|
||||
// 进行一拆四操作
|
||||
async function OneToFourBookTask() {
|
||||
dialog.warning({
|
||||
title: '一拆四提示',
|
||||
content:
|
||||
'是否一拆四(一拆四是个泛指,根据出的子图数量最少的),会自动生成多个批次任务并设置对应的图片!',
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: async () => {
|
||||
let res = await window.book.OneToFourBookTask(reverseManageStore.selectBookTask.id)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
message.success(res.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
reverseManageStore,
|
||||
handleUpdateValue,
|
||||
OneToFourBookTask,
|
||||
softwareStore,
|
||||
ImageLockOperation,
|
||||
select,
|
||||
blockOptions: [
|
||||
{
|
||||
label: '一键解锁',
|
||||
key: 'unlock'
|
||||
}
|
||||
],
|
||||
options: [
|
||||
{
|
||||
label: 'MJ',
|
||||
value: BookImageCategory.MJ
|
||||
},
|
||||
{
|
||||
label: 'SD',
|
||||
value: BookImageCategory.SD
|
||||
},
|
||||
{
|
||||
label: 'D3',
|
||||
value: BookImageCategory.D3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<div style="display: flex; align-items: center; margin-left: 10px">
|
||||
<n-popover trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button color="#7c461e" @click="SetMergeModel" text style="font-size: 24px">
|
||||
<n-icon>
|
||||
<Construct />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</template>
|
||||
<span>设置合并排序模式</span>
|
||||
</n-popover>
|
||||
<n-dropdown trigger="hover" :options="MergePromptOptions" @select="MergePrompt">
|
||||
<n-button
|
||||
size="tiny"
|
||||
style="margin-left: 5px"
|
||||
@click="MergePrompt(null)"
|
||||
:color="softwareStore.SoftColor.ZHUYANTUO"
|
||||
>合并命令</n-button
|
||||
>
|
||||
</n-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch, h } from 'vue'
|
||||
import es, { useMessage, useDialog, NDropdown, NPopover, NIcon, NButton } from 'naive-ui'
|
||||
import { Construct } from '@vicons/ionicons5'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import DynamicTagsSelect from '../../Components/DynamicTagsSelect.vue'
|
||||
import { usePromptStore } from '../../../../../stores/prompt'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import { BookImageCategory, BookType, MergeType } from '../../../../../define/enum/bookEnum'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NDropdown, NPopover, NIcon, NButton, Construct },
|
||||
|
||||
setup() {
|
||||
let softwareStore = useSoftwareStore()
|
||||
let promptStore = usePromptStore()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let message = useMessage()
|
||||
let dialog = useDialog()
|
||||
onMounted(async () => {})
|
||||
|
||||
async function SaveFunction(value, options) {
|
||||
// 开始保存
|
||||
|
||||
// 判断当前的数据是不是options中的数据数量是不是相同
|
||||
if (value.length != options.length) {
|
||||
message.error('要保存的数据量和下拉选择的的数据量不一致')
|
||||
return
|
||||
}
|
||||
promptStore.InitPromptSort(value)
|
||||
|
||||
// 开始保存
|
||||
await window.pmpt.SavePromptSort(value, (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
reutrn
|
||||
}
|
||||
message.success(value.message)
|
||||
// 保存成功,修改store
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置合并的模式
|
||||
*/
|
||||
async function SetMergeModel() {
|
||||
let promptSortRes = await window.pmpt.GetPromptSort()
|
||||
if (promptSortRes.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
promptStore.InitPromptSort(promptSortRes.data)
|
||||
// 获取当前的排序数据
|
||||
await window.pmpt.GetPromptSortOptions((value) => {
|
||||
let options = value.data
|
||||
|
||||
dialog.create({
|
||||
name: 'setMergeModel',
|
||||
title: '设置合并排序模式',
|
||||
content: () =>
|
||||
h(DynamicTagsSelect, {
|
||||
options: options,
|
||||
tagType: 'success',
|
||||
placeholder: '选择当前的prompt排序方式',
|
||||
SaveFunction: SaveFunction,
|
||||
initData: promptStore.GetPromptSort,
|
||||
max: 4
|
||||
}),
|
||||
style: `width : 500px; `,
|
||||
maskClosable: false,
|
||||
onPositiveClick: async () => {}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 合并命令按钮,后台合并
|
||||
async function MergePrompt(key) {
|
||||
let type = key
|
||||
if (!key) {
|
||||
if (reverseManageStore.selectBookTask.imageCategory == BookImageCategory.MJ) {
|
||||
type = 'mj_merge'
|
||||
} else if (reverseManageStore.selectBookTask.imageCategory == BookImageCategory.SD) {
|
||||
type = 'sd_merge'
|
||||
} else {
|
||||
type = 'mj_merge'
|
||||
}
|
||||
}
|
||||
// 开始进行合并,调用不同的合并模式
|
||||
let res = undefined
|
||||
// 合并之前,要确认保存
|
||||
softwareStore.spin.spinning = true
|
||||
softwareStore.spin.tip = '合并命令中。。。'
|
||||
|
||||
if (type == 'mj_merge') {
|
||||
res = await window.mj.MergePrompt(reverseManageStore.selectBookTask.id, MergeType.BOOKTASK)
|
||||
} else if (type == 'sd_merge') {
|
||||
res = await window.sd.MergePrompt(reverseManageStore.selectBookTask.id, MergeType.BOOKTASK)
|
||||
} else {
|
||||
message.error('未知的合并模式')
|
||||
softwareStore.spin.spinning = false
|
||||
return
|
||||
}
|
||||
|
||||
// 这边对返回的数据进行处理
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
softwareStore.spin.spinning = false
|
||||
return
|
||||
}
|
||||
for (let i = 0; i < res.data.length; i++) {
|
||||
const element = res.data[i]
|
||||
let selectBookDetailIndex = reverseManageStore.selectBookTaskDetail.findIndex(
|
||||
(item) => item.id == element.id
|
||||
)
|
||||
reverseManageStore.selectBookTaskDetail[selectBookDetailIndex].prompt = element.prompt
|
||||
}
|
||||
message.success(res.message)
|
||||
softwareStore.spin.spinning = false
|
||||
}
|
||||
|
||||
return {
|
||||
softwareStore,
|
||||
SetMergeModel,
|
||||
reverseManageStore,
|
||||
MergePrompt,
|
||||
MergePromptOptions: [
|
||||
{ label: 'MJ模式合并', key: 'mj_merge' },
|
||||
{ label: 'SD模式合并', key: 'sd_merge' }
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,234 @@
|
||||
<template>
|
||||
<div style="position: absolute; top: 0">
|
||||
<n-dropdown trigger="hover" :options="mergeOptions" @select="MergePrompt">
|
||||
<n-button
|
||||
size="tiny"
|
||||
:color="softwareStore.SoftColor.BROWN_YELLOW"
|
||||
@click="MergePrompt(undefined)"
|
||||
>
|
||||
单句合并
|
||||
</n-button>
|
||||
</n-dropdown>
|
||||
|
||||
<n-button
|
||||
style="margin-left: 5px"
|
||||
size="tiny"
|
||||
:color="softwareStore.SoftColor.BROWN_YELLOW"
|
||||
@click="SingleGenerateImage"
|
||||
>
|
||||
单句生图
|
||||
</n-button>
|
||||
|
||||
<n-button
|
||||
style="margin-left: 5px"
|
||||
size="tiny"
|
||||
:color="softwareStore.SoftColor.BROWN_YELLOW"
|
||||
@click="UnderGenerateImage"
|
||||
>
|
||||
下生图
|
||||
</n-button>
|
||||
<n-button
|
||||
style="margin-left: 5px"
|
||||
size="tiny"
|
||||
:color="softwareStore.SoftColor.BROWN_YELLOW"
|
||||
@click="ImportMJImageUrl"
|
||||
>
|
||||
导入图片
|
||||
</n-button>
|
||||
</div>
|
||||
<n-input
|
||||
style="margin-top: 5px"
|
||||
type="textarea"
|
||||
size="tiny"
|
||||
@input="InputDebounced"
|
||||
v-model:value="data.prompt"
|
||||
:autosize="{ minRows: 6, maxRows: 6 }"
|
||||
></n-input>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch, h } from 'vue'
|
||||
import { useMessage, useDialog, NInput, NButton, NDropdown } from 'naive-ui'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import { MergeType, OperateBookType } from '../../../../../define/enum/bookEnum'
|
||||
import { BookImageCategory } from '../../../../../define/enum/bookEnum'
|
||||
import { debounce } from 'lodash'
|
||||
import InputDialogContent from '../../Original/Components/InputDialogContent.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NInput, NButton, NDropdown },
|
||||
props: ['initData', 'index'],
|
||||
setup(props) {
|
||||
let message = useMessage()
|
||||
let softwareStore = useSoftwareStore()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let data = ref(props.initData)
|
||||
let image_url_ref = ref(null)
|
||||
let dialog = useDialog()
|
||||
onMounted(async () => {})
|
||||
|
||||
// 合并提示词
|
||||
async function MergePrompt(key) {
|
||||
let type = key
|
||||
if (!key) {
|
||||
if (reverseManageStore.selectBookTask.imageCategory == BookImageCategory.MJ) {
|
||||
type = 'mj_merge'
|
||||
} else if (reverseManageStore.selectBookTask.imageCategory == BookImageCategory.SD) {
|
||||
type = 'sd_merge'
|
||||
} else {
|
||||
type = 'mj_merge'
|
||||
}
|
||||
}
|
||||
// 开始进行合并,调用不同的合并模式
|
||||
let res = undefined
|
||||
// 合并之前,要确认保存
|
||||
softwareStore.spin.spinning = true
|
||||
softwareStore.spin.tip = '合并命令中。。。'
|
||||
|
||||
if (type == 'mj_merge') {
|
||||
res = await window.mj.MergePrompt(data.value.id, MergeType.BOOKTASKDETAIL)
|
||||
} else if (type == 'sd_merge') {
|
||||
res = await window.sd.MergePrompt(data.value.id, MergeType.BOOKTASKDETAIL)
|
||||
} else {
|
||||
message.error('未知的合并模式')
|
||||
softwareStore.spin.spinning = false
|
||||
return
|
||||
}
|
||||
|
||||
// 这边对返回的数据进行处理
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
softwareStore.spin.spinning = false
|
||||
return
|
||||
}
|
||||
for (let i = 0; i < res.data.length; i++) {
|
||||
const element = res.data[i]
|
||||
let selectBookDetailIndex = reverseManageStore.selectBookTaskDetail.findIndex(
|
||||
(item) => item.id == element.id
|
||||
)
|
||||
reverseManageStore.selectBookTaskDetail[selectBookDetailIndex].prompt = element.prompt
|
||||
}
|
||||
message.success(res.message)
|
||||
softwareStore.spin.spinning = false
|
||||
}
|
||||
|
||||
// 单个出图
|
||||
async function SingleGenerateImage() {
|
||||
let res = undefined
|
||||
if (reverseManageStore.selectBookTask.imageCategory == BookImageCategory.MJ) {
|
||||
res = await window.mj.AddMJGenerateImageTask(data.value.id, OperateBookType.BOOKTASKDETAIL)
|
||||
} else if (reverseManageStore.selectBookTask.imageCategory == BookImageCategory.SD) {
|
||||
// res = await window.sd.SingleGenerateImage(data.value.id, OperateBookType.BOOKTASKDETAIL)
|
||||
message.error('暂不支该出图模式')
|
||||
} else {
|
||||
message.error('未知的出图模式')
|
||||
return
|
||||
}
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
message.success(res.message)
|
||||
}
|
||||
|
||||
// 下生图
|
||||
async function UnderGenerateImage() {
|
||||
let res = undefined
|
||||
if (reverseManageStore.selectBookTask.imageCategory == BookImageCategory.MJ) {
|
||||
res = await window.mj.AddMJGenerateImageTask(data.value.id, OperateBookType.UNDERBOOKTASK)
|
||||
} else if (reverseManageStore.selectBookTask.imageCategory == BookImageCategory.SD) {
|
||||
// res = await window.sd.SingleGenerateImage(data.value.id, OperateBookType.UNDERBOOKTASK)
|
||||
message.error('暂不支该出图模式')
|
||||
} else {
|
||||
message.error('未知的出图模式')
|
||||
return
|
||||
}
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
message.success(res.message)
|
||||
}
|
||||
|
||||
let InputDebounced = debounce(handleInput, 1000)
|
||||
async function handleInput() {
|
||||
let res = await window.db.UpdateBookTaskDetailData(data.value.id, {
|
||||
prompt: data.value.prompt
|
||||
})
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入图片的链接,将图片链接下载,并且分割
|
||||
*/
|
||||
async function ImportMJImageUrl() {
|
||||
// 判断当前数据是不是存在
|
||||
// 处理数据。获取当前的所有的数据
|
||||
let dialogWidth = 400
|
||||
let dialogHeight = 150
|
||||
dialog.create({
|
||||
title: '添加图片链接/本地地址',
|
||||
showIcon: false,
|
||||
closeOnEsc: false,
|
||||
content: () =>
|
||||
h(InputDialogContent, {
|
||||
ref: image_url_ref,
|
||||
initData: null,
|
||||
placeholder: '请输入图片链接/本地地址'
|
||||
}),
|
||||
style: `width : ${dialogWidth}px; min-height : ${dialogHeight}px`,
|
||||
maskClosable: false,
|
||||
onClose: async () => {
|
||||
let row_image_url = image_url_ref.value.data
|
||||
alert(row_image_url)
|
||||
let res = await window.book.DownloadImageUrlAndSplit(data.value.id, row_image_url)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
data.value.outImagePath = res.data.outImagePath
|
||||
data.value.subImagePath = res.data.subImagePath
|
||||
message.success(res.message)
|
||||
|
||||
// 下载指定的图片地址并且分割
|
||||
// await window.mj.DownloadImageUrlAndSplit(
|
||||
// JSON.stringify([toRaw(row.value), row_image_url]),
|
||||
// (value) => {
|
||||
// if (value.code == 0) {
|
||||
// message.error(value.message)
|
||||
// return
|
||||
// }
|
||||
// // 更新当前的数据
|
||||
// row.value.outImagePath = value.data.outImagePath
|
||||
// row.value.subImagePath = value.data.subImagePath
|
||||
// row.value.mj_message = value.data.mj_message ? value.data.mj_message : {}
|
||||
// row.value.mj_message.image_click = value.data.image_click
|
||||
// row.value.mj_message.image_path = value.data.image_path
|
||||
// row.value.mj_message.progress = 100
|
||||
// }
|
||||
// )
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
softwareStore,
|
||||
reverseManageStore,
|
||||
InputDebounced,
|
||||
SingleGenerateImage,
|
||||
MergePrompt,
|
||||
data,
|
||||
image_url_ref,
|
||||
ImportMJImageUrl,
|
||||
UnderGenerateImage,
|
||||
mergeOptions: [
|
||||
{ label: 'MJ模式合并', key: 'mj_merge' },
|
||||
{ label: 'SD模式合并', key: 'sd_merge' }
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
+2
-2
@@ -41,9 +41,9 @@
|
||||
import { ref, onMounted, defineComponent, onUnmounted, h, toRaw, computed } from 'vue'
|
||||
import { useMessage, NButton, NIcon, useDialog, NPopover, NSwitch, NDropdown } from 'naive-ui'
|
||||
import { AddSharp, ReloadSharp, ResizeSharp, SwapHorizontalSharp } from '@vicons/ionicons5'
|
||||
import AddBook from './AddBook.vue'
|
||||
import AddBook from '../Components/AddBook.vue'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage.js'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage.ts'
|
||||
import { BookType } from '../../../../../define/enum/bookEnum'
|
||||
|
||||
export default defineComponent({
|
||||
@@ -0,0 +1,679 @@
|
||||
<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"> 返回 </n-button>
|
||||
<n-dropdown trigger="hover" :options="AutoOptions" @select="SelectAutoAction">
|
||||
<n-button :color="softwareStore.SoftColor.ORANGE" @click="Start" style="margin-left: 5px">
|
||||
自动开始
|
||||
</n-button>
|
||||
</n-dropdown>
|
||||
<n-divider vertical style="height: 30px" />
|
||||
<n-dropdown trigger="hover" :options="frameOptions" @select="handleSelect">
|
||||
<n-button :color="softwareStore.SoftColor.ORANGE" @click=""> 开始分镜 </n-button>
|
||||
</n-dropdown>
|
||||
<n-dropdown trigger="hover" :options="copywritingOptions" @select="handleSelect">
|
||||
<n-button
|
||||
:color="softwareStore.SoftColor.ORANGE"
|
||||
style="margin-left: 5px"
|
||||
@click="GetCopywriting"
|
||||
>
|
||||
开始提取文案
|
||||
</n-button>
|
||||
</n-dropdown>
|
||||
|
||||
<n-dropdown trigger="hover" :options="watermarkOptions" @select="handleSelect">
|
||||
<n-button
|
||||
:color="softwareStore.SoftColor.ORANGE"
|
||||
style="margin-left: 5px"
|
||||
@click="RemoveWatermark"
|
||||
>
|
||||
开始去除水印
|
||||
</n-button>
|
||||
</n-dropdown>
|
||||
|
||||
<n-button
|
||||
:color="softwareStore.SoftColor.ORANGE"
|
||||
style="margin-left: 5px"
|
||||
@click="ImportWordAndSrtFunc"
|
||||
>
|
||||
导入文案/SRT
|
||||
</n-button>
|
||||
|
||||
<n-dropdown trigger="hover" :options="reverseOptions" @select="handleSelect">
|
||||
<n-button
|
||||
:color="softwareStore.SoftColor.ORANGE"
|
||||
style="margin-left: 5px"
|
||||
@click="ImageReversePrompt(undefined)"
|
||||
>
|
||||
一键反推
|
||||
</n-button>
|
||||
</n-dropdown>
|
||||
|
||||
<n-dropdown trigger="hover" :options="translateOptions" @select="handleSelect">
|
||||
<n-button
|
||||
:color="softwareStore.SoftColor.ORANGE"
|
||||
style="margin-left: 5px"
|
||||
@click="Translate(undefined)"
|
||||
>
|
||||
一键翻译
|
||||
</n-button>
|
||||
</n-dropdown>
|
||||
|
||||
<n-dropdown trigger="hover" :options="generateOptions" @select="handleSelect">
|
||||
<n-button
|
||||
:color="softwareStore.SoftColor.ORANGE"
|
||||
style="margin-left: 5px"
|
||||
@click="GenerateImageAll"
|
||||
>
|
||||
一键生图
|
||||
</n-button>
|
||||
</n-dropdown>
|
||||
|
||||
<n-button
|
||||
:color="softwareStore.SoftColor.ORANGE"
|
||||
style="margin-left: 5px"
|
||||
@click="OpenSettingDialog"
|
||||
>
|
||||
设置
|
||||
</n-button>
|
||||
</div>
|
||||
|
||||
<div class="right-button">
|
||||
<n-button
|
||||
text
|
||||
strong
|
||||
:type="softwareStore.show_logger ? 'default' : 'info'"
|
||||
@click="switchLogger"
|
||||
>
|
||||
{{ softwareStore.show_logger ? '隐藏日志' : '显示日志' }}
|
||||
</n-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch, h } from 'vue'
|
||||
import { useMessage, NButton, useDialog, NCheckbox, NDropdown, NDivider, NRate } from 'naive-ui'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage.ts'
|
||||
import { isEmpty } from 'lodash'
|
||||
import VideoCanvas from '../../VideoSubtitle/VideoCanvas.vue'
|
||||
import { SubtitleSavePositionType } from '../../../../../define/enum/waterMarkAndSubtitle'
|
||||
import { DEFINE_STRING } from '../../../../../define/define_string'
|
||||
import Setting from './Setting.vue'
|
||||
import { BookType } from '../../../../../define/enum/bookEnum'
|
||||
import TranslateSetting from '../../Setting/TranslateSetting.vue'
|
||||
import { TranslateType } from '../../../../../define/enum/translate'
|
||||
import { ContainsChineseOrPunctuation } from '../../../../../define/Tools/common'
|
||||
import ImportWordAndSrt from '../../Original/Components/ImportWordAndSrt.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NButton,
|
||||
NCheckbox,
|
||||
NDropdown,
|
||||
NDivider
|
||||
},
|
||||
|
||||
setup() {
|
||||
let router = useRouter()
|
||||
let message = useMessage()
|
||||
let dialog = useDialog()
|
||||
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let softwareStore = useSoftwareStore()
|
||||
// 获取当前这个界面的数据
|
||||
onMounted(async () => {
|
||||
window.api.setEventListen([DEFINE_STRING.BOOK.GET_COPYWRITING_RETURN], (value) => {
|
||||
debugger
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
code.value = code.value + '\n' + value.data
|
||||
return
|
||||
}
|
||||
let index = reverseManageStore.selectBookTaskDetail.findIndex((item) => item.id == value.id)
|
||||
if (index >= 0) {
|
||||
reverseManageStore.selectBookTaskDetail[index].word = value.data
|
||||
reverseManageStore.selectBookTaskDetail[index].afterGpt = value.data
|
||||
}
|
||||
})
|
||||
|
||||
window.api.setEventListen([DEFINE_STRING.BOOK.REMOVE_WATERMARK_RETURN], (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
let index = reverseManageStore.selectBookTaskDetail.findIndex((item) => item.id == value.id)
|
||||
if (index >= 0) {
|
||||
reverseManageStore.selectBookTaskDetail[index].oldImage =
|
||||
value.data + '?time=' + new Date().getTime()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// 返回主页
|
||||
function RetuenMain() {
|
||||
router.push('/book_management')
|
||||
}
|
||||
|
||||
// 自动开始
|
||||
async function AutoAction() {
|
||||
// 开始自动执行。先分镜,后面在添加任务中
|
||||
let res_frame = await window.book.AutoAction(reverseManageStore.selectBook.id)
|
||||
}
|
||||
|
||||
// 选择自动开始的操作(停止或者是继续)
|
||||
async function SelectAutoAction() {}
|
||||
|
||||
// 是不是显示日志
|
||||
async function switchLogger() {
|
||||
softwareStore.show_logger = !softwareStore.show_logger
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始分镜
|
||||
*/
|
||||
async function ComputeStoryboard() {
|
||||
softwareStore.spin.spinning = true
|
||||
softwareStore.spin.tip = '正在计算分镜中'
|
||||
if (isEmpty(reverseManageStore.selectBookTask.id)) {
|
||||
window.api.showGlobalMessageDialog({
|
||||
code: 0,
|
||||
message: '没有找到要执行的任务'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
let res_frame = await window.book.ComputeStoryboard(reverseManageStore.selectBook.id)
|
||||
if (res_frame.code == 0) {
|
||||
softwareStore.spin.spinning = false
|
||||
window.api.showGlobalMessageDialog(res_frame)
|
||||
return
|
||||
}
|
||||
|
||||
// 分镜完成,重新获取一下数据
|
||||
let getRes = await reverseManageStore.GetBookTaskDataFromDB({
|
||||
id: reverseManageStore.selectBookTask.id
|
||||
})
|
||||
|
||||
if (getRes.code == 0) {
|
||||
softwareStore.spin.spinning = false
|
||||
message.error(getRes.message)
|
||||
return
|
||||
}
|
||||
softwareStore.spin.spinning = false
|
||||
message.success('重新获取数据成功')
|
||||
}
|
||||
|
||||
// 执行分镜的方法
|
||||
async function Framing() {
|
||||
softwareStore.spin.spinning = true
|
||||
softwareStore.spin.tip = '正在分镜中'
|
||||
if (isEmpty(reverseManageStore.selectBookTask.id)) {
|
||||
window.api.showGlobalMessageDialog({
|
||||
code: 0,
|
||||
message: '没有找到要执行的任务'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
let res_frame = await window.book.Framing(reverseManageStore.selectBook.id)
|
||||
if (res_frame.code == 0) {
|
||||
softwareStore.spin.spinning = false
|
||||
window.api.showGlobalMessageDialog(res_frame)
|
||||
return
|
||||
}
|
||||
|
||||
// 分镜完成,重新获取一下数据
|
||||
let getRes = await reverseManageStore.GetBookTaskDataFromDB({
|
||||
id: reverseManageStore.selectBookTask.id
|
||||
})
|
||||
|
||||
if (getRes.code == 0) {
|
||||
softwareStore.spin.spinning = false
|
||||
message.error(getRes.message)
|
||||
return
|
||||
}
|
||||
softwareStore.spin.spinning = false
|
||||
message.success('重新获取数据成功')
|
||||
}
|
||||
|
||||
// 获取文案信息
|
||||
async function GetCopywriting() {
|
||||
if (isEmpty(reverseManageStore.selectBookTask.id)) {
|
||||
window.api.showGlobalMessageDialog({
|
||||
code: 0,
|
||||
message: '没有找到要执行的任务'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
let copywriting_res = await window.book.GetCopywriting(reverseManageStore.selectBook.id)
|
||||
if (copywriting_res.code == 0) {
|
||||
message.error(copywriting_res.message)
|
||||
return
|
||||
}
|
||||
message.success('获取文案成功')
|
||||
}
|
||||
|
||||
// 开始去除水印
|
||||
async function RemoveWatermark() {
|
||||
// softwareStore.spin.spinning = true
|
||||
// softwareStore.spin.tip = '正在去除水印中'
|
||||
if (isEmpty(reverseManageStore.selectBookTask.id)) {
|
||||
window.api.showGlobalMessageDialog({
|
||||
code: 0,
|
||||
message: '没有找到要执行的任务'
|
||||
})
|
||||
return
|
||||
}
|
||||
let res_frame = await window.book.RemoveWatermark(reverseManageStore.selectBook.id)
|
||||
softwareStore.spin.spinning = false
|
||||
window.api.showGlobalMessageDialog(res_frame)
|
||||
}
|
||||
|
||||
// 获取文案信息设置
|
||||
async function GetCopywritingSetting() {
|
||||
let dialogHeight = window.innerHeight * 0.9
|
||||
dialog.create({
|
||||
showIcon: false,
|
||||
closeOnEsc: false,
|
||||
content: () =>
|
||||
h(VideoCanvas, {
|
||||
videoWidth: 800,
|
||||
videoSrc: reverseManageStore.selectBook.oldVideoPath,
|
||||
height: dialogHeight - 50,
|
||||
type: SubtitleSavePositionType.SETTING
|
||||
}),
|
||||
style: `width : 850px; height : ${dialogHeight}px`,
|
||||
maskClosable: false,
|
||||
onClose: () => {}
|
||||
})
|
||||
}
|
||||
|
||||
async function handleSelect(key) {
|
||||
switch (key) {
|
||||
case 'compute_frame':
|
||||
await ComputeStoryboard()
|
||||
break
|
||||
case 'framing':
|
||||
await Framing()
|
||||
break
|
||||
case 'recognizing_setting':
|
||||
await GetCopywritingSetting()
|
||||
break
|
||||
case 'mj_reverse':
|
||||
await ImageReversePrompt(BookType.MJ_REVERSE)
|
||||
break
|
||||
case 'sd_reverse':
|
||||
await ImageReversePrompt(BookType.SD_REVERSE)
|
||||
break
|
||||
case 'remove_reverse':
|
||||
await RemoveReverseData(undefined)
|
||||
break
|
||||
case 'translate_chinese': // 英文翻译为中文
|
||||
await Translate('translate_chinese')
|
||||
break
|
||||
case 'translate_english': // 中文翻译为英文
|
||||
await Translate('translate_english')
|
||||
break
|
||||
|
||||
case 'translate_setting': // 翻译设置
|
||||
await Translate('translate_setting')
|
||||
break
|
||||
default:
|
||||
message.error('未知的选项')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开设置对话框
|
||||
*/
|
||||
async function OpenSettingDialog() {
|
||||
let dialogWidth = window.innerWidth * 0.8
|
||||
let dialogHeight = window.innerHeight * 0.95
|
||||
dialog.create({
|
||||
showIcon: false,
|
||||
title: '设置',
|
||||
content: () => h(Setting, { height: dialogHeight }),
|
||||
style: `width : ${dialogWidth}px; height : ${dialogHeight}px`,
|
||||
maskClosable: false
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* MJ反推数据
|
||||
* @param type 反推类型
|
||||
*/
|
||||
async function ImageReversePrompt(type = undefined) {
|
||||
debugger
|
||||
if (isEmpty(reverseManageStore.selectBookTask.id)) {
|
||||
window.api.showGlobalMessageDialog({
|
||||
code: 0,
|
||||
message: '没有找到要执行的任务'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (!type) {
|
||||
let bookType = reverseManageStore.selectBook.type
|
||||
type = bookType
|
||||
}
|
||||
|
||||
if (type != BookType.MJ_REVERSE && type != BookType.SD_REVERSE) {
|
||||
message.error(`该类型 ${bookType} 的小说不支持反推`)
|
||||
return
|
||||
}
|
||||
let reverseIds = []
|
||||
// 开始获取需要反推的数据
|
||||
for (let i = 0; i < reverseManageStore.selectBookTaskDetail.length; i++) {
|
||||
const element = reverseManageStore.selectBookTaskDetail[i]
|
||||
if (!element.reversePrompt || element.reversePrompt.length <= 0) {
|
||||
reverseIds.push(element.id)
|
||||
}
|
||||
}
|
||||
|
||||
// 开始添加
|
||||
let res = await window.book.AddReversePrompt(reverseIds, type)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
} else {
|
||||
message.success('添加所有反推任务成功')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除反推的数据
|
||||
*/
|
||||
async function RemoveReverseData(id) {
|
||||
let deleteIds = []
|
||||
|
||||
// 删除全部的
|
||||
for (let i = 0; i < reverseManageStore.selectBookTaskDetail.length; i++) {
|
||||
const element = reverseManageStore.selectBookTaskDetail[i]
|
||||
if (element.reversePrompt && element.reversePrompt.length > 0) {
|
||||
deleteIds.push(element.id)
|
||||
}
|
||||
}
|
||||
|
||||
let res = await window.book.RemoveReverseData(deleteIds)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
} else {
|
||||
// 这个做个前端删除
|
||||
for (let i = 0; i < deleteIds.length; i++) {
|
||||
const element = deleteIds[i]
|
||||
let index = reverseManageStore.selectBookTaskDetail.findIndex(
|
||||
(item) => item.id == element
|
||||
)
|
||||
if (index >= 0) {
|
||||
reverseManageStore.selectBookTaskDetail[index].reversePrompt = undefined
|
||||
}
|
||||
}
|
||||
|
||||
message.success('删除反推数据成功')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻译提示词
|
||||
* @param key 操作的值,进行分类
|
||||
*/
|
||||
async function Translate(key) {
|
||||
switch (key) {
|
||||
case undefined:
|
||||
case null:
|
||||
message.error('请选择子菜单中的选项')
|
||||
break
|
||||
case 'translate_chinese': // 将英文翻译到中文
|
||||
await TranslateService('en', 'zh')
|
||||
break
|
||||
|
||||
case 'translate_english': // 将中文翻译到英文
|
||||
await TranslateService('zh', 'en')
|
||||
break
|
||||
|
||||
case 'translate_setting': // 翻译设置
|
||||
await OpenTranslateSettingDialog()
|
||||
break
|
||||
|
||||
default:
|
||||
message.error('不支持的操作类型')
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开翻译设置弹窗
|
||||
*/
|
||||
async function OpenTranslateSettingDialog() {
|
||||
// 判断当前数据是不是存在
|
||||
// 处理数据。获取当前的所有的数据
|
||||
let dialogWidth = window.innerWidth * 0.8
|
||||
let dialogHeight = window.innerHeight * 0.9
|
||||
dialog.create({
|
||||
showIcon: false,
|
||||
title: '翻译设置',
|
||||
content: () => h(TranslateSetting),
|
||||
style: `width : ${dialogWidth}px; height : ${dialogHeight}px`,
|
||||
maskClosable: false
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用翻译接口
|
||||
* @param from 源语言
|
||||
* @param to 目标语言
|
||||
*/
|
||||
async function TranslateService(from, to) {
|
||||
let translateData = []
|
||||
for (let i = 0; i < reverseManageStore.selectBookTaskDetail.length; i++) {
|
||||
const element = reverseManageStore.selectBookTaskDetail[i]
|
||||
let reversePrompt = element.reversePrompt
|
||||
if (reversePrompt) {
|
||||
reversePrompt.forEach((item) => {
|
||||
if (from == 'zh' && to == 'en') {
|
||||
// 判断是不是有中文
|
||||
if (!ContainsChineseOrPunctuation(item.promptCN ? item.promptCN : item.prompt)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
let temp_obj = {
|
||||
text: item.prompt,
|
||||
from: from,
|
||||
to: to,
|
||||
type: TranslateType.REVERSE_PROMPT_TRANSLATE,
|
||||
isSplit: false, // 该参数设置为true时,会将文本按照标点符号分割成多个句子进行翻译
|
||||
bookTaskDetailId: element.id,
|
||||
reversePromptId: item.id
|
||||
}
|
||||
translateData.push(temp_obj)
|
||||
})
|
||||
}
|
||||
}
|
||||
if (translateData.length == 0) {
|
||||
message.error('没有需要翻译的数据')
|
||||
return
|
||||
}
|
||||
|
||||
softwareStore.spin.spinning = true
|
||||
softwareStore.spin.tip = `翻译中 ... 0 / ${translateData.length}`
|
||||
// 开始翻译
|
||||
let res = await window.translate.TranslateNowReturn(translateData)
|
||||
softwareStore.spin.spinning = false
|
||||
window.api.showGlobalMessageDialog(res)
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成所有图片
|
||||
*/
|
||||
async function GenerateImageAll() {
|
||||
let res = await window.book.GenerateImageAll(
|
||||
reverseManageStore.selectBookTask.id,
|
||||
reverseManageStore.selectBookTask.imageCategory
|
||||
)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
message.success(res.message)
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入文案和SRT
|
||||
*/
|
||||
async function ImportWordAndSrtFunc() {
|
||||
let dialogWidth = window.innerWidth * 0.95
|
||||
let dialogHeight = window.innerHeight * 0.95
|
||||
|
||||
// 这边要处理下数据
|
||||
if (
|
||||
reverseManageStore.selectBook.type == BookType.MJ_REVERSE ||
|
||||
reverseManageStore.selectBook.type == BookType.MJ_REVERSE
|
||||
) {
|
||||
if (reverseManageStore.selectBookTaskDetail.length <= 0) {
|
||||
message.error('反推小说,没有找到对应的分镜数据')
|
||||
}
|
||||
}
|
||||
|
||||
let tempData = []
|
||||
for (let i = 0; i < reverseManageStore.selectBookTaskDetail.length; i++) {
|
||||
debugger
|
||||
const element = reverseManageStore.selectBookTaskDetail[i]
|
||||
tempData.push({
|
||||
no: element.no,
|
||||
id: element.id,
|
||||
lastId: i == 0 ? '' : reverseManageStore.selectBookTaskDetail[i - 1].id,
|
||||
word: element.word,
|
||||
after_gpt: element.afterGpt,
|
||||
subValue: element.subValue ? element.subValue : [],
|
||||
name: element.name + '.png',
|
||||
prompt: element.prompt
|
||||
})
|
||||
}
|
||||
|
||||
// ImportWordAndSrt
|
||||
dialog.create({
|
||||
showIcon: false,
|
||||
closeOnEsc: false,
|
||||
content: () =>
|
||||
h(ImportWordAndSrt, {
|
||||
initData: tempData,
|
||||
height: dialogHeight,
|
||||
type: BookType.MJ_REVERSE
|
||||
}),
|
||||
style: `width : ${dialogWidth}px; min-height : ${dialogHeight}px`,
|
||||
maskClosable: false,
|
||||
onClose: () => {}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
RetuenMain,
|
||||
AutoAction,
|
||||
ImportWordAndSrtFunc,
|
||||
reverseManageStore,
|
||||
softwareStore,
|
||||
switchLogger,
|
||||
ComputeStoryboard,
|
||||
OpenSettingDialog,
|
||||
GetCopywriting,
|
||||
RemoveWatermark,
|
||||
ImageReversePrompt,
|
||||
RemoveReverseData,
|
||||
Translate,
|
||||
TranslateService,
|
||||
GenerateImageAll,
|
||||
handleSelect,
|
||||
AutoOptions: [
|
||||
{
|
||||
label: '停止任务',
|
||||
value: 'auto_stop'
|
||||
},
|
||||
{
|
||||
label: '继续任务',
|
||||
value: 'auto_continue'
|
||||
}
|
||||
],
|
||||
frameOptions: [
|
||||
{
|
||||
label: '计算分镜',
|
||||
key: 'compute_frame'
|
||||
},
|
||||
{ label: '分镜', key: 'framing' }
|
||||
],
|
||||
copywritingOptions: [
|
||||
{
|
||||
label: '提取文案设置',
|
||||
key: 'recognizing_setting'
|
||||
},
|
||||
{
|
||||
label: '停止提取',
|
||||
key: 'stop_recognizing'
|
||||
}
|
||||
],
|
||||
watermarkOptions: [
|
||||
{
|
||||
label: '去除水印设置',
|
||||
key: 'watermark_setting'
|
||||
},
|
||||
{
|
||||
label: '停止去除',
|
||||
key: 'stop_watermark'
|
||||
}
|
||||
],
|
||||
reverseOptions: [
|
||||
{
|
||||
label: 'MJ反推',
|
||||
key: 'mj_reverse'
|
||||
},
|
||||
{
|
||||
label: 'SD反推',
|
||||
key: 'sd_reverse'
|
||||
},
|
||||
{
|
||||
label: '清除反推数据',
|
||||
key: 'remove_reverse'
|
||||
},
|
||||
{
|
||||
label: '停止反推',
|
||||
key: 'stop_reverse'
|
||||
}
|
||||
],
|
||||
translateOptions: [
|
||||
{
|
||||
label: '英文 -> 中文',
|
||||
key: 'translate_chinese'
|
||||
},
|
||||
{
|
||||
label: '中文 -> 英文',
|
||||
key: 'translate_english'
|
||||
},
|
||||
{
|
||||
label: '翻译设置',
|
||||
key: 'translate_setting'
|
||||
},
|
||||
{
|
||||
label: '停止翻译',
|
||||
key: 'translate_stop'
|
||||
}
|
||||
],
|
||||
generateOptions: [
|
||||
{
|
||||
label: '停止生图',
|
||||
key: 'stop_image_generate'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="css">
|
||||
.right-button {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<div style="position: absolute; top: 0">
|
||||
<!-- <n-button size="tiny">123</n-button> -->
|
||||
</div>
|
||||
<n-image v-if="data.oldImage" width="110" :src="data.oldImage"> </n-image>
|
||||
<video v-else-if="data.data.videoPath" width="110" controls>
|
||||
<source :src="data.videoPath" type="video/mp4" />
|
||||
</video>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NImage, NButton } from 'naive-ui'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NImage, NButton },
|
||||
props: ['initData', 'index'],
|
||||
setup(props) {
|
||||
let message = useMessage()
|
||||
let data = ref(props.initData)
|
||||
onMounted(async () => {})
|
||||
|
||||
return {
|
||||
data
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
<div class="artplayer-app" style="height: 100%">
|
||||
<Artplayer @get-instance="getInstance" :option="option" :style="palyarStyle" />
|
||||
<n-log
|
||||
style="height: 60%; background-color: #f8f8f8"
|
||||
style="height: 60%; background-color: #f8f8f8; margin-top: 10px"
|
||||
ref="logInst"
|
||||
:log="logger"
|
||||
:loading="loading"
|
||||
@@ -15,7 +15,7 @@
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, nextTick, watchEffect } from 'vue'
|
||||
import { useMessage, NLog } from 'naive-ui'
|
||||
import Artplayer from '../../Components/Artplayer.vue'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage.ts'
|
||||
import { DEFINE_STRING } from '../../../../../define/define_string'
|
||||
|
||||
export default defineComponent({
|
||||
@@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<n-form
|
||||
ref="formRef"
|
||||
:model="bookTask"
|
||||
:rules="rules"
|
||||
label-width="auto"
|
||||
require-mark-placement="right-hanging"
|
||||
:size="size"
|
||||
:style="{
|
||||
maxWidth: '640px'
|
||||
}"
|
||||
>
|
||||
<n-form-item label="选择srt地址" path="srtPath">
|
||||
<n-input
|
||||
style="width: 300px; margin-right: 5px"
|
||||
v-model:value="bookTask.srtPath"
|
||||
type="text"
|
||||
placeholder="SRT字幕地址"
|
||||
/>
|
||||
<n-button color="#e5a84b" @click="SelectSrtFile">
|
||||
<n-icon :size="20">
|
||||
<folder-open />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</n-form-item>
|
||||
<n-form-item label="选择配音" path="audioPath">
|
||||
<n-input
|
||||
style="width: 300px; margin-right: 5px"
|
||||
v-model:value="bookTask.audioPath"
|
||||
type="text"
|
||||
placeholder="配音地址(mp3或wav)"
|
||||
/>
|
||||
<n-button color="#e5a84b" @click="SelectMusicFile">
|
||||
<n-icon :size="20">
|
||||
<folder-open />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</n-form-item>
|
||||
<n-form-item label="选择背景音乐文件夹(随机匹配,自动合成视频必选)" path="backgroundMusic">
|
||||
<n-select
|
||||
style="width: 300px"
|
||||
v-model:value="bookTask.backgroundMusic"
|
||||
filterable
|
||||
placeholder="选择样式"
|
||||
:options="backgroundMusicOptions"
|
||||
clearable
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item path="backgroundMusic">
|
||||
<n-button :disabled="type == 'book'" type="info" @click="UseBookVideoDataToBookTask">{{
|
||||
type == 'bookTsk' ? '应用主小说相关数据' : '当前就是用的主小说的数据'
|
||||
}}</n-button>
|
||||
<n-button type="info" style="margin-left: 10px" @click="SaveVideoData">保存数据</n-button>
|
||||
</n-form-item>
|
||||
<div v-if="type == 'bookTask'" style="color: red">注意:在生成草稿前要先保存数据</div>
|
||||
<div v-else style="color: red">
|
||||
注意:在生成草稿前要先保存数据,当前会生成全部的草稿,全部会使用上面的参数
|
||||
</div>
|
||||
<n-form-item style="display: flex; justify-content: flex-end">
|
||||
<n-button type="info" style="margin-left: 10px" @click="AddJianyingDraft">生成草稿</n-button>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NForm, NFormItem, NButton, NIcon, NInput, NSelect } from 'naive-ui'
|
||||
import { FolderOpen } from '@vicons/ionicons5'
|
||||
import { OperateBookType } from '../../../../../define/enum/bookEnum'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NForm, NFormItem, NButton, NIcon, NInput, NSelect, FolderOpen },
|
||||
props: ['bookTask', 'type'],
|
||||
setup(props) {
|
||||
let bookTask = ref(props.bookTask)
|
||||
let type = ref(props.type)
|
||||
let backgroundMusicOptions = ref([])
|
||||
let message = useMessage()
|
||||
onMounted(async () => {
|
||||
// 获取初始化的背景音乐列表
|
||||
await window.api.GetBackgroundMusicConfigList((value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
for (let i = 0; i < value.value.length; i++) {
|
||||
const element = value.value[i]
|
||||
let obj = {
|
||||
label: element.name,
|
||||
value: element.id
|
||||
}
|
||||
backgroundMusicOptions.value.push(obj)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* 选择对应的字幕文件
|
||||
*/
|
||||
async function SelectSrtFile() {
|
||||
window.api.SelectFile(['srt'], (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
bookTask.value.srtPath = value.value
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择对应的配音文件
|
||||
*/
|
||||
async function SelectMusicFile() {
|
||||
window.api.SelectFile(['mp3', 'wav'], (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
bookTask.value.audioPath = value.value
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用主小说相关数据
|
||||
*/
|
||||
async function UseBookVideoDataToBookTask() {
|
||||
if (type.value == 'book') {
|
||||
message.error('当前状态这个按钮不可用')
|
||||
return
|
||||
}
|
||||
let res = await window.book.UseBookVideoDataToBookTask(
|
||||
bookTask.value.id,
|
||||
OperateBookType.BOOKTASK
|
||||
)
|
||||
debugger
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
} else {
|
||||
// 将数据写回去
|
||||
bookTask.value.backgroundMusic = res.data.backgroundMusic
|
||||
bookTask.value.friendlyReminder = res.data.friendlyReminder
|
||||
bookTask.value.draftSrtStyle = res.data.draftSrtStyle
|
||||
bookTask.value.srtPath = res.data.srtPath
|
||||
bookTask.value.audioPath = res.data.audioPath
|
||||
|
||||
message.success('应用主小说相关数据成功')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存数据
|
||||
*/
|
||||
async function SaveVideoData() {
|
||||
let res = await window.db.UpdateBookTaskData(bookTask.value.id, {
|
||||
srtPath: bookTask.value.srtPath,
|
||||
audioPath: bookTask.value.audioPath,
|
||||
backgroundMusic: bookTask.value.backgroundMusic,
|
||||
friendlyReminder: bookTask.value.friendlyReminder,
|
||||
draftSrtStyle: bookTask.value.draftSrtStyle
|
||||
})
|
||||
if (res.code == 0) {
|
||||
message.error('保存小说批次数据失败')
|
||||
} else {
|
||||
message.success('保存小说批次数据成功')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加草稿
|
||||
*/
|
||||
async function AddJianyingDraft() {
|
||||
let res = await window.book.AddJianyingDraft(bookTask.value.id, OperateBookType.BOOKTASK)
|
||||
window.api.showGlobalMessageDialog(res)
|
||||
}
|
||||
|
||||
return {
|
||||
bookTask,
|
||||
type,
|
||||
AddJianyingDraft,
|
||||
SelectSrtFile,
|
||||
SelectMusicFile,
|
||||
SaveVideoData,
|
||||
UseBookVideoDataToBookTask,
|
||||
backgroundMusicOptions,
|
||||
rules: {
|
||||
srtPath: [
|
||||
{ required: true, message: '请选择背景音乐', trigger: ['input', 'blur', 'change'] }
|
||||
],
|
||||
audioPath: [
|
||||
{ required: true, message: '请选择音频文件', trigger: ['input', 'blur', 'change'] }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div id="book-setting">
|
||||
<n-card>
|
||||
<n-tabs
|
||||
class="card-tabs"
|
||||
default-value="mj_setting"
|
||||
size="large"
|
||||
animated
|
||||
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="sd_setting" tab="SD设置"> <SDSetting /> </n-tab-pane>
|
||||
<n-tab-pane name="export_video_setting" tab="导出视频设置">
|
||||
<VideoGenerateSetting />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="subtitle_setting" tab="识别文案设置">
|
||||
<SubtitleSetting />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="water_mark_setting" tab="水印设置">
|
||||
<WatermarkSetting />
|
||||
</n-tab-pane>
|
||||
</n-tabs>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<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 SDSetting from '../../Setting/SDSetting.vue'
|
||||
import VideoGenerateSetting from '../../Setting/VideoGenerateSetting.vue'
|
||||
import WatermarkSetting from '../../Setting/WatermarkSetting.vue'
|
||||
import SubtitleSetting from '../../Setting/SubtitleSetting.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NTabPane,
|
||||
NTabs,
|
||||
NCard,
|
||||
MJSetting,
|
||||
SDSetting,
|
||||
VideoGenerateSetting,
|
||||
WatermarkSetting,
|
||||
SubtitleSetting
|
||||
},
|
||||
|
||||
props: ['height'],
|
||||
setup(props) {
|
||||
let height = ref(props.height)
|
||||
onMounted(async () => {
|
||||
let div = document.getElementById('book-setting')
|
||||
div.style.height = height.value - 70 + 'px'
|
||||
div.style.overflow = 'auto'
|
||||
})
|
||||
|
||||
return { height }
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="css">
|
||||
#book-setting {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<div style="margin-bottom: 7px">
|
||||
<DatatableGptPromptButton :initData="data" :index="index" />
|
||||
</div>
|
||||
<div v-if="data.gptPrompt">
|
||||
<n-input
|
||||
type="textarea"
|
||||
size="tiny"
|
||||
v-model:value="data.gptPrompt"
|
||||
:autosize="{
|
||||
minRows: 6,
|
||||
maxRows: 6
|
||||
}"
|
||||
@input="InputDebounced"
|
||||
>
|
||||
</n-input>
|
||||
</div>
|
||||
<div v-else class="show-gpt-prompt">
|
||||
<div v-for="(item, index) in showReversePrompt" :key="index" style="margin-bottom: 5px">
|
||||
<n-input v-model:value="item.prompt" type="text" size="tiny"> </n-input>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, computed } from 'vue'
|
||||
import { useMessage, NButton, NInput, NSpin, NDropdown } from 'naive-ui'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import DatatableGptPromptButton from '../Components/DatatableGptPromptButton.vue'
|
||||
import { debounce } from 'lodash'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NButton, NInput, NSpin, NDropdown, DatatableGptPromptButton },
|
||||
props: ['initData', 'index'],
|
||||
setup(props) {
|
||||
let data = ref(props.initData)
|
||||
let index = ref(props.index)
|
||||
let message = useMessage()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
|
||||
// 做个计算属性
|
||||
let showReversePrompt = computed(() => {
|
||||
debugger
|
||||
let res = []
|
||||
for (let i = 0; i < data.value.reversePrompt.length; i++) {
|
||||
let item = data.value.reversePrompt[i]
|
||||
let res_obj = {
|
||||
...item
|
||||
}
|
||||
if (res_obj.promptCN) {
|
||||
res_obj.prompt = res_obj.promptCN
|
||||
}
|
||||
res.push(res_obj)
|
||||
}
|
||||
return res
|
||||
})
|
||||
onMounted(async () => {})
|
||||
|
||||
let InputDebounced = debounce(handleInput, 1000)
|
||||
|
||||
async function handleInput(value) {
|
||||
console.log('开始修改')
|
||||
let res = await window.db.UpdateBookTaskDetailData(data.value.id, {
|
||||
gptPrompt: value
|
||||
})
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
data,
|
||||
index,
|
||||
InputDebounced,
|
||||
reverseManageStore,
|
||||
showReversePrompt
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-data-table
|
||||
:columns="columns"
|
||||
:data="reverseManageStore.selectBookTaskDetail"
|
||||
:max-height="maxHeight"
|
||||
:scroll-x="1500"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, h } from 'vue'
|
||||
import { useMessage, NDataTable, NImage, NInput } from 'naive-ui'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import DataTableShowGenerateImage from '../../Original/Components/DataTableShowGenerateImage.vue'
|
||||
import ManageBookOldImage from '../Components/ManageBookOldImage.vue'
|
||||
import { BookType } from '../../../../../define/enum/bookEnum'
|
||||
import MJReversePrompt from './MJReversePrompt.vue'
|
||||
import DatatableHeaderGptPrompt from '../Components/DatatableHeaderGptPrompt.vue'
|
||||
import DatatableHeaderPrompt from '../Components/DatatableHeaderPrompt.vue'
|
||||
import DatatablePrompt from '../Components/DatatablePrompt.vue'
|
||||
import DatatableHeaderImage from '../Components/DatatableHeaderImage.vue'
|
||||
import DatatableAfterGpt from '../Components/DatatableAfterGpt.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NDataTable, NImage },
|
||||
|
||||
setup() {
|
||||
let softwareStore = useSoftwareStore()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let message = useMessage()
|
||||
let maxHeight = ref(0)
|
||||
|
||||
const createColumns = () => [
|
||||
{
|
||||
title: 'No.',
|
||||
key: 'name',
|
||||
width: 80,
|
||||
fixed: 'left'
|
||||
},
|
||||
{
|
||||
title: '文案',
|
||||
key: 'afterGpt',
|
||||
width: 200,
|
||||
fixed: 'left',
|
||||
render(row, index) {
|
||||
return h(DatatableAfterGpt, { initData: row, index: index })
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '图片/视频',
|
||||
key: 'oldImage',
|
||||
className: 'space-row',
|
||||
width: 130,
|
||||
render(row, index) {
|
||||
return h(ManageBookOldImage, {
|
||||
initData: row,
|
||||
index: index
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
title(row) {
|
||||
return h(DatatableHeaderGptPrompt)
|
||||
},
|
||||
key: 'gptPrompt',
|
||||
className: 'space-row',
|
||||
resizable: true,
|
||||
width: 400,
|
||||
minWidth: 400,
|
||||
maxWidth: 600,
|
||||
render(row, index) {
|
||||
if (reverseManageStore.selectBook.type == BookType.MJ_REVERSE) {
|
||||
return h(MJReversePrompt, {
|
||||
initData: row,
|
||||
index: index
|
||||
})
|
||||
} else if (reverseManageStore.selectBook.type == BookType.SD_REVERSE) {
|
||||
return h('span', ['SD 反推这边不能用', index])
|
||||
} else if (reverseManageStore.selectBook.type == BookType.ORIGINAL) {
|
||||
return h('span', ['原创 这边暂时不能用', index])
|
||||
}
|
||||
return h('span', ['不支持的类型', index])
|
||||
}
|
||||
},
|
||||
{
|
||||
title(row) {
|
||||
return h('div', { style: 'display: flex; align-items: center' }, [
|
||||
h('span', { size: 'tiny', style: 'margin-left: 5px' }, '生图提示词'),
|
||||
h(DatatableHeaderPrompt)
|
||||
])
|
||||
},
|
||||
className: 'space-row',
|
||||
key: 'row1',
|
||||
render(row, index) {
|
||||
return h(DatatablePrompt, {
|
||||
initData: row,
|
||||
index: index
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
title() {
|
||||
return h(DatatableHeaderImage)
|
||||
},
|
||||
width: 300,
|
||||
render(row, index) {
|
||||
return h(DataTableShowGenerateImage, {
|
||||
image_generate_category: 'mj',
|
||||
initData: row,
|
||||
index: index,
|
||||
type: 'data'
|
||||
})
|
||||
},
|
||||
fixed: 'right'
|
||||
}
|
||||
]
|
||||
|
||||
onMounted(async () => {
|
||||
debugger
|
||||
calcHeight()
|
||||
|
||||
setTimeout(() => {
|
||||
let div = document.getElementsByClassName('space-row')
|
||||
for (let i = 0; i < div.length; i++) {
|
||||
div[i].style.padding = '0px 5px'
|
||||
div[i].style.position = 'relative'
|
||||
}
|
||||
}, 100)
|
||||
|
||||
// 数据加载完毕
|
||||
let detailRes = await window.book.GetBookTaskDetail(reverseManageStore.selectBookTask.id)
|
||||
if (detailRes.code == 0) {
|
||||
message.error(detailRes.message)
|
||||
softwareStore.spin.spinning = false
|
||||
return
|
||||
}
|
||||
softwareStore.spin.spinning = false
|
||||
reverseManageStore.selectBookTaskDetail = detailRes.data
|
||||
})
|
||||
|
||||
function calcHeight() {
|
||||
debugger
|
||||
// 视口的高度
|
||||
let height = window.innerHeight
|
||||
maxHeight.value = height - 120
|
||||
}
|
||||
|
||||
return {
|
||||
softwareStore,
|
||||
reverseManageStore,
|
||||
maxHeight,
|
||||
columns: createColumns()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<div
|
||||
v-for="(item, index) in reversePrompts"
|
||||
style="margin-bottom: 5px; display: flex; align-items: center"
|
||||
>
|
||||
<div style="width: 600px">
|
||||
<n-input
|
||||
v-if="item.promptCN"
|
||||
v-model:value="item.promptCN"
|
||||
type="text"
|
||||
placeholder="promptCN"
|
||||
/>
|
||||
<n-input v-else v-model:value="item.prompt" type="text" placeholder="prompt" />
|
||||
</div>
|
||||
<n-button style="margin-left: 20px" type="info" @click="SaveSelectReversePrompt(item, index)"
|
||||
>保存</n-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NInput, NButton } from 'naive-ui'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NInput, NButton },
|
||||
props: ['reversePrompts', 'index'],
|
||||
setup(props) {
|
||||
let message = useMessage()
|
||||
let reversePrompts = ref(props.reversePrompts)
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
onMounted(async () => {})
|
||||
|
||||
/**
|
||||
* 选择反推的提示词,并修改对应的数据库数据
|
||||
*/
|
||||
async function SaveSelectReversePrompt(item, index) {
|
||||
let prompt = item.promptCN ? item.promptCN : item.prompt
|
||||
// 修改数据库数据
|
||||
let res = await window.book.SingleReverseToGptPrompt(
|
||||
reverseManageStore.selectBookTaskDetail[props.index].id,
|
||||
index
|
||||
)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
} else {
|
||||
// 修改前端数据
|
||||
reverseManageStore.selectBookTaskDetail[props.index].gptPrompt = res.data
|
||||
message.success('修改成功')
|
||||
}
|
||||
}
|
||||
|
||||
return { reversePrompts, SaveSelectReversePrompt, reverseManageStore }
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div style="display: flex; align-items: center">
|
||||
<n-select
|
||||
style="width: 300px; margin-right: 10px"
|
||||
v-model:value="selectIndex"
|
||||
:options="options"
|
||||
placeholder="选择用于出图的反推提示词位置"
|
||||
/>
|
||||
<n-button type="info" @click="SaveImagePrompt">保存</n-button>
|
||||
</div>
|
||||
<div style="color: red; margin-top: 10px">
|
||||
注意:点击保存之后,会将对应位置的反推提示词用于出图(未找到对应位置直接跳过)<br />改过后就不可逆,只能重新选择或者是手动修改
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NSelect, NButton } from 'naive-ui'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NSelect, NButton },
|
||||
|
||||
setup() {
|
||||
let selectIndex = ref(undefined)
|
||||
let message = useMessage()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
onMounted(async () => {})
|
||||
|
||||
/**
|
||||
* 保存数据,然后修改对应的数据
|
||||
*/
|
||||
async function SaveImagePrompt() {
|
||||
if (selectIndex.value == undefined) {
|
||||
message.error('请选择用于出图的反推提示词位置')
|
||||
return
|
||||
}
|
||||
// 将数据传入到后端,进行数据处理,然后返回数据,修改前端数据
|
||||
let res = await window.book.ReversePromptToGptPrompt(
|
||||
reverseManageStore.selectBook.id,
|
||||
reverseManageStore.selectBookTask.id,
|
||||
selectIndex.value
|
||||
)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
} else {
|
||||
reverseManageStore.selectBookTaskDetail = res.data
|
||||
message.success('保存成功')
|
||||
}
|
||||
// 后端数据处理完毕,前端重新处理一遍数据
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
selectIndex,
|
||||
SaveImagePrompt,
|
||||
reverseManageStore,
|
||||
options: [
|
||||
{
|
||||
label: '1',
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: '2',
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
label: '3',
|
||||
value: 3
|
||||
},
|
||||
{
|
||||
label: '4',
|
||||
value: 4
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
+16
-8
@@ -23,10 +23,9 @@ import { ref, onMounted, defineComponent, onUnmounted, toRaw, reactive, computed
|
||||
import { useMessage, NButton, NDataTable, NTag, NEllipsis } from 'naive-ui'
|
||||
import ManageBookButton from './Components/ManageBookButton.vue'
|
||||
import { useSoftwareStore } from '../../../../stores/software'
|
||||
import { useReverseManageStore } from '../../../../stores/reverseManage.js'
|
||||
import { useReverseManageStore } from '../../../../stores/reverseManage.ts'
|
||||
import { BookType } from '../../../../define/enum/bookEnum'
|
||||
import BookListAction from './Components/BookListAction.vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@@ -41,7 +40,6 @@ export default defineComponent({
|
||||
let softwareStore = useSoftwareStore()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let data = computed(() => reverseManageStore.GetBookData())
|
||||
const router = useRouter()
|
||||
let maxHeight = ref(0)
|
||||
// 分页设置
|
||||
const paginationReactive = (() => {
|
||||
@@ -69,7 +67,6 @@ export default defineComponent({
|
||||
|
||||
async function GetBookByCondition() {
|
||||
try {
|
||||
debugger
|
||||
let res = await reverseManageStore.GetBookDataFromDB({
|
||||
page: paginationReactive.page,
|
||||
pageSize: paginationReactive.pageSize
|
||||
@@ -84,6 +81,7 @@ export default defineComponent({
|
||||
}
|
||||
pagination.value.pageCount = res_count
|
||||
|
||||
debugger
|
||||
// 开始获取批次任务
|
||||
let bookTask = await reverseManageStore.GetBookTaskDataFromDB({
|
||||
bookId: reverseManageStore.selectBook.id
|
||||
@@ -113,6 +111,7 @@ export default defineComponent({
|
||||
// 监听窗口的大小变化
|
||||
window.addEventListener('resize', getMaxHeight)
|
||||
})
|
||||
|
||||
// 计算当前程序界面的高度,减去上下的高度,设置maxHegiht
|
||||
function getMaxHeight() {
|
||||
let height = window.innerHeight
|
||||
@@ -193,11 +192,20 @@ export default defineComponent({
|
||||
rowProps: (row) => {
|
||||
return {
|
||||
style: 'cursor: pointer;',
|
||||
onClick: () => {
|
||||
debugger
|
||||
message.info(row.id)
|
||||
onClick: async () => {
|
||||
reverseManageStore.selectBook = row
|
||||
router.push({ name: 'manage_book', params: { id: row.id } })
|
||||
softwareStore.spin.spinning = true
|
||||
softwareStore.spin.tip = '正在加载数据'
|
||||
|
||||
// 加载任务列表
|
||||
let bookTaskRes = await reverseManageStore.GetBookTaskDataFromDB({
|
||||
bookId: reverseManageStore.selectBook.id
|
||||
})
|
||||
softwareStore.spin.spinning = false
|
||||
if (bookTaskRes.code == 0) {
|
||||
message.error(bookTaskRes.message)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
<template>
|
||||
<div style="height: 100%; display: flex; width: 100%; overflow: auto">
|
||||
<div v-if="true" class="left_container" style="flex: 10; min-width: 500px">
|
||||
<ManageBookDetailButton />
|
||||
<ManageBookReverseTable style="margin-top: 10px" />
|
||||
</div>
|
||||
<div v-if="softwareStore.show_logger">
|
||||
<n-divider vertical style="height: 100%"></n-divider>
|
||||
</div>
|
||||
<div v-if="softwareStore.show_logger" class="right_container">
|
||||
<ManageBookShowLogger />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NDivider } from 'naive-ui'
|
||||
import ManageBookDetailButton from './Components/ManageBookDetailButton.vue'
|
||||
import ManageBookReverseTable from './MJReverse/ManageBookReverseTable.vue'
|
||||
import ManageBookShowLogger from './Components/ManageBookShowLogger.vue'
|
||||
import { useSoftwareStore } from '../../../../stores/software'
|
||||
import { DEFINE_STRING } from '../../../../define/define_string'
|
||||
import { DialogType } from '../../../../define/enum/bookEnum'
|
||||
import { ResponseMessageType } from '../../../../define/enum/softwareEnum'
|
||||
import { useReverseManageStore } from '../../../../stores/reverseManage'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
ManageBookDetailButton,
|
||||
ManageBookReverseTable,
|
||||
ManageBookShowLogger,
|
||||
NDivider
|
||||
},
|
||||
|
||||
setup() {
|
||||
debugger
|
||||
let message = useMessage()
|
||||
let softwareStore = useSoftwareStore()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
onMounted(async () => {
|
||||
// 添加一个总的监听器,主要监听后端数据变化,修改后端数据后,前端数据也会随之变化
|
||||
if (!window['mainReturn']) {
|
||||
window.mainReturn = true
|
||||
window.api.setEventListen([DEFINE_STRING.BOOK.MAIN_DATA_RETURN], (value) => {
|
||||
// 这边是不监听的数据
|
||||
if (value.type == ResponseMessageType.HD_IMAGE) {
|
||||
return
|
||||
}
|
||||
if (value.code == 0) {
|
||||
switch (value.dialogType) {
|
||||
case DialogType.DIALOG:
|
||||
window.api.showGlobalMessageDialog(value)
|
||||
break
|
||||
case DialogType.MESSAGE:
|
||||
message.error(value.message)
|
||||
break
|
||||
case DialogType.NOTIFICATION:
|
||||
window.api.showGlobalNotificationDialog(value)
|
||||
break
|
||||
default:
|
||||
window.api.showGlobalNotificationDialog(value)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 执行对应的方法,修改数据
|
||||
switch (value.type) {
|
||||
case ResponseMessageType.MJ_REVERSE:
|
||||
MJReverseResponse(value)
|
||||
break
|
||||
case ResponseMessageType.PROMPT_TRANSLATE:
|
||||
PromptTranslateResponse(value)
|
||||
break
|
||||
case ResponseMessageType.MJ_IMAGE:
|
||||
MJImageResponse(value)
|
||||
break
|
||||
case ResponseMessageType.HD_IMAGE:
|
||||
break
|
||||
default:
|
||||
message.error('未知的返回数据类型')
|
||||
break
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
function MJImageResponse(value) {
|
||||
debugger
|
||||
console.log(value)
|
||||
//开始修改
|
||||
if (value.data) {
|
||||
let dataIndex = reverseManageStore.selectBookTaskDetail.findIndex(
|
||||
(item) => item.id == value.data.id
|
||||
)
|
||||
if (dataIndex >= 0) {
|
||||
reverseManageStore.selectBookTaskDetail[dataIndex].mj_message = value.data
|
||||
reverseManageStore.selectBookTaskDetail[dataIndex].outImagePath = value.data.outImagePath
|
||||
reverseManageStore.selectBookTaskDetail[dataIndex].subImagePath = value.data.subImagePath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理翻译返回的数据,主要是将翻译的数据放到对应的位置
|
||||
* @param value 返回的数据,数据结构如下
|
||||
* bookTaskDetailId: string // 分镜ID
|
||||
* reversePromptId: string // 反推提示词ID
|
||||
* from: string // 源语言
|
||||
* to: string // 目标语言 to 是 zh 值重新保存到 promptCN 中,to 是 en ,需要重新覆盖prompt和prom
|
||||
* prompt: string // 英文数据
|
||||
* promptCN: string // 中文翻译数据(但是也可以存储英文)
|
||||
*/
|
||||
function PromptTranslateResponse(value) {
|
||||
if (!value.data) {
|
||||
return
|
||||
}
|
||||
// 修改进度
|
||||
softwareStore.spin.tip = `翻译中 ... ${value.data.progress} / ${value.data.total}`
|
||||
let detailIndex = reverseManageStore.selectBookTaskDetail.findIndex(
|
||||
(item) => item.id == value.data.bookTaskDetailId
|
||||
)
|
||||
if (detailIndex < 0) {
|
||||
return
|
||||
}
|
||||
let dataObj = reverseManageStore.selectBookTaskDetail[detailIndex]
|
||||
let reverseIndex = dataObj.reversePrompt.findIndex(
|
||||
(item) => item.id == value.data.reversePromptId
|
||||
)
|
||||
if (reverseIndex < 0) {
|
||||
return
|
||||
}
|
||||
if (value.data.to == 'en') {
|
||||
reverseManageStore.selectBookTaskDetail[detailIndex].reversePrompt[reverseIndex].prompt =
|
||||
value.data.prompt
|
||||
reverseManageStore.selectBookTaskDetail[detailIndex].reversePrompt[reverseIndex].promptCN =
|
||||
value.data.promptCN
|
||||
} else if (value.data.to == 'zh') {
|
||||
reverseManageStore.selectBookTaskDetail[detailIndex].reversePrompt[reverseIndex].promptCN =
|
||||
value.data.promptCN
|
||||
} else {
|
||||
message.error('未知的翻译目标语言')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MJ反推返回数据
|
||||
*/
|
||||
function MJReverseResponse(value) {
|
||||
if (value.data && value.data.progress == 100) {
|
||||
let dataIndex = reverseManageStore.selectBookTaskDetail.findIndex(
|
||||
(item) => item.id == value.data.id
|
||||
)
|
||||
if (dataIndex >= 0) {
|
||||
reverseManageStore.selectBookTaskDetail[dataIndex].reversePrompt = JSON.parse(
|
||||
value.data.prompt
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { softwareStore, reverseManageStore }
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="css">
|
||||
.right_container {
|
||||
flex: 2;
|
||||
min-width: 200px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<div style="margin-bottom: 5px; margin-left: 5px; display: flex; align-items: center">
|
||||
<n-button :render-icon="renderIcon" size="small" type="info" @click="AddBookDialog"
|
||||
>新增</n-button
|
||||
>
|
||||
<n-button style="margin-left: 5px" size="small" type="info" @click="HDImageAll"
|
||||
>一键高清</n-button
|
||||
>
|
||||
<n-button style="margin-left: 5px" type="info" size="small" @click="DraftAll"
|
||||
>一键草稿</n-button
|
||||
>
|
||||
<n-button style="margin-left: 5px" type="info" size="small" @click="VideoAll"
|
||||
>一键视频</n-button
|
||||
>
|
||||
<n-button style="margin-left: 5px" type="info" size="small" @click="ResetAll"
|
||||
>一键重置</n-button
|
||||
>
|
||||
<n-button style="margin-left: 5px" type="info" size="small" @click="DeleteAll"
|
||||
>一键删除</n-button
|
||||
>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<n-data-table
|
||||
:columns="columns"
|
||||
:data="reverseManageStore.bookTaskData"
|
||||
:scroll-x="800"
|
||||
:row-props="rowProps"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch, h } from 'vue'
|
||||
import { useMessage, useDialog, NButton, NDataTable, NIcon } from 'naive-ui'
|
||||
import { useReverseManageStore } from '../../../../stores/reverseManage'
|
||||
import { useSoftwareStore } from '../../../../stores/software'
|
||||
import { AddSharp } from '@vicons/ionicons5'
|
||||
import BookTaskListAction from './Components/BookTaskListAction.vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { OperateBookType } from '../../../../define/enum/bookEnum'
|
||||
import { DEFINE_STRING } from '../../../../define/define_string'
|
||||
import { ResponseMessageType } from '../../../../define/enum/softwareEnum'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NButton,
|
||||
NDataTable,
|
||||
BookTaskListAction
|
||||
},
|
||||
|
||||
setup() {
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let softwareStore = useSoftwareStore()
|
||||
let dialog = useDialog()
|
||||
const router = useRouter()
|
||||
let message = useMessage()
|
||||
onMounted(async () => {
|
||||
window.api.setEventListen([DEFINE_STRING.BOOK.MAIN_DATA_RETURN], (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
if (value.type == ResponseMessageType.HD_IMAGE) {
|
||||
softwareStore.spin.tip = `正在高清中 ${value.data.current} / ${value.data.total}`
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.api.removeEventListen([DEFINE_STRING.BOOK.MAIN_DATA_RETURN])
|
||||
})
|
||||
|
||||
function createColumns() {
|
||||
return [
|
||||
{
|
||||
title: 'No.',
|
||||
key: 'no',
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
title: '名称',
|
||||
key: 'name',
|
||||
width: 130
|
||||
},
|
||||
{
|
||||
title: '风格',
|
||||
key: 'styleList'
|
||||
},
|
||||
{
|
||||
title: '前缀',
|
||||
key: 'prefix',
|
||||
width: 130
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 215,
|
||||
fixed: 'right',
|
||||
render(row, index) {
|
||||
return h(BookTaskListAction, {
|
||||
bookTask: row
|
||||
})
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* 高清数据
|
||||
*/
|
||||
async function hdImageFunc(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 HDImageAll() {
|
||||
alert('高清全部')
|
||||
softwareStore.spin.spinning = true
|
||||
softwareStore.spin.tip = '正在进行高清检查。。。'
|
||||
let checkImage = await window.book.CheckImageFileSize(
|
||||
reverseManageStore.selectBook.id,
|
||||
10240,
|
||||
OperateBookType.BOOK
|
||||
)
|
||||
softwareStore.spin.spinning = false
|
||||
if (checkImage.code == 0) {
|
||||
message.error(checkImage.message)
|
||||
return
|
||||
}
|
||||
// 高清检查完成
|
||||
if (checkImage.data && checkImage.data.length > 0) {
|
||||
// 出现了图片大的,用户判断是不是需要高清
|
||||
let msg = checkImage.data.map((item, index) => {
|
||||
return item.outImagePath + '\n'
|
||||
})
|
||||
dialog.warning({
|
||||
title: '高清警告',
|
||||
content: '下面的图片大于10MB,是否继续高清?' + '\n' + msg,
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: async () => {
|
||||
alert('确认高清')
|
||||
await hdImageFunc(reverseManageStore.selectBook.id, OperateBookType.BOOK)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 没有就直接高清
|
||||
await hdImageFunc(reverseManageStore.selectBook.id, OperateBookType.BOOK)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 一键生成草稿
|
||||
*/
|
||||
async function DraftAll() {
|
||||
alert('草稿全部')
|
||||
}
|
||||
|
||||
/**
|
||||
* 一键生成视频
|
||||
*/
|
||||
async function VideoAll() {
|
||||
alert('视频全部')
|
||||
}
|
||||
|
||||
/**
|
||||
* 一键重置
|
||||
*/
|
||||
async function ResetAll() {
|
||||
alert('重置全部')
|
||||
}
|
||||
|
||||
/**
|
||||
* 一键删除
|
||||
*/
|
||||
async function DeleteAll() {
|
||||
alert('删除全部')
|
||||
}
|
||||
|
||||
return {
|
||||
reverseManageStore,
|
||||
HDImageAll,
|
||||
DraftAll,
|
||||
VideoAll,
|
||||
ResetAll,
|
||||
DeleteAll,
|
||||
columns: createColumns(),
|
||||
renderIcon() {
|
||||
return h(NIcon, null, {
|
||||
default: () => h(AddSharp, { size: '40', color: 'white' }, {})
|
||||
})
|
||||
},
|
||||
rowProps: (row) => {
|
||||
return {
|
||||
style: 'cursor: pointer;',
|
||||
onClick: async () => {
|
||||
// message.info(row.id)
|
||||
reverseManageStore.selectBookTask = row
|
||||
softwareStore.spin.spinning = true
|
||||
softwareStore.spin.tip = '正在加载数据'
|
||||
// 跳转
|
||||
router.push({ name: 'manage_book', params: { id: row.id } })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
+6
-1
@@ -24,7 +24,7 @@ import { useMessage, NSplit, NSpin, NFloatButton, NIcon, NBadge } from 'naive-ui
|
||||
import ManageBook from './ManageBook.vue'
|
||||
import ManageBookTask from './ManageBookTask.vue'
|
||||
import { useSoftwareStore } from '../../../../stores/software'
|
||||
import { useReverseManageStore } from '../../../../stores/reverseManage.js'
|
||||
import { useReverseManageStore } from '../../../../stores/reverseManage.ts'
|
||||
import { Layers } from '@vicons/ionicons5'
|
||||
|
||||
export default defineComponent({
|
||||
@@ -38,6 +38,11 @@ export default defineComponent({
|
||||
|
||||
onMounted(() => {})
|
||||
|
||||
onUnmounted(() => {
|
||||
debugger
|
||||
reverseManageStore.selectBookTaskDetail = undefined
|
||||
})
|
||||
|
||||
return {
|
||||
isShowTask,
|
||||
softwareStore,
|
||||
@@ -10,7 +10,7 @@
|
||||
<script>
|
||||
import { defineComponent, ref, onMounted } from "vue";
|
||||
import { NButton, useMessage, NSpin, NSpace, NSelect, NDivider, NInput, NCode } from "naive-ui"
|
||||
import { DEFINE_STRING } from "../../../../define/define_string.js"
|
||||
import { DEFINE_STRING } from "../../../../define/define_string"
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NButton, NSpin, NSpace, NSelect, NDivider, NInput, NCode
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<script>
|
||||
import { defineComponent, ref, onMounted } from "vue";
|
||||
import { NButton, useMessage, NSpin, NSpace, NSelect, NDivider, NInput } from "naive-ui"
|
||||
import { DEFINE_STRING } from "../../../../define/define_string.js"
|
||||
import { DEFINE_STRING } from "../../../../define/define_string"
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NButton, NSpin, NSpace, NSelect, NDivider, NInput
|
||||
|
||||
@@ -46,10 +46,10 @@
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
"
|
||||
>{{ image.prompt }}</span
|
||||
>{{ image.label }}</span
|
||||
>
|
||||
</template>
|
||||
<span>{{ image.prompt }}</span>
|
||||
<span>{{ image.label }}</span>
|
||||
</n-popover>
|
||||
</div>
|
||||
</div>
|
||||
@@ -119,7 +119,7 @@ export default defineComponent({
|
||||
AddStyleTags,
|
||||
NPopover
|
||||
},
|
||||
props: ['selectStyle', 'height', 'tags'],
|
||||
props: ['selectStyle', 'height', 'tags', 'imageStyle', 'customizeImageStyle'],
|
||||
setup(props) {
|
||||
let current_menu = null
|
||||
let selectedKeyRef = ref(null)
|
||||
@@ -174,9 +174,22 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
if (!tags.value) {
|
||||
// 没有接收到数据,这边要重新初始化
|
||||
await window.mj.GetTagDataByTypeAndProperty(['dynamic', null], (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
tags.value = value.data
|
||||
})
|
||||
}
|
||||
|
||||
await InitStyleData()
|
||||
|
||||
setLayoutHeight('layout_height')
|
||||
await window.api.GetImageStyleMenu((value) => {
|
||||
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
@@ -193,11 +206,43 @@ export default defineComponent({
|
||||
selectedKeyRef.value = current_menu
|
||||
})
|
||||
|
||||
// 初始化选中的数据
|
||||
async function InitStyleData() {
|
||||
debugger
|
||||
if (!props.imageStyle || !props.customizeImageStyle) {
|
||||
return
|
||||
}
|
||||
selectStyle.value = []
|
||||
// 开始初始化
|
||||
await window.api.GetImageStyleInfomation(JSON.stringify(props.imageStyle), (value) => {
|
||||
debugger
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
selectStyle.value.push(...value.data)
|
||||
})
|
||||
// 获取自定义的
|
||||
await window.mj.GetTagDataByTypeAndProperty(['dynamic', 'style_tags'], (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
let styleData = value.data
|
||||
for (let i = 0; i < styleData.length; i++) {
|
||||
const element = styleData[i]
|
||||
if (props.customizeImageStyle.includes(element.key)) {
|
||||
element.id = element.key
|
||||
selectStyle.value.push(element)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单选中事件
|
||||
*/
|
||||
async function SelectMenu(key, item) {
|
||||
|
||||
current_menu = key
|
||||
await getStyleImageSubList()
|
||||
}
|
||||
@@ -214,7 +259,6 @@ export default defineComponent({
|
||||
style_image_list.value = tags.value.style_tags
|
||||
} else {
|
||||
await window.api.getStyleImageSubList(current_menu, (value) => {
|
||||
|
||||
console.log(value)
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
@@ -232,7 +276,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
async function closeTag(image) {
|
||||
|
||||
debugger
|
||||
let index = selectStyle.value.findIndex((item) => item.id == image.id)
|
||||
if (index != -1) {
|
||||
selectStyle.value.splice(index, 1)
|
||||
@@ -268,7 +312,6 @@ export default defineComponent({
|
||||
handleSelect(key) {
|
||||
showDropdownRef.value = false
|
||||
if (key == 'selectStyle') {
|
||||
|
||||
// 将当前的风格添加到选择的风格中
|
||||
if (current_img.value) {
|
||||
selectStyle.value.push(current_img.value)
|
||||
|
||||
@@ -56,7 +56,7 @@ export default defineComponent({
|
||||
onMounted(async () => {})
|
||||
|
||||
async function closeTag(image) {
|
||||
|
||||
debugger
|
||||
let index = selectStyle.value.findIndex((item) => item.id == image.id)
|
||||
if (index != -1) {
|
||||
selectStyle.value.splice(index, 1)
|
||||
|
||||
@@ -56,7 +56,7 @@ import {
|
||||
} from '@vicons/ionicons5'
|
||||
import CheckMachineId from '../Components/CheckMachineId.vue'
|
||||
import axios from 'axios'
|
||||
import { DEFINE_STRING } from '../../../../define/define_string.js'
|
||||
import { DEFINE_STRING } from '../../../../define/define_string'
|
||||
import ShowMessage from './ShowMessage.vue'
|
||||
import { MD5 } from 'crypto-js'
|
||||
import InputDialogContent from '../Original/Components/InputDialogContent.vue'
|
||||
@@ -88,8 +88,7 @@ export default defineComponent({
|
||||
if (option.key == 'sdoriginal') return h(NIcon, null, { default: () => h(PaperPlaneOutline) })
|
||||
if (option.key == 'setting') return h(NIcon, null, { default: () => h(SettingsOutline) })
|
||||
if (option.key == 'gptCopywriting') return h(NIcon, null, { default: () => h(BookOutline) })
|
||||
if (option.key == 'reverse_management')
|
||||
return h(NIcon, null, { default: () => h(GridOutline) })
|
||||
if (option.key == 'book_management') return h(NIcon, null, { default: () => h(GridOutline) })
|
||||
if (option.key == 'backward_matrix')
|
||||
return h(NIcon, null, { default: () => h(DuplicateOutline) })
|
||||
if (option.key == 'TTS_Services') return h(NIcon, null, { default: () => h(RadioOutline) })
|
||||
@@ -186,7 +185,7 @@ export default defineComponent({
|
||||
let title = '成功'
|
||||
if (value.code == 0) {
|
||||
type = 'error'
|
||||
title = '成功但失败'
|
||||
title = '成功但失败1'
|
||||
} else if (value.code == 2) {
|
||||
;(type = 'warning'), (title = '警告')
|
||||
}
|
||||
@@ -265,7 +264,7 @@ export default defineComponent({
|
||||
key: 'sdoriginal'
|
||||
},
|
||||
{
|
||||
label: '反推矩阵',
|
||||
label: '超级矩阵',
|
||||
key: 'backward_matrix',
|
||||
children: [
|
||||
{
|
||||
@@ -341,14 +340,14 @@ export default defineComponent({
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'reverse_management'
|
||||
name: 'book_management'
|
||||
}
|
||||
},
|
||||
{
|
||||
default: () => '一键反推'
|
||||
default: () => '聚合推文'
|
||||
}
|
||||
),
|
||||
key: 'reverse_management'
|
||||
key: 'book_management'
|
||||
},
|
||||
// {
|
||||
// label: "剪辑",
|
||||
@@ -452,37 +451,37 @@ export default defineComponent({
|
||||
key: 'mj_setting'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'test_options'
|
||||
}
|
||||
},
|
||||
{
|
||||
default: () => '测试操作'
|
||||
}
|
||||
),
|
||||
key: 'test_options'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'TTS_Services'
|
||||
}
|
||||
},
|
||||
{
|
||||
default: () => '语音服务'
|
||||
}
|
||||
),
|
||||
key: 'TTS_Services'
|
||||
}
|
||||
// {
|
||||
// label: () =>
|
||||
// h(
|
||||
// RouterLink,
|
||||
// {
|
||||
// to: {
|
||||
// name: 'test_options'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// default: () => '测试操作'
|
||||
// }
|
||||
// ),
|
||||
// key: 'test_options'
|
||||
// },
|
||||
// {
|
||||
// label: () =>
|
||||
// h(
|
||||
// RouterLink,
|
||||
// {
|
||||
// to: {
|
||||
// name: 'TTS_Services'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// default: () => '语音服务'
|
||||
// }
|
||||
// ),
|
||||
// key: 'TTS_Services'
|
||||
// }
|
||||
]
|
||||
|
||||
return {
|
||||
|
||||
@@ -111,6 +111,11 @@ export default defineComponent({
|
||||
* @param {*} row 要生图的行数据
|
||||
*/
|
||||
async function SingleGenerateImage() {
|
||||
// 检查当前数据是不是有被锁定
|
||||
if (row.value.imageLock) {
|
||||
message.error('当前数据已经被锁定,无法生图')
|
||||
return
|
||||
}
|
||||
let ca = window.config.image_generate_category ? window.config.image_generate_category : 'sd'
|
||||
// 判断当前的生图模式
|
||||
if (ca == 'sd') {
|
||||
|
||||
@@ -28,14 +28,19 @@
|
||||
</div>
|
||||
<div v-else-if="type == 'data'">
|
||||
<div style="height: 22px; display: flex" v-if="select_image_category == 'mj'">
|
||||
<div>进度:{{ data.mj_message?.progress }}%</div>
|
||||
<div style="z-index: 100">
|
||||
进度:{{ data.mj_message ? data.mj_message.progress : data.mjMessage?.progress }}%
|
||||
</div>
|
||||
<n-tag
|
||||
v-if="data.mj_message?.status != 'error'"
|
||||
v-if="(data.mj_message ? data.mj_message.status : data.mjMessage?.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
|
||||
(data.mj_message ? data.mj_message.status : data.mjMessage?.status != null) &&
|
||||
(data.mj_message ? data.mj_message.status : data.mjMessage?.status != '')
|
||||
? data.mj_message
|
||||
? data.mj_message.status
|
||||
: data.mjMessage?.status
|
||||
: 'wait'
|
||||
}}</n-tag
|
||||
>
|
||||
@@ -44,10 +49,25 @@
|
||||
<template #trigger>
|
||||
<n-tag style="height: 18px; margin: 2px 0 2px 0" type="error">error</n-tag>
|
||||
</template>
|
||||
<span>{{ data.mj_message?.message }}</span>
|
||||
<span>{{ data.mj_message ? data.mj_message.message : data.mjMessage?.message }}</span>
|
||||
</n-popover>
|
||||
</div>
|
||||
<div style="margin-left: 5px">{{ data.mj_message?.message_id }}</div>
|
||||
<n-popover style="padding: 0; margin: 0" trigger="hover">
|
||||
<template #trigger>
|
||||
<div
|
||||
style="
|
||||
margin-left: 5px;
|
||||
width: 100px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
"
|
||||
>
|
||||
{{ data.mj_message ? data.mj_message.message_id : data.mjMessage?.messageId }}
|
||||
</div>
|
||||
</template>
|
||||
<span>{{ data.mj_message ? data.mj_message.message_id : data.mjMessage?.messageId }}</span>
|
||||
</n-popover>
|
||||
</div>
|
||||
<div></div>
|
||||
<div
|
||||
@@ -56,15 +76,25 @@
|
||||
@drop="imageDragDrop"
|
||||
@dragover="imageDragOver"
|
||||
>
|
||||
<div style="display: flex; align-items: center">
|
||||
<div style="display: flex; align-items: center; position: relative">
|
||||
<n-image
|
||||
class="g-image-class generate-image-show"
|
||||
v-if="outImagePath"
|
||||
:src="outImagePath"
|
||||
:src="outImagePath ? outImagePath : space_image"
|
||||
fit="cover"
|
||||
width="120"
|
||||
height="120"
|
||||
/>
|
||||
<n-button
|
||||
text
|
||||
:type="data.imageLock ? 'error' : 'primary'"
|
||||
style="font-size: 24px; position: absolute; left: -12px; top: -0"
|
||||
@click="ModifyLock"
|
||||
>
|
||||
<n-icon>
|
||||
<LockClosed v-if="data.imageLock" />
|
||||
<LockOpen v-else />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</div>
|
||||
<div>
|
||||
<n-divider vertical style="height: 100%" />
|
||||
@@ -102,10 +132,13 @@ import {
|
||||
NButton,
|
||||
NSelect,
|
||||
NPopover,
|
||||
NTag
|
||||
NTag,
|
||||
NIcon
|
||||
} from 'naive-ui'
|
||||
import { usePromptStore } from '../../../../../stores/prompt'
|
||||
import { useImageStore } from '../../../../../stores/image'
|
||||
import { LockClosed, LockOpen } from '@vicons/ionicons5'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@@ -115,9 +148,12 @@ export default defineComponent({
|
||||
NButton,
|
||||
NSelect,
|
||||
NPopover,
|
||||
NTag
|
||||
NTag,
|
||||
NIcon,
|
||||
LockClosed,
|
||||
LockOpen
|
||||
},
|
||||
props: ['initData', 'type', 'image_generate_category', 'func'],
|
||||
props: ['initData', 'type', 'image_generate_category', 'func', 'index'],
|
||||
setup(props) {
|
||||
let imageStore = useImageStore()
|
||||
let promptStore = usePromptStore()
|
||||
@@ -128,11 +164,11 @@ export default defineComponent({
|
||||
let outImagePath = ref(props.initData.outImagePath)
|
||||
let sd_batch_size = ref(null)
|
||||
let width = ref(null)
|
||||
|
||||
let dragTarget = null
|
||||
|
||||
let space_image = ref(window.config.space_image)
|
||||
let image_options = ref([])
|
||||
let select_image_category = ref(props.image_generate_category)
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
|
||||
watch(
|
||||
() => select_image_category.value,
|
||||
@@ -171,7 +207,6 @@ export default defineComponent({
|
||||
|
||||
onMounted(async () => {
|
||||
await window.api.InitSDConfig((value) => {
|
||||
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
@@ -219,7 +254,6 @@ export default defineComponent({
|
||||
|
||||
// 图片拖拽结束事件
|
||||
async function imageDragDrop(e) {
|
||||
|
||||
console.log('end', e.target, dragTarget)
|
||||
// 判断原始数据是不是为空
|
||||
// if (dragTarget == null) {
|
||||
@@ -288,13 +322,43 @@ export default defineComponent({
|
||||
await props.func.oneSplitFour()
|
||||
}
|
||||
|
||||
async function ModifyLock() {
|
||||
// 锁定之前,判断是不是有
|
||||
if (!outImagePath.value) {
|
||||
message.error('没有生成图片,不能锁定')
|
||||
return
|
||||
}
|
||||
let lock = !data.value.imageLock
|
||||
|
||||
if (
|
||||
reverseManageStore.selectBookTaskDetail &&
|
||||
reverseManageStore.selectBookTaskDetail.length > 0
|
||||
) {
|
||||
// 修改数据库数据
|
||||
let res = await window.db.UpdateBookTaskDetailData(data.value.id, {
|
||||
imageLock: lock
|
||||
})
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
message.success('图片锁定/解锁成功')
|
||||
reverseManageStore.selectBookTaskDetail[props.index].imageLock = data.value.imageLock
|
||||
data.value.imageLock = lock
|
||||
} else {
|
||||
data.value.imageLock = lock
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
data,
|
||||
type,
|
||||
image_options,
|
||||
sd_batch_size,
|
||||
ModifyLock,
|
||||
width,
|
||||
images,
|
||||
space_image,
|
||||
outImagePath,
|
||||
imageDragStart,
|
||||
imageDragDrop,
|
||||
@@ -302,7 +366,8 @@ export default defineComponent({
|
||||
select_image_category,
|
||||
UpdateImageGenerateCategory,
|
||||
MJGetImage,
|
||||
OneSplitFour
|
||||
OneSplitFour,
|
||||
reverseManageStore
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
<template>
|
||||
<div id="import_word_and_srt">
|
||||
<div style="height: 30px; margin-bottom: 5px">
|
||||
<n-button color="#1e90ff" size="small" style="margin-left: 20px" @click="OpenOneDialog"
|
||||
<n-button
|
||||
v-if="type == 'original'"
|
||||
color="#1e90ff"
|
||||
size="small"
|
||||
style="margin-left: 20px"
|
||||
@click="OpenOneDialog"
|
||||
>导入字幕</n-button
|
||||
>
|
||||
<n-button color="#1e90ff" size="small" style="margin-left: 20px" @click="ImportSrtAndGetTime"
|
||||
@@ -32,7 +37,8 @@ import { h, defineComponent, onMounted, ref, toRaw, watch, onUnmounted } from 'v
|
||||
import { NButton, NDataTable, useMessage, NInput, NImage, useDialog } from 'naive-ui'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import EditWord from './EditWord.vue'
|
||||
import { checkStringValueDeleteSuffix } from '../../../../../main/generalTools'
|
||||
import { checkStringValueDeleteSuffix } from '../../../../../main/Public/generalTools'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
const buttonArr = [
|
||||
{
|
||||
title: '下对齐',
|
||||
@@ -49,16 +55,18 @@ export default defineComponent({
|
||||
NInput,
|
||||
NImage
|
||||
},
|
||||
props: ['initData', 'menuType', 'height'],
|
||||
props: ['initData', 'menuType', 'height', 'type'],
|
||||
setup(props) {
|
||||
let hh = props.height
|
||||
let maxHeight = props.height - 80
|
||||
let data = ref(props.initData)
|
||||
let data = ref(JSON.parse(JSON.stringify(props.initData)))
|
||||
const message = useMessage()
|
||||
let dialog = useDialog()
|
||||
let selectKey = ref([])
|
||||
let editWordRef = ref(null)
|
||||
let wenkeRef = ref(null)
|
||||
let type = ref(props.type ? props.type : 'original')
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
|
||||
const createColumns = ({ AlignNextWord }) => {
|
||||
return [
|
||||
@@ -351,6 +359,7 @@ export default defineComponent({
|
||||
|
||||
// 判断当前行的文案和洗稿后文件是不是还有。(没有的话直接删除)
|
||||
if (
|
||||
data.value[thisIndex] &&
|
||||
data.value[thisIndex].subValue == null &&
|
||||
(row.word == null || row.word == '' || row.after_gpt == null || row.after_gpt == '')
|
||||
) {
|
||||
@@ -513,40 +522,58 @@ export default defineComponent({
|
||||
* 保存字幕文案信息,用于自动生成视频
|
||||
*/
|
||||
async function SaveCopywritingInformation() {
|
||||
if (props.menuType == 'mj') {
|
||||
await window.mj.SvaeMJWordSrt([toRaw(data.value), 'srt_time_information'], (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
message.success('保存成功')
|
||||
})
|
||||
return
|
||||
} else {
|
||||
// 先保存单个文件(然后在config文件中指向对应的文件)
|
||||
await window.api.OriginalAddWebuiJson(JSON.stringify(data.value), async (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
if (value.data) {
|
||||
for (let i = 0; i < data.value.length; i++) {
|
||||
let name = String(data.value[i].no).padStart(5, '0')
|
||||
data.value[i].prompt_json = value.data + '/' + name + '.png.json'
|
||||
data.value[i].name = name + '.png'
|
||||
if (type.value == 'original') {
|
||||
if (props.menuType == 'mj') {
|
||||
await window.mj.SvaeMJWordSrt([toRaw(data.value), 'srt_time_information'], (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
}
|
||||
await window.api.SaveCopywritingInformation(
|
||||
[toRaw(data.value), 'srt_time_information'],
|
||||
(value) => {
|
||||
if (value.code != 1) {
|
||||
message.error('未知错误')
|
||||
return
|
||||
message.success('保存成功')
|
||||
})
|
||||
return
|
||||
} else {
|
||||
// 先保存单个文件(然后在config文件中指向对应的文件)
|
||||
await window.api.OriginalAddWebuiJson(JSON.stringify(data.value), async (value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
if (value.data) {
|
||||
for (let i = 0; i < data.value.length; i++) {
|
||||
let name = String(data.value[i].no).padStart(5, '0')
|
||||
data.value[i].prompt_json = value.data + '/' + name + '.png.json'
|
||||
data.value[i].name = name + '.png'
|
||||
}
|
||||
message.success('保存成功')
|
||||
}
|
||||
)
|
||||
})
|
||||
await window.api.SaveCopywritingInformation(
|
||||
[toRaw(data.value), 'srt_time_information'],
|
||||
(value) => {
|
||||
if (value.code != 1) {
|
||||
message.error('未知错误')
|
||||
return
|
||||
}
|
||||
message.success('保存成功')
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
} else if (type.value == 'mj_reverse' || type.value == 'sd_reverse') {
|
||||
debugger
|
||||
if (data.value.length != reverseManageStore.selectBookTaskDetail.length) {
|
||||
message.error('检测到导入的字幕数据和分镜对不上,请先对齐')
|
||||
return
|
||||
}
|
||||
// 将对齐后的数据写入到数据库中
|
||||
for (let i = 0; i < data.value.length; i++) {
|
||||
const element = data.value[i]
|
||||
let res = await window.db.UpdateBookTaskDetailData(element.id, {
|
||||
startTime: element.start_time,
|
||||
endTime: element.end_time,
|
||||
timeLimit: element.timeLimit,
|
||||
subValue: JSON.stringify(element.subValue)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -651,7 +678,9 @@ export default defineComponent({
|
||||
OpenOneDialog,
|
||||
maxHeight,
|
||||
hh,
|
||||
wenkeRef
|
||||
wenkeRef,
|
||||
type,
|
||||
reverseManageStore
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -56,7 +56,7 @@ import {
|
||||
checkStringValueAddPrefix,
|
||||
checkStringValueAddSuffix,
|
||||
checkStringValueDeleteSuffix
|
||||
} from '../../../../main/generalTools'
|
||||
} from '../../../../main/Public/generalTools'
|
||||
|
||||
import { usePromptStore } from '../../../../stores/prompt'
|
||||
|
||||
@@ -751,12 +751,22 @@ export default defineComponent({
|
||||
* @param {*} row
|
||||
*/
|
||||
async function NextGenerateImage(row, ca = 'sd') {
|
||||
debugger
|
||||
let index = data.value.findIndex((item) => item.id == row.id)
|
||||
let tempData = []
|
||||
for (let i = index; i < data.value.length; i++) {
|
||||
const element = data.value[i]
|
||||
tempData.push(element)
|
||||
}
|
||||
|
||||
// 筛选下面被锁定的数据
|
||||
tempData = tempData.filter((item) => item.imageLock == false)
|
||||
|
||||
if (tempData.length <= 0) {
|
||||
message.error('下面的数据都被锁定,无法生图,请检查')
|
||||
return
|
||||
}
|
||||
|
||||
// 判断当前的生图模式
|
||||
if (ca == 'sd') {
|
||||
// 生成SD生图
|
||||
|
||||
@@ -127,13 +127,13 @@ export default defineComponent({
|
||||
* 初始化数据
|
||||
*/
|
||||
async function InItPromptSort() {
|
||||
await window.pmpt.GetPromptSort((value) => {
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
promptStore.InitPromptSort(value.data)
|
||||
})
|
||||
let promptSortRes = await window.pmpt.GetPromptSort()
|
||||
|
||||
if (promptSortRes.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
promptStore.InitPromptSort(promptSortRes.data)
|
||||
}
|
||||
|
||||
// 导入提示词
|
||||
|
||||
@@ -222,7 +222,8 @@ export default defineComponent({
|
||||
async function GenerateImageAll() {
|
||||
let tmpData = cloneDeep(toRaw(data.value))
|
||||
tmpData = tmpData.filter((item) => {
|
||||
return item.outImagePath == null || item.outImagePath == ''
|
||||
// return item.outImagePath == null || item.outImagePath == ''
|
||||
return !item.imageLoak
|
||||
})
|
||||
|
||||
if (tmpData.length == 0) {
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-button strong secondary @click="RetuenMain"> 返回 </n-button>
|
||||
<n-dropdown trigger="hover" :options="AutoOptions" @select="SelectAutoAction">
|
||||
<n-button color="#ee7959" @click="AutoAction" style="margin-left: 5px"> 自动开始 </n-button>
|
||||
</n-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NButton, NCheckbox, NDropdown } from 'naive-ui'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NButton,
|
||||
NCheckbox,
|
||||
NDropdown
|
||||
},
|
||||
|
||||
setup() {
|
||||
let router = useRouter()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
// 获取当前这个界面的数据
|
||||
onMounted(async () => {})
|
||||
|
||||
// 返回主页
|
||||
function RetuenMain() {
|
||||
router.push('/reverse_management')
|
||||
}
|
||||
|
||||
// 自动开始
|
||||
async function AutoAction() {
|
||||
// 开始自动执行。先分镜,后面在添加任务中
|
||||
let res_frame = await window.book.AutoAction(reverseManageStore.selectBook.id)
|
||||
}
|
||||
|
||||
// 选择自动开始的操作(停止或者是继续)
|
||||
async function SelectAutoAction() {}
|
||||
|
||||
return {
|
||||
RetuenMain,
|
||||
AutoAction,
|
||||
reverseManageStore,
|
||||
AutoOptions: [
|
||||
{
|
||||
label: '停止任务',
|
||||
value: 'auto_stop'
|
||||
},
|
||||
{
|
||||
label: '继续任务',
|
||||
value: 'auto_continue'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,37 +0,0 @@
|
||||
<template>
|
||||
<div style="height: 100%; display: flex; width: 100%; overflow: auto">
|
||||
<div v-if="true" class="left_container" style="flex: 10; min-width: 600px">
|
||||
<ManageBookDetailButton />
|
||||
<ManageBookReverseTable style="margin-top: 10px" />
|
||||
</div>
|
||||
<div >
|
||||
<n-divider vertical style="height: 100%"></n-divider>
|
||||
</div>
|
||||
<div class="right_container" style="flex: 3; min-width: 250px">
|
||||
<ManageBookShowLogger />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NDivider } from 'naive-ui'
|
||||
import ManageBookDetailButton from './Components/ManageBookDetailButton.vue'
|
||||
import ManageBookReverseTable from './Components/ManageBookReverseTable.vue'
|
||||
import ManageBookShowLogger from './Components/ManageBookShowLogger.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
ManageBookDetailButton,
|
||||
ManageBookReverseTable,
|
||||
ManageBookShowLogger,
|
||||
NDivider
|
||||
},
|
||||
|
||||
setup() {
|
||||
onMounted(async () => {})
|
||||
|
||||
return {}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,21 +0,0 @@
|
||||
<template>
|
||||
<div>按钮</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NButton, NDataTable } from 'naive-ui'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
NButton,
|
||||
NDataTable
|
||||
},
|
||||
|
||||
setup() {
|
||||
onMounted(async () => {})
|
||||
|
||||
return {}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -45,7 +45,6 @@ export default defineComponent({
|
||||
|
||||
onMounted(async () => {
|
||||
document.getElementById('AddMultiRemoteMj').style.height = props.height - 60 + 'px'
|
||||
debugger
|
||||
let remoteMjSettingRes = await window.setting.GetRemoteMJSettings()
|
||||
if (remoteMjSettingRes.code == 0) {
|
||||
message.error('获取代理MJ配置失败')
|
||||
@@ -58,7 +57,6 @@ export default defineComponent({
|
||||
* 添加和编辑账号
|
||||
*/
|
||||
async function ManageAccount(remote = null) {
|
||||
debugger
|
||||
if (remote == null) {
|
||||
settingStore.ResetActionRemoteMJ()
|
||||
} else {
|
||||
|
||||
@@ -80,6 +80,20 @@
|
||||
placeholder="GPT Key"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
v-if="formValue.gpt_business == 'b44c6f24-59e4-4a71-b2c7-3df0c4e35e65'"
|
||||
style="width: 120px; margin-left: 30px"
|
||||
path="gpt_key"
|
||||
label="LAI 站点选择"
|
||||
>
|
||||
<n-select
|
||||
v-model:value="formValue.laiApiSelect"
|
||||
placeholder="选择LAIAPI的请求站点"
|
||||
style="width: 200px"
|
||||
:options="laiApiOptions"
|
||||
>
|
||||
</n-select>
|
||||
</n-form-item>
|
||||
<n-form-item style="margin-left: 30px" path="gpt_model" label="GPT模型">
|
||||
<n-select
|
||||
v-model:value="formValue.gpt_model"
|
||||
@@ -115,47 +129,7 @@
|
||||
</n-button>
|
||||
</n-form-item>
|
||||
<n-form-item path="translation_setting" label="翻译设置">
|
||||
<n-form-item path="translation_business" label="翻译服务商">
|
||||
<n-select
|
||||
v-model:value="formValue.translation_business"
|
||||
:options="translation_options"
|
||||
@update:value="SwitchTranslate"
|
||||
placeholder="翻译服务商"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
path="translation_app_id"
|
||||
label="APP ID"
|
||||
style="width: 300px; margin-left: 30px"
|
||||
>
|
||||
<n-input
|
||||
type="password"
|
||||
show-password-on="mousedown"
|
||||
v-model:value="formValue.translation_app_id"
|
||||
@keydown.enter.prevent
|
||||
placeholder="APP ID"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
path="translation_secret"
|
||||
label="产品密钥"
|
||||
style="width: 300px; margin-left: 30px"
|
||||
>
|
||||
<n-input
|
||||
type="password"
|
||||
show-password-on="mousedown"
|
||||
v-model:value="formValue.translation_secret"
|
||||
placeholder="请输入产品密钥"
|
||||
></n-input>
|
||||
</n-form-item>
|
||||
<n-form-item
|
||||
path="translation_secret"
|
||||
label="自动翻译"
|
||||
style="width: 300px; margin-left: 30px"
|
||||
>
|
||||
<n-checkbox v-model:checked="formValue.translation_auto"></n-checkbox>
|
||||
</n-form-item>
|
||||
<n-button color="#e18a3b" @click="ModifyTranslateSetting"> 翻译设置 </n-button>
|
||||
</n-form-item>
|
||||
<n-form-item>
|
||||
<n-button
|
||||
@@ -199,6 +173,9 @@ 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: {
|
||||
@@ -234,7 +211,8 @@ export default defineComponent({
|
||||
translation_auto: window.config.translation_auto,
|
||||
theme: softwareStore.softWare.theme,
|
||||
character_select_model: window.config.character_select_model,
|
||||
window_wh_bm_remember: window.config.window_wh_bm_remember
|
||||
window_wh_bm_remember: window.config.window_wh_bm_remember,
|
||||
laiApiSelect: window.config.laiApiSelect ? window.config.laiApiSelect : LaiAPIType.MAIN
|
||||
})
|
||||
let show = ref(false)
|
||||
let gpt_options = ref([])
|
||||
@@ -271,25 +249,6 @@ export default defineComponent({
|
||||
await InitGptOptions()
|
||||
})
|
||||
|
||||
let translation_options = [
|
||||
{
|
||||
label: '百度翻译',
|
||||
value: 'https://fanyi-api.baidu.com/api/trans/vip/translate'
|
||||
},
|
||||
{
|
||||
label: '火山引擎',
|
||||
value: 'https://translate.volcengineapi.com?'
|
||||
},
|
||||
{
|
||||
label: '腾讯翻译',
|
||||
value: 'https://tmt.tencentcloudapi.com'
|
||||
},
|
||||
{
|
||||
label: '阿里翻译',
|
||||
value: 'https://mt.cn-hangzhou.aliyuncs.com'
|
||||
}
|
||||
]
|
||||
|
||||
// 切换翻译服务商事件
|
||||
function SwitchTranslate(value, option) {
|
||||
// 将之前的数据全部删除
|
||||
@@ -468,6 +427,24 @@ export default defineComponent({
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 进行翻译设置
|
||||
*/
|
||||
async function ModifyTranslateSetting() {
|
||||
// 判断当前数据是不是存在
|
||||
// 处理数据。获取当前的所有的数据
|
||||
let dialogWidth = window.innerWidth * 0.8
|
||||
let dialogHeight = window.innerHeight * 0.9
|
||||
// ImportWordAndSrt
|
||||
dialog.create({
|
||||
showIcon: false,
|
||||
title: '翻译设置',
|
||||
content: () => h(TranslateSetting),
|
||||
style: `width : ${dialogWidth}px; height : ${dialogHeight}px`,
|
||||
maskClosable: false
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
formRef,
|
||||
ChangeMode,
|
||||
@@ -476,7 +453,6 @@ export default defineComponent({
|
||||
handleValidateButtonClick,
|
||||
rules,
|
||||
SwitchTranslate,
|
||||
translation_options,
|
||||
gpt_model_options,
|
||||
gpt_options,
|
||||
show,
|
||||
@@ -487,7 +463,40 @@ export default defineComponent({
|
||||
SelectProjectFolder,
|
||||
AddGptPrompt,
|
||||
character_select_model_options,
|
||||
softwareStore
|
||||
softwareStore,
|
||||
ModifyTranslateSetting,
|
||||
laiApiOptions: [
|
||||
{
|
||||
label: '主站点',
|
||||
value: LaiAPIType.MAIN
|
||||
},
|
||||
{
|
||||
label: '香港站点',
|
||||
value: LaiAPIType.HK_PROXY
|
||||
},
|
||||
{
|
||||
label: '香港站点',
|
||||
value: LaiAPIType.HK_PROXY
|
||||
}
|
||||
],
|
||||
translation_options: [
|
||||
{
|
||||
label: '百度翻译',
|
||||
value: TranslateAPIType.BAIDU
|
||||
},
|
||||
{
|
||||
label: '腾讯翻译',
|
||||
value: TranslateAPIType.TENCENT
|
||||
},
|
||||
{
|
||||
label: '火山翻译',
|
||||
value: TranslateAPIType.VOLCENGINE
|
||||
},
|
||||
{
|
||||
label: '阿里翻译',
|
||||
value: TranslateAPIType.ALI
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div>ManageBookReverseTable</div>
|
||||
<div>识别文案设置</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -0,0 +1,182 @@
|
||||
<template>
|
||||
<div style="display: flex">
|
||||
<div style="display: flex; align-items: center">
|
||||
<div style="width: 200px">选择翻译服务商:</div>
|
||||
<n-select v-model:value="translateSetting.selectModel" :options="translateOptions"></n-select>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; margin-left: 20px">
|
||||
<n-checkbox v-model:checked="translateSetting.translation_auto"> 是否自动翻译 </n-checkbox>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; margin-left: 20px">
|
||||
<n-button :type="block ? 'warning' : 'primary'" @click="ModifyBlock">{{
|
||||
block ? '解锁' : '锁定'
|
||||
}}</n-button>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; margin-left: 20px">
|
||||
<n-button type="error" @click="ResetTranslateSetting">重置数据</n-button>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; margin-left: 20px">
|
||||
<n-button type="info" @click="SaveTranslateSetting">保存</n-button>
|
||||
</div>
|
||||
</div>
|
||||
<n-card
|
||||
v-for="item in translateSetting.translates"
|
||||
style="margin-top: 10px"
|
||||
:title="GetTranslationName(item.name)"
|
||||
size="medium"
|
||||
>
|
||||
<n-form label-placement="left" inline="">
|
||||
<n-form-item label="API URL:">
|
||||
<n-input :disabled="block" style="width: 250px" v-model:value="item.translation_business" />
|
||||
</n-form-item>
|
||||
<n-form-item label="APP ID/应用ID:">
|
||||
<n-input
|
||||
type="password"
|
||||
show-password-on="mousedown"
|
||||
v-model:value="item.translation_app_id"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="产品密钥:">
|
||||
<n-input
|
||||
type="password"
|
||||
show-password-on="mousedown"
|
||||
v-model:value="item.translation_secret"
|
||||
/>
|
||||
</n-form-item>
|
||||
<!-- </div> -->
|
||||
</n-form>
|
||||
</n-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import {
|
||||
useMessage,
|
||||
useDialog,
|
||||
NCard,
|
||||
NInput,
|
||||
NSelect,
|
||||
NButton,
|
||||
NCheckbox,
|
||||
NForm,
|
||||
NFormItem
|
||||
} from 'naive-ui'
|
||||
import { TranslateAPIType } from '../../../../define/enum/translate'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NCard, NInput, NSelect, NButton, NCheckbox, NForm, NFormItem },
|
||||
|
||||
setup() {
|
||||
let message = useMessage()
|
||||
let dialog = useDialog()
|
||||
let translateSetting = ref({})
|
||||
let block = ref(true)
|
||||
onMounted(async () => {
|
||||
// 初始化加载数据
|
||||
let translateSettingRes = await window.translate.GetTranslateSetting()
|
||||
if (translateSettingRes.code == 0) {
|
||||
message.error(translateSettingRes.message)
|
||||
return
|
||||
}
|
||||
translateSetting.value = translateSettingRes.data
|
||||
})
|
||||
|
||||
function GetTranslationName(name) {
|
||||
switch (name) {
|
||||
case 'baidu':
|
||||
return '百度翻译'
|
||||
case 'tencent':
|
||||
return '腾讯翻译'
|
||||
case 'volcengine':
|
||||
return '火山翻译'
|
||||
case 'ali':
|
||||
return '阿里翻译'
|
||||
default:
|
||||
message.error('未知的翻译类型')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置翻译设置
|
||||
*/
|
||||
async function ResetTranslateSetting() {
|
||||
dialog.warning({
|
||||
title: '重置翻译设置',
|
||||
content: '注意,该操作不可逆,是否重置翻译设置?',
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: async () => {
|
||||
let res = await window.translate.ResetTranslateSetting()
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
translateSetting.value = res.data
|
||||
message.success('重置翻译设置成功')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存翻译设置
|
||||
*/
|
||||
async function SaveTranslateSetting() {
|
||||
debugger
|
||||
// 判断当前选中的数据是不是设置完善
|
||||
let selectModel = translateSetting.value.selectModel
|
||||
let settingIndex = translateSetting.value.translates.findIndex(
|
||||
(item) => (item.name = selectModel)
|
||||
)
|
||||
if (settingIndex < 0) {
|
||||
message.error('未找到选中的数据,请检查')
|
||||
return
|
||||
}
|
||||
let detailSetting = translateSetting.value.translates[settingIndex]
|
||||
for (const key in detailSetting) {
|
||||
if (!detailSetting[key]) {
|
||||
message.error('选中的翻译商,对应的设置未完善,请检查')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 开始保存
|
||||
let saveRes = await window.translate.SaveTranslateSetting(toRaw(translateSetting.value))
|
||||
window.api.showGlobalMessageDialog(saveRes)
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改锁定状态
|
||||
*/
|
||||
async function ModifyBlock() {
|
||||
block.value = !block.value
|
||||
}
|
||||
|
||||
return {
|
||||
translateSetting,
|
||||
GetTranslationName,
|
||||
ResetTranslateSetting,
|
||||
SaveTranslateSetting,
|
||||
ModifyBlock,
|
||||
block,
|
||||
translateOptions: [
|
||||
{
|
||||
label: '百度翻译',
|
||||
value: TranslateAPIType.BAIDU
|
||||
},
|
||||
{
|
||||
label: '腾讯翻译',
|
||||
value: TranslateAPIType.TENCENT
|
||||
},
|
||||
{
|
||||
label: '火山翻译',
|
||||
value: TranslateAPIType.VOLCENGINE
|
||||
},
|
||||
{
|
||||
label: '阿里翻译',
|
||||
value: TranslateAPIType.ALI
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div>
|
||||
<div style="margin-left: 10px">
|
||||
<!-- <n-checkbox size="small" v-model:checked="mask_setting.isRemote"> 使用iopaint </n-checkbox> -->
|
||||
<n-form label-placement="left">
|
||||
<n-form-item label="选择去水印的方式" style="width: 400px">
|
||||
<n-select v-model:value="watermarkSetting.selectModel" :options="options" />
|
||||
<n-button type="info" style="margin-left: 10px" @click="SaveWatermarkSetting"
|
||||
>保存</n-button
|
||||
>
|
||||
</n-form-item>
|
||||
|
||||
<n-card title="本地Lama" size="medium">
|
||||
<span class="url_class" @click="OpenTeach('lama')">lama安装教程</span>
|
||||
</n-card>
|
||||
<n-card title="Iopaint" style="margin-top: 20px" size="large">
|
||||
<n-form-item label="Iopaint地址" style="width: 400px">
|
||||
<n-input v-model:value="watermarkSetting.iopaint.url" placeholder="请输入Iopaint地址" />
|
||||
</n-form-item>
|
||||
<div style="margin-top: 5px">
|
||||
<span class="url_class" @click="OpenTeach('iopaint')" style="margin-left: 5px"
|
||||
>iopaint安装教程</span
|
||||
>
|
||||
</div>
|
||||
</n-card>
|
||||
</n-form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch } from 'vue'
|
||||
import { useMessage, NInput, NButton, NSelect, NForm, NFormItem, NCard } from 'naive-ui'
|
||||
import { RemoveWatermarkType } from '../../../../define/enum/waterMarkAndSubtitle'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NInput, NButton, NSelect, NForm, NFormItem, NCard },
|
||||
|
||||
setup() {
|
||||
let message = useMessage()
|
||||
let watermarkSetting = ref({
|
||||
selectModel: RemoveWatermarkType.LOCAL_LAMA,
|
||||
iopaint: {
|
||||
url: undefined
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
// 再加载的时候。获取一下配置
|
||||
let initRes = await window.setting.GetWaterMarkSetting()
|
||||
if (initRes.code == 1) {
|
||||
watermarkSetting.value = initRes.data
|
||||
} else {
|
||||
message.error(initRes.message)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 打开环境安装网站
|
||||
*/
|
||||
function OpenTeach(type) {
|
||||
switch (type) {
|
||||
case 'lama':
|
||||
window.api.OpenUrl(
|
||||
'https://rvgyir5wk1c.feishu.cn/docx/RZYCdG7ZpoKsIzxBEzccNEIFn8f#QOIRdJQvEouJB7xv0Xqcx3zInyb'
|
||||
)
|
||||
break
|
||||
case 'iopaint':
|
||||
window.api.OpenUrl(
|
||||
'https://rvgyir5wk1c.feishu.cn/docx/RZYCdG7ZpoKsIzxBEzccNEIFn8f#MLoUdn5cfo6NJTxL0xTcUGyLn43'
|
||||
)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 保存去除水印设置
|
||||
async function SaveWatermarkSetting() {
|
||||
if (watermarkSetting.value.selectModel == RemoveWatermarkType.IOPAINT) {
|
||||
if (!watermarkSetting.value.iopaint.url) {
|
||||
message.error('请输入iopaint地址')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!watermarkSetting.value.selectModel) {
|
||||
message.error('请选择去水印的方式')
|
||||
}
|
||||
|
||||
let saveRes = await window.setting.SaveWaterMarkSetting(toRaw(watermarkSetting.value))
|
||||
window.api.showGlobalMessageDialog(saveRes)
|
||||
}
|
||||
return {
|
||||
watermarkSetting,
|
||||
SaveWatermarkSetting,
|
||||
OpenTeach,
|
||||
options: [
|
||||
{
|
||||
label: '本地lama',
|
||||
value: RemoveWatermarkType.LOCAL_LAMA
|
||||
},
|
||||
{
|
||||
label: 'iopaint',
|
||||
value: RemoveWatermarkType.IOPAINT
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.url_class {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.url_class:hover {
|
||||
color: brown;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
@@ -4,29 +4,39 @@
|
||||
label-placement="left"
|
||||
label-width="auto"
|
||||
require-mark-placement="right-hanging"
|
||||
:model="edgeTTs"
|
||||
:model="settingStore.ttsSetting.edgeTTS"
|
||||
>
|
||||
<n-form-item label="合成角色">
|
||||
<n-select v-model:value="edgeTTs.value" :options="roleOptions" />
|
||||
<n-select
|
||||
@update:value="ChangeCharacter"
|
||||
v-model:value="settingStore.ttsSetting.edgeTTS.value"
|
||||
:options="roleOptions"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="音量">
|
||||
<n-input-number v-model:value="edgeTTs.volumn" :min="0" :max="100" />
|
||||
<n-input-number
|
||||
v-model:value="settingStore.ttsSetting.edgeTTS.volumn"
|
||||
:min="0"
|
||||
:max="100"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="语速">
|
||||
<n-input-number v-model:value="edgeTTs.rate" :min="0" :max="100" />
|
||||
<n-input-number v-model:value="settingStore.ttsSetting.edgeTTS.rate" :min="0" :max="100" />
|
||||
</n-form-item>
|
||||
<n-form-item label="语调">
|
||||
<n-input-number v-model:value="edgeTTs.pitch" :min="0" :max="100" />
|
||||
<n-input-number v-model:value="settingStore.ttsSetting.edgeTTS.pitch" :min="0" :max="100" />
|
||||
</n-form-item>
|
||||
<n-form-item label="生成SRT">
|
||||
<n-checkbox v-model:checked="edgeTTs.saveSubtitles"> 复选框 </n-checkbox>
|
||||
<n-checkbox v-model:checked="settingStore.ttsSetting.edgeTTS.saveSubtitles">
|
||||
复选框
|
||||
</n-checkbox>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, watch } from 'vue'
|
||||
import { ref, onMounted, defineComponent, watch, inject } from 'vue'
|
||||
import {
|
||||
useMessage,
|
||||
NForm,
|
||||
@@ -40,7 +50,7 @@ import {
|
||||
} from 'naive-ui'
|
||||
import { GetEdgeTTSRole } from '../../../../define/tts/ttsDefine'
|
||||
import { ReaderOutline } from '@vicons/ionicons5'
|
||||
import { useSoftwareStore } from '../../../../stores/software'
|
||||
import { useSettingStore } from '../../../../stores/setting'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@@ -54,18 +64,9 @@ export default defineComponent({
|
||||
ReaderOutline,
|
||||
NPopover
|
||||
},
|
||||
props: ['edgeTTs'],
|
||||
setup(props) {
|
||||
let edgeTTs = ref(props.edgeTTs)
|
||||
let message = useMessage()
|
||||
let softwareStore = useSoftwareStore()
|
||||
|
||||
watch(
|
||||
() => props.edgeTTs,
|
||||
(val) => {
|
||||
edgeTTs.value = val
|
||||
}
|
||||
)
|
||||
let settingStore = useSettingStore()
|
||||
|
||||
let roleOptions = ref([])
|
||||
onMounted(async () => {
|
||||
@@ -73,7 +74,20 @@ export default defineComponent({
|
||||
roleOptions.value = GetEdgeTTSRole()
|
||||
})
|
||||
|
||||
return { edgeTTs, roleOptions, softwareStore }
|
||||
/**
|
||||
* 切换角色的时候,修改角色的配置
|
||||
*/
|
||||
function ChangeCharacter(value) {
|
||||
debugger
|
||||
let role = roleOptions.value.find(
|
||||
(item) => item.value === value
|
||||
)
|
||||
settingStore.ttsSetting.edgeTTS.value = role.value
|
||||
settingStore.ttsSetting.edgeTTS.label = role.label
|
||||
settingStore.ttsSetting.edgeTTS.lang = role.lang
|
||||
settingStore.ttsSetting.edgeTTS.gender = role.gender
|
||||
}
|
||||
return { roleOptions, settingStore, ChangeCharacter }
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -41,20 +41,16 @@
|
||||
<n-form-item label="选择配音渠道">
|
||||
<n-select
|
||||
placeholder="请选择配音渠道"
|
||||
v-model:value="ttsConfig.selectModel"
|
||||
v-model:value="settingStore.ttsSetting.selectModel"
|
||||
:options="ttsOptions"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
<EdgeTTS
|
||||
:edgeTTs="ttsConfig.edgeTTS"
|
||||
ref="edgettsRef"
|
||||
v-if="ttsConfig.selectModel == 'edge-tts'"
|
||||
/>
|
||||
<EdgeTTS :ref="edgettsRef" v-if="settingStore.ttsSetting.selectModel == 'edge-tts'" />
|
||||
<AzureTTS
|
||||
:azureTTS="ttsConfig.azureTTS"
|
||||
ref="azurettsRef"
|
||||
v-else-if="ttsConfig.selectModel == 'azure-tts'"
|
||||
:azureTTS="settingStore.ttsSetting.azureTTS"
|
||||
:ref="azurettsRef"
|
||||
v-else-if="settingStore.ttsSetting.selectModel == 'azure-tts'"
|
||||
/>
|
||||
</div>
|
||||
<div class="autio-button">
|
||||
@@ -81,19 +77,14 @@
|
||||
</n-button>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center">
|
||||
<audio
|
||||
ref="audio"
|
||||
src="D:\\3.大力\\1\\1719165587206_6cd74afd-ff56-4ba7-abc9-9021a70ac9c7.wav"
|
||||
controls
|
||||
style="width: 100%"
|
||||
></audio>
|
||||
<audio ref="audio" :src="audioUrl" controls style="width: 100%"></audio>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, watch, h } from 'vue'
|
||||
import { ref, onMounted, defineComponent, onUnmounted, toRaw, reactive, h } from 'vue'
|
||||
import {
|
||||
useMessage,
|
||||
NInput,
|
||||
@@ -111,6 +102,7 @@ import { GetTTSSelect } from '../../../../define/tts/ttsDefine'
|
||||
import { useSoftwareStore } from '../../../../stores/software'
|
||||
import { AddCircleOutline } from '@vicons/ionicons5'
|
||||
import InputDialogContent from '../Original/Components/InputDialogContent.vue'
|
||||
import { useSettingStore } from '../../../../stores/setting'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@@ -136,24 +128,14 @@ export default defineComponent({
|
||||
let edgettsRef = ref(null)
|
||||
let azurettsRef = ref(null)
|
||||
let splitRef = ref(null)
|
||||
let ttsConfig = ref({
|
||||
selectModel: 'edge-tts',
|
||||
edgeTTS: {
|
||||
name: 'zh-CN-XiaoxiaoNeural',
|
||||
gender: 'Female',
|
||||
label: '晓晓',
|
||||
lang: 'zh-CN',
|
||||
pitch: '0', // 语调
|
||||
rate: '10', // 倍速
|
||||
volumn: '0' // 音量
|
||||
}
|
||||
})
|
||||
let settingStore = useSettingStore()
|
||||
let writeSetting = ref({
|
||||
split_char: '。,“”‘’!?【】《》()…—:;.,\'\'""!?[]<>()...-:;',
|
||||
merge_count: 3,
|
||||
merge_char: ',',
|
||||
end_char: '。'
|
||||
})
|
||||
let audioUrl = ref(null)
|
||||
|
||||
onMounted(async () => {
|
||||
ttsOptions.value = GetTTSSelect()
|
||||
@@ -163,7 +145,7 @@ export default defineComponent({
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
} else {
|
||||
ttsConfig.value = res.data
|
||||
settingStore.ttsSetting = res.data
|
||||
}
|
||||
|
||||
// 加载文字设置
|
||||
@@ -255,7 +237,14 @@ export default defineComponent({
|
||||
/**
|
||||
* 保存TTS配置信息
|
||||
*/
|
||||
async function SaveTTSConfig() {}
|
||||
async function SaveTTSConfig() {
|
||||
let saveRes = await window.tts.SaveTTSConfig(toRaw(settingStore.ttsSetting))
|
||||
if (saveRes.code == 0) {
|
||||
message.error(saveRes.message)
|
||||
return
|
||||
}
|
||||
message.success('TTS配置保存成功')
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始合成音频
|
||||
@@ -266,22 +255,31 @@ export default defineComponent({
|
||||
return
|
||||
}
|
||||
|
||||
if (ttsConfig.value.selectModel == 'edge-tts') {
|
||||
// let res =
|
||||
} else if (ttsConfig.value.selectModel == 'azure-tts') {
|
||||
}
|
||||
}
|
||||
softwareStore.spin.spinning = true
|
||||
softwareStore.spin.tip = '正在合成音频,请稍等...'
|
||||
|
||||
/**
|
||||
* 保存配置信息
|
||||
*/
|
||||
async function SaveTTSConfig() {}
|
||||
let saveRes = await window.tts.SaveTTSConfig(toRaw(settingStore.ttsSetting))
|
||||
if (saveRes.code == 0) {
|
||||
softwareStore.spin.spinning = false
|
||||
message.error(saveRes.message)
|
||||
return
|
||||
}
|
||||
|
||||
let generateRes = await window.tts.GenerateAudio(text.value)
|
||||
if (generateRes.code == 0) {
|
||||
softwareStore.spin.spinning = false
|
||||
message.error(generateRes.message)
|
||||
return
|
||||
}
|
||||
audioUrl.value = generateRes.data
|
||||
softwareStore.spin.spinning = false
|
||||
}
|
||||
|
||||
return {
|
||||
text,
|
||||
azurettsRef,
|
||||
edgettsRef,
|
||||
ttsConfig,
|
||||
settingStore,
|
||||
writeSetting,
|
||||
softwareStore,
|
||||
ModifySplitChar,
|
||||
@@ -289,6 +287,7 @@ export default defineComponent({
|
||||
FormatWord,
|
||||
ClearText,
|
||||
splitRef,
|
||||
audioUrl,
|
||||
GenerateAudio,
|
||||
ttsOptions: [{ label: 'Edge TTS(免费)', value: 'edge-tts' }]
|
||||
}
|
||||
|
||||
@@ -1,67 +1,70 @@
|
||||
<template>
|
||||
<div id="video-canvas" style="position: relative">
|
||||
<video ref="videoRef" muted style="width: 100%" :src="videoSrc" id="video" autoplay></video>
|
||||
<canvas
|
||||
ref="canvasRef"
|
||||
@mousemove="handleMouseMove"
|
||||
@mousedown="handleMouseDown"
|
||||
@mouseup="handleMouseUp"
|
||||
style="position: absolute; top: 0; left: 0; pointer-events: auto"
|
||||
/>
|
||||
<n-divider />
|
||||
<div class="option-button">
|
||||
<n-button @click="SetVideoMuted" :color="buttonColor">{{
|
||||
isMuted ? '取消静音' : '开启静音'
|
||||
}}</n-button>
|
||||
<n-button
|
||||
@click="SaveSelectPosition"
|
||||
style="margin-left: 5px"
|
||||
:loading="SaveSelectPositionLodding"
|
||||
:color="softwareStore.SoftColor.BROWN_YELLOW"
|
||||
>保存位置</n-button
|
||||
>
|
||||
<n-button
|
||||
@click="OpenBookSubtitlePositionScreenshot"
|
||||
style="margin-left: 5px"
|
||||
:color="softwareStore.SoftColor.BROWN_YELLOW"
|
||||
>查看截图</n-button
|
||||
>
|
||||
<n-button
|
||||
@click="GetCurrentFrameText"
|
||||
style="margin-left: 5px; width: 150px"
|
||||
:color="softwareStore.SoftColor.BROWN_YELLOW"
|
||||
:loading="GetCurrentFrameTextLodding"
|
||||
>
|
||||
{{ GetCurrentFrameTextLodding ? '提取文本中' : '提取保存帧' }}</n-button
|
||||
>
|
||||
<div>
|
||||
<div id="video-canvas">
|
||||
<video ref="videoRef" muted :src="videoSrc" id="video" autoplay></video>
|
||||
<canvas
|
||||
ref="canvasRef"
|
||||
@mousemove="handleMouseMove"
|
||||
@mousedown="handleMouseDown"
|
||||
@mouseup="handleMouseUp"
|
||||
style="position: absolute; top: 0; left: 0; pointer-events: auto"
|
||||
/>
|
||||
<n-divider />
|
||||
<div class="option-button">
|
||||
<n-button @click="SetVideoMuted" :color="buttonColor">{{
|
||||
isMuted ? '取消静音' : '开启静音'
|
||||
}}</n-button>
|
||||
<n-button
|
||||
@click="SaveSelectPosition"
|
||||
style="margin-left: 5px"
|
||||
:loading="SaveSelectPositionLodding"
|
||||
:color="softwareStore.SoftColor.BROWN_YELLOW"
|
||||
>保存位置</n-button
|
||||
>
|
||||
<n-button
|
||||
@click="OpenBookSubtitlePositionScreenshot"
|
||||
style="margin-left: 5px"
|
||||
:color="softwareStore.SoftColor.BROWN_YELLOW"
|
||||
>查看截图</n-button
|
||||
>
|
||||
<n-button
|
||||
@click="GetCurrentFrameText"
|
||||
style="margin-left: 5px; width: 150px"
|
||||
:color="softwareStore.SoftColor.BROWN_YELLOW"
|
||||
:loading="GetCurrentFrameTextLodding"
|
||||
>
|
||||
{{ GetCurrentFrameTextLodding ? '提取文本中' : '提取保存帧' }}</n-button
|
||||
>
|
||||
|
||||
<n-button
|
||||
@click="GetVideoFrameText"
|
||||
style="margin-left: 5px; width: 150px"
|
||||
:color="softwareStore.SoftColor.BROWN_YELLOW"
|
||||
:loading="GetVideoFrameTextLodding"
|
||||
>
|
||||
{{ GetVideoFrameTextLodding ? '视频文案提取中' : '提示视频文案' }}</n-button
|
||||
>
|
||||
<n-button
|
||||
v-if="type == 'storyboard_video'"
|
||||
@click="GetAllImageText"
|
||||
style="margin-left: 5px"
|
||||
:color="softwareStore.SoftColor.BROWN_YELLOW"
|
||||
>提取所有</n-button
|
||||
>
|
||||
</div>
|
||||
<div class="output-text" style="margin-top: 10px">
|
||||
<n-input
|
||||
type="textarea"
|
||||
placeholder="识别到的字幕文本(可能有错,需要手动看一下)"
|
||||
:autosize="{
|
||||
minRows: 5,
|
||||
maxRows: 7
|
||||
}"
|
||||
v-model:value="frameText"
|
||||
>
|
||||
</n-input>
|
||||
<n-button
|
||||
v-if="type != 'setting'"
|
||||
@click="GetVideoFrameText"
|
||||
style="margin-left: 5px; width: 150px"
|
||||
:color="softwareStore.SoftColor.BROWN_YELLOW"
|
||||
:loading="GetVideoFrameTextLodding"
|
||||
>
|
||||
{{ GetVideoFrameTextLodding ? '视频文案提取中' : '提取视频文案' }}</n-button
|
||||
>
|
||||
<n-button
|
||||
v-if="type == 'storyboard_video'"
|
||||
@click="GetAllImageText"
|
||||
style="margin-left: 5px"
|
||||
:color="softwareStore.SoftColor.BROWN_YELLOW"
|
||||
>提取所有</n-button
|
||||
>
|
||||
</div>
|
||||
<div class="output-text" style="margin-top: 10px">
|
||||
<n-input
|
||||
type="textarea"
|
||||
placeholder="识别到的字幕文本(可能有错,需要手动看一下)"
|
||||
:autosize="{
|
||||
minRows: 5,
|
||||
maxRows: 7
|
||||
}"
|
||||
v-model:value="frameText"
|
||||
>
|
||||
</n-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -70,8 +73,9 @@
|
||||
import { ref, onMounted, defineComponent, onUnmounted, computed, toRaw } from 'vue'
|
||||
import { NDivider, NButton, useMessage, NInput, useDialog } from 'naive-ui'
|
||||
import { useSoftwareStore } from '../../../../stores/software'
|
||||
import { useReverseManageStore } from '../../../../stores/reverseManage'
|
||||
import { useReverseManageStore } from '../../../../stores/reverseManage.ts'
|
||||
import { SubtitleSavePositionType } from '../../../../define/enum/waterMarkAndSubtitle'
|
||||
import { isEmpty } from 'lodash'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@@ -113,15 +117,19 @@ export default defineComponent({
|
||||
// resizeObserver.observe(videoRef.value)
|
||||
const video = videoRef.value
|
||||
video.onloadedmetadata = () => {
|
||||
let { width, height } = video.getBoundingClientRect()
|
||||
canvasRef.value.width = width
|
||||
canvasRef.value.height = height
|
||||
canvasRef.value.style.width = `${width}px`
|
||||
canvasRef.value.style.height = `${height}px`
|
||||
setTimeout(() => {
|
||||
video.play()
|
||||
isPlaying.value = true
|
||||
debugger
|
||||
let { width, height } = video.getBoundingClientRect()
|
||||
canvasRef.value.width = width
|
||||
canvasRef.value.height = height
|
||||
canvasRef.value.style.width = `${width}px`
|
||||
canvasRef.value.style.height = `${height}px`
|
||||
}, 1000) //
|
||||
}
|
||||
|
||||
let videoCanvas = document.getElementById('video-canvas')
|
||||
videoCanvas.style.width = `${videoWidth.value}px`
|
||||
videoCanvas.style.width = `${videoWidth.value + 2}px`
|
||||
videoCanvas.style.height = `${props.height}px`
|
||||
videoCanvas.style.overflow = 'scroll'
|
||||
buttonColor.value = videoRef.value.muted
|
||||
@@ -302,11 +310,16 @@ export default defineComponent({
|
||||
}
|
||||
SaveSelectPositionLodding.value = true
|
||||
message.success(JSON.stringify(rectPos.value))
|
||||
if (isEmpty(reverseManageStore.selectBook.id)) {
|
||||
window.api.showGlobalMessageDialog({
|
||||
code: 0,
|
||||
message: '当前没有选中的小说'
|
||||
})
|
||||
return
|
||||
}
|
||||
// 调用保存
|
||||
let saveRes = await window.book.SaveBookSubtitlePosition({
|
||||
id: reverseManageStore.selectBook.id
|
||||
? reverseManageStore.selectBook.id
|
||||
: '58053f68-da54-4a48-92fc-8a5c3cb75043',
|
||||
id: reverseManageStore.selectBook.id,
|
||||
bookSubtitlePosition: [toRaw(rectPos.value)],
|
||||
currentTime: videoRef.value.currentTime,
|
||||
type: type.value
|
||||
@@ -328,10 +341,15 @@ export default defineComponent({
|
||||
message.error('请先选择一个区域')
|
||||
return
|
||||
}
|
||||
if (isEmpty(reverseManageStore.selectBook.id)) {
|
||||
window.api.showGlobalMessageDialog({
|
||||
code: 0,
|
||||
message: '当前没有选中的小说'
|
||||
})
|
||||
return
|
||||
}
|
||||
let res = await window.book.OpenBookSubtitlePositionScreenshot({
|
||||
id: reverseManageStore.selectBook.id
|
||||
? reverseManageStore.selectBook.id
|
||||
: '58053f68-da54-4a48-92fc-8a5c3cb75043',
|
||||
id: reverseManageStore.selectBook.id,
|
||||
type: type.value
|
||||
})
|
||||
if (res.code == 0) {
|
||||
@@ -345,13 +363,21 @@ export default defineComponent({
|
||||
* 获取当前的字幕
|
||||
*/
|
||||
async function GetCurrentFrameText() {
|
||||
if (isEmpty(reverseManageStore.selectBook.id)) {
|
||||
window.api.showGlobalMessageDialog({
|
||||
code: 0,
|
||||
message: '当前没有选中的小说'
|
||||
})
|
||||
return
|
||||
}
|
||||
debugger
|
||||
GetCurrentFrameTextLodding.value = true
|
||||
if (type.value == SubtitleSavePositionType.MAIN_VIDEO) {
|
||||
if (
|
||||
type.value == SubtitleSavePositionType.MAIN_VIDEO ||
|
||||
type.value == SubtitleSavePositionType.SETTING
|
||||
) {
|
||||
let res = await window.book.GetCurrentFrameText({
|
||||
id: reverseManageStore.selectBook.id
|
||||
? reverseManageStore.selectBook.id
|
||||
: '58053f68-da54-4a48-92fc-8a5c3cb75043',
|
||||
currentTime: videoRef.value.currentTime,
|
||||
id: reverseManageStore.selectBook.id,
|
||||
type: type.value
|
||||
})
|
||||
if (res.code == 0) {
|
||||
@@ -369,12 +395,17 @@ export default defineComponent({
|
||||
* 获取整个视频的文案信息,保存到和视频的同级目录中
|
||||
*/
|
||||
async function GetVideoFrameText() {
|
||||
if (isEmpty(reverseManageStore.selectBook.id)) {
|
||||
window.api.showGlobalMessageDialog({
|
||||
code: 0,
|
||||
message: '当前没有选中的小说'
|
||||
})
|
||||
return
|
||||
}
|
||||
GetVideoFrameTextLodding.value = true
|
||||
if (type.value == SubtitleSavePositionType.MAIN_VIDEO) {
|
||||
let res = await window.book.GetVideoFrameText({
|
||||
id: reverseManageStore.selectBook.id
|
||||
? reverseManageStore.selectBook.id
|
||||
: '58053f68-da54-4a48-92fc-8a5c3cb75043',
|
||||
id: reverseManageStore.selectBook.id,
|
||||
type: type.value
|
||||
})
|
||||
if (res.code == 0) {
|
||||
@@ -421,3 +452,15 @@ export default defineComponent({
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="css">
|
||||
#video-canvas {
|
||||
position: relative;
|
||||
overflow: 'auto';
|
||||
}
|
||||
.option-button {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -406,7 +406,6 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
async function SaveMask() {
|
||||
|
||||
// 判断当前是不是又蒙板
|
||||
if (canvasHistory.length <= 1) {
|
||||
message.error('请先绘制蒙板')
|
||||
|
||||
@@ -87,14 +87,14 @@ const routes = [
|
||||
component: () => import('./components/Setting/MJSetting.vue')
|
||||
},
|
||||
{
|
||||
path: '/reverse_management',
|
||||
name: 'reverse_management',
|
||||
component: () => import('./components/ReverseManage/ReverseManage.vue')
|
||||
path: '/book_management',
|
||||
name: 'book_management',
|
||||
component: () => import('./components/Book/ReverseManage.vue')
|
||||
},
|
||||
{
|
||||
path: '/manage_book/:id',
|
||||
name: 'manage_book',
|
||||
component: () => import('./components/ReverseManage/ManageBookDetail.vue')
|
||||
component: () => import('./components/Book/ManageBookDetail.vue')
|
||||
},
|
||||
{
|
||||
path: '/test_options',
|
||||
@@ -102,9 +102,9 @@ const routes = [
|
||||
component: () => import('./components/VideoSubtitle/VideoCanvas.vue')
|
||||
},
|
||||
{
|
||||
path : "/TTS_Services",
|
||||
name : "TTS_Services",
|
||||
component : () => import('./components/TTS/TTSHome.vue')
|
||||
path: '/TTS_Services',
|
||||
name: 'TTS_Services',
|
||||
component: () => import('./components/TTS/TTSHome.vue')
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user