V 3.2.2
1. 文案处理后端服务迁移(此版本之前的后端服务持续到12月1日) 2. 新增默认动图方式 3. (聚合推文)实现原创分类的图生视频(runway,luma,可灵) 4. 修复软件内配音 5. 删除旧的原创生图(原创,SD反推,MJ反推等操作在聚合推文中) 6. 导出剪映适配(视频) 7. 新增四个单句推理模式
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
<template>
|
||||
<div style="display: flex; align-items: center">
|
||||
<span>参数</span>
|
||||
<div>
|
||||
<span v-if="reverseManageStore.selectBook.type == 'original'">参数/菜单</span>
|
||||
<span v-else>参数</span>
|
||||
</div>
|
||||
<n-dropdown
|
||||
trigger="hover"
|
||||
:options="options"
|
||||
@@ -19,7 +22,7 @@ import { ref } from 'vue'
|
||||
import { NDropdown, NButton, NIcon, useMessage } from 'naive-ui'
|
||||
import MenuOpenRound from '@/renderer/src/components/Icon/MenuOpenRound.vue'
|
||||
import { useReverseManageStore } from '@/stores/reverseManage'
|
||||
import { BookImageCategory } from '@/define/enum/bookEnum'
|
||||
import { BookImageCategory, BookType } from '@/define/enum/bookEnum'
|
||||
import { useSoftwareStore } from '@/stores/software'
|
||||
import { TimeDelay } from '@/define/Tools/time'
|
||||
|
||||
@@ -33,7 +36,12 @@ let softwareStore = useSoftwareStore()
|
||||
|
||||
let options = [
|
||||
{ label: '启用修脸', key: 'openFaceRepair' },
|
||||
{ label: '关闭修脸', key: 'closeFaceRepair' }
|
||||
{ label: '关闭修脸', key: 'closeFaceRepair' },
|
||||
{
|
||||
label: () =>
|
||||
reverseManageStore.selectBookTask.openVideoGenerate ? '关闭合成视频' : '开启合成视频',
|
||||
key: 'openGenerateVideo'
|
||||
}
|
||||
]
|
||||
|
||||
async function ModifyFaceRepair(key) {
|
||||
@@ -75,6 +83,9 @@ async function handleSelect(key) {
|
||||
case 'closeFaceRepair':
|
||||
await ModifyFaceRepair(key)
|
||||
break
|
||||
case 'openGenerateVideo':
|
||||
await ModifyGenerateVideo()
|
||||
break
|
||||
default:
|
||||
message.error('未知操作')
|
||||
break
|
||||
@@ -86,6 +97,15 @@ async function handleSelect(key) {
|
||||
}
|
||||
}
|
||||
|
||||
async function ModifyGenerateVideo() {
|
||||
softwareStore.spin.tip = '正在修改表格数据'
|
||||
reverseManageStore.selectBookTask.openVideoGenerate =
|
||||
!reverseManageStore.selectBookTask.openVideoGenerate
|
||||
await window.db.UpdateBookTaskData(reverseManageStore.selectBookTask.id, {
|
||||
openVideoGenerate: reverseManageStore.selectBookTask.openVideoGenerate
|
||||
})
|
||||
}
|
||||
|
||||
function renderOption({ node, option }) {
|
||||
if (option.key === 'openFaceRepair' || option.key === 'closeFaceRepair') {
|
||||
if (
|
||||
@@ -94,6 +114,10 @@ function renderOption({ node, option }) {
|
||||
) {
|
||||
return node
|
||||
}
|
||||
} else if (option.key === 'openGenerateVideo') {
|
||||
if (reverseManageStore.selectBook.type == BookType.ORIGINAL) {
|
||||
return node
|
||||
}
|
||||
} else {
|
||||
return node
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<div class="data-table-generate">
|
||||
<div class="data-table-generate-progress">
|
||||
<n-button size="tiny" :color="softwareStore.SoftColor.BROWN_YELLOW" @click="OpenVideoOptions"
|
||||
>视频</n-button
|
||||
>
|
||||
<div>
|
||||
<n-tag
|
||||
v-if="bookTaskDetail.videoMessage?.status != 'fail'"
|
||||
style="margin-left: 5px"
|
||||
:bordered="false"
|
||||
type="success"
|
||||
size="small"
|
||||
>
|
||||
{{ GetVideoStatus(bookTaskDetail.videoMessage?.status ?? 'wait') }}
|
||||
</n-tag>
|
||||
<div v-else>
|
||||
<n-popover style="padding: 0; margin: 0" trigger="hover">
|
||||
<template #trigger>
|
||||
<n-tag style="margin-left: 5px" :bordered="false" type="error" size="small">
|
||||
{{ GetVideoStatus(bookTaskDetail.videoMessage?.status ?? 'fail') }}
|
||||
</n-tag>
|
||||
</template>
|
||||
<span>{{ bookTaskDetail.videoMessage?.msg }}</span>
|
||||
</n-popover>
|
||||
</div>
|
||||
</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;
|
||||
"
|
||||
>
|
||||
{{ bookTaskDetail.videoMessage?.taskId ?? '' }}
|
||||
</div>
|
||||
</template>
|
||||
<span>{{ bookTaskDetail.videoMessage?.taskId ?? '' }}</span>
|
||||
</n-popover>
|
||||
</div>
|
||||
<div>
|
||||
<div v-if="showVideo" class="data-table-generate-video"></div>
|
||||
<div v-else style="display: flex; justify-content: center; align-items: center;">
|
||||
<video style="max-width: 180px; max-height: 120px" controls>
|
||||
<source :src="bookTaskDetail.generateVideoPath" type="video/mp4" />
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { isEmpty } from 'lodash'
|
||||
import { computed, onMounted, ref, h } from 'vue'
|
||||
import { NButton, useDialog, NTag, NPopover } from 'naive-ui'
|
||||
import { useSoftwareStore } from '@/stores/software'
|
||||
import GenerateVideoDialog from './GenerateVideoDialog.vue'
|
||||
import { useReverseManageStore } from '@/stores/reverseManage'
|
||||
import { GetVideoStatus } from '@/define/enum/video'
|
||||
|
||||
let softwareStore = useSoftwareStore()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let dialog = useDialog()
|
||||
|
||||
let props = defineProps({
|
||||
bookTaskDetail: undefined,
|
||||
index: undefined
|
||||
})
|
||||
|
||||
let bookTaskDetail = ref(props.bookTaskDetail)
|
||||
|
||||
let showVideo = computed(() => {
|
||||
return isEmpty(bookTaskDetail?.value?.generateVideoPath)
|
||||
})
|
||||
|
||||
async function OpenVideoOptions() {
|
||||
dialog.create({
|
||||
showIcon: false,
|
||||
title: '图/文 生视频',
|
||||
content: () => h(GenerateVideoDialog, { bookTaskDetailId: bookTaskDetail.value.id }),
|
||||
style: 'width : 800px',
|
||||
maskClosable: false
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.data-table-generate {
|
||||
height: 145px;
|
||||
}
|
||||
|
||||
.data-table-generate-video {
|
||||
height: 120px;
|
||||
}
|
||||
.data-table-generate-progress {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,215 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-form inline :label-width="180">
|
||||
<n-form-item label="动图服务商" path="videoMessage.videoType" style="width: 200px">
|
||||
<n-select
|
||||
:options="videoOptions"
|
||||
v-model:value="videoMessage.videoType"
|
||||
placeholder="请选择动图服务商"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item label="生成方式" path="videoMessage.model" style="width: 200px">
|
||||
<n-select
|
||||
:options="videoModelOptions"
|
||||
v-model:value="videoMessage.model"
|
||||
placeholder="请选择动图生图方式"
|
||||
></n-select>
|
||||
</n-form-item>
|
||||
<n-form-item>
|
||||
<n-button type="primary" @click="SaveSimpleOptions">保存</n-button>
|
||||
</n-form-item>
|
||||
<n-form-item>
|
||||
<n-button type="primary" @click="AddImageToVideoTask">添加转视频任务</n-button>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
<n-divider />
|
||||
<div>
|
||||
<RunwayOption
|
||||
ref="runwayRef"
|
||||
:options="runwayOptions"
|
||||
:motionVector="runwayOptions.options?.motion_vector"
|
||||
v-if="videoMessage.videoType == videoType.RUNWAY"
|
||||
/>
|
||||
<LumaOption
|
||||
ref="lumaRef"
|
||||
:lumaOptions="lumaOptions"
|
||||
v-else-if="videoMessage.videoType == videoType.LUMA"
|
||||
/>
|
||||
<KlingOption
|
||||
:klingOptions="klingOptions"
|
||||
v-else-if="videoMessage.videoType == videoType.KLING"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useMessage, NForm, NFormItem, NDivider, NButton, NSelect } from 'naive-ui'
|
||||
import { ValidateJson } from '@/define/Tools/validate'
|
||||
import { ImageToVideoModels, VideoModel, VideoStatus } from '@/define/enum/video'
|
||||
import { useSoftwareStore } from '@/stores/software'
|
||||
import RunwayOption from './RunwayOption.vue'
|
||||
import LumaOption from './LumaOption.vue'
|
||||
import KlingOption from './KlingOption.vue'
|
||||
import { BookBackTaskType, TaskExecuteType } from '@/define/enum/bookEnum'
|
||||
import { useReverseManageStore } from '@/stores/reverseManage'
|
||||
import { DEFINE_STRING } from '@/define/define_string'
|
||||
import { option } from 'artplayer'
|
||||
|
||||
let props = defineProps({
|
||||
bookTaskDetailId: undefined
|
||||
})
|
||||
let videoType = ref(ImageToVideoModels)
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let message = useMessage()
|
||||
let softwareStore = useSoftwareStore()
|
||||
let runwayRef = ref(null)
|
||||
|
||||
let videoMessage = ref({})
|
||||
let runwayOptions = ref({})
|
||||
let lumaOptions = ref({})
|
||||
let klingOptions = ref({})
|
||||
|
||||
async function GetBookTaskDetailOption() {
|
||||
debugger
|
||||
let res = await window.db.GetBookTaskDetailProperty(props.bookTaskDetailId, 'videoMessage')
|
||||
if (res.code != 1) {
|
||||
message.error(res.message)
|
||||
}
|
||||
if (res.data != null) {
|
||||
videoMessage.value = res.data
|
||||
} else {
|
||||
// 这边初始化
|
||||
let initRes = await window.book.InitVideoMessage(props.bookTaskDetailId)
|
||||
console.log('InitVideoMessage', initRes)
|
||||
if (initRes.code != 1) {
|
||||
message.error(initRes.message)
|
||||
return
|
||||
}
|
||||
videoMessage.value = initRes.data
|
||||
}
|
||||
console.log(videoMessage.value)
|
||||
if (ValidateJson(videoMessage.value.runwayOptions)) {
|
||||
runwayOptions.value = JSON.parse(videoMessage.value.runwayOptions)
|
||||
runwayOptions.value.image = videoMessage.value.imageUrl
|
||||
}
|
||||
if (ValidateJson(videoMessage.value.lumaOptions)) {
|
||||
lumaOptions.value = JSON.parse(videoMessage.value.lumaOptions)
|
||||
lumaOptions.value.image_url = videoMessage.value.imageUrl
|
||||
}
|
||||
if (ValidateJson(videoMessage.value.klingOptions)) {
|
||||
klingOptions.value = JSON.parse(videoMessage.value.klingOptions)
|
||||
klingOptions.value.image = videoMessage.value.imageUrl
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await GetBookTaskDetailOption()
|
||||
})
|
||||
|
||||
async function SaveSimpleOptions() {
|
||||
try {
|
||||
// 保存数据
|
||||
// 这边修改数据然后直接保存
|
||||
let saveVideoMessageObject = {}
|
||||
debugger
|
||||
if (videoMessage.value.videoType == ImageToVideoModels.RUNWAY) {
|
||||
runwayOptions.value.options = runwayRef.value.options
|
||||
runwayOptions.value.options.motion_vector = runwayRef.value.motion_vector
|
||||
saveVideoMessageObject = {
|
||||
...videoMessage.value,
|
||||
prompt: runwayRef.value.prompt,
|
||||
style: runwayRef.value.style,
|
||||
model: videoMessage.value.model,
|
||||
bookTaskDetailId: props.bookTaskDetailId,
|
||||
status: VideoStatus.WAIT,
|
||||
runwayOptions: JSON.stringify(runwayOptions.value),
|
||||
lumaOptions: JSON.stringify(lumaOptions.value),
|
||||
klingOptions: JSON.stringify(klingOptions.value)
|
||||
}
|
||||
saveVideoMessageObject.imageUrl = runwayOptions.value.image
|
||||
} else if (videoMessage.value.videoType == ImageToVideoModels.LUMA) {
|
||||
saveVideoMessageObject = {
|
||||
...videoMessage.value,
|
||||
model: videoMessage.value.model,
|
||||
bookTaskDetailId: props.bookTaskDetailId,
|
||||
status: VideoStatus.WAIT,
|
||||
runwayOptions: JSON.stringify(runwayOptions.value),
|
||||
lumaOptions: JSON.stringify(lumaOptions.value),
|
||||
klingOptions: JSON.stringify(klingOptions.value)
|
||||
}
|
||||
saveVideoMessageObject.imageUrl = lumaOptions.value.image_url
|
||||
} else if (videoMessage.value.videoType == ImageToVideoModels.KLING) {
|
||||
saveVideoMessageObject = {
|
||||
...videoMessage.value,
|
||||
model: videoMessage.value.model,
|
||||
bookTaskDetailId: props.bookTaskDetailId,
|
||||
status: VideoStatus.WAIT,
|
||||
runwayOptions: JSON.stringify(runwayOptions.value),
|
||||
lumaOptions: JSON.stringify(lumaOptions.value),
|
||||
klingOptions: JSON.stringify(klingOptions.value)
|
||||
}
|
||||
saveVideoMessageObject.imageUrl = klingOptions.value.image
|
||||
} else {
|
||||
message.error('保存失败,未知的转视频类型')
|
||||
return
|
||||
}
|
||||
console.log('saveVideoMessageObject', saveVideoMessageObject)
|
||||
|
||||
let res = await window.book.UpdateBookTaskDetailVideoMessage(
|
||||
props.bookTaskDetailId,
|
||||
saveVideoMessageObject
|
||||
)
|
||||
if (res.code == 0) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
message.success('保存成功')
|
||||
} catch (error) {
|
||||
message.error('保存失败,' + error.message)
|
||||
throw new Error('保存失败,' + error.message)
|
||||
}
|
||||
}
|
||||
|
||||
async function AddImageToVideoTask() {
|
||||
try {
|
||||
// 先保存数据
|
||||
await SaveSimpleOptions()
|
||||
|
||||
let type = BookBackTaskType.RUNWAY_VIDEO
|
||||
if (videoMessage.value.videoType == ImageToVideoModels.LUMA) {
|
||||
type = BookBackTaskType.LUMA_VIDEO
|
||||
} else if (videoMessage.value.videoType == ImageToVideoModels.KLING) {
|
||||
type = BookBackTaskType.KLING_VIDEO
|
||||
}
|
||||
debugger
|
||||
// 添加任务
|
||||
let res = await window.task.AddBookBackTask(
|
||||
reverseManageStore.selectBook.id,
|
||||
type,
|
||||
TaskExecuteType.AUTO,
|
||||
reverseManageStore.selectBookTask.id,
|
||||
props.bookTaskDetailId,
|
||||
DEFINE_STRING.BOOK.RUNWAY_IMAGE_TO_VIDEO_RETURN
|
||||
)
|
||||
if (res.code != 1) {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
message.success('添加图转视频任务到队列成功')
|
||||
} catch (error) {
|
||||
message.error('添加任务到队列失败,错误消息如下:' + error.message)
|
||||
}
|
||||
}
|
||||
|
||||
let videoOptions = ref([
|
||||
{ label: 'Runway', value: ImageToVideoModels.RUNWAY },
|
||||
{ label: 'Luma', value: ImageToVideoModels.LUMA },
|
||||
{ label: '可灵', value: ImageToVideoModels.KLING }
|
||||
])
|
||||
|
||||
let videoModelOptions = ref([
|
||||
{ label: '文生视频', value: VideoModel.TEXT_TO_VIDEO },
|
||||
{ label: '图生视频', value: VideoModel.IMAGE_TO_VIDEO }
|
||||
])
|
||||
</script>
|
||||
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-form :model="klingOptions" label-placement="top">
|
||||
<n-grid :cols="24" :x-gap="24">
|
||||
<n-form-item-gi :span="12" label="提示词">
|
||||
<n-input v-model:value="klingOptions.prompt" placeholder="请输入提示词"></n-input>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="12" label="反向提示词">
|
||||
<n-input
|
||||
v-model:value="klingOptions.negative_prompt"
|
||||
placeholder="请输反向提示词"
|
||||
></n-input>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="6" label="生成视频的自由度">
|
||||
<n-input-number
|
||||
v-model:value="klingOptions.cfg_scale"
|
||||
placeholder="请输入生成视频的自由度"
|
||||
></n-input-number>
|
||||
</n-form-item-gi>
|
||||
|
||||
<n-form-item-gi :span="6" label="生成视频的模式">
|
||||
<n-select
|
||||
v-model:value="klingOptions.mode"
|
||||
:options="KlingModeOptions"
|
||||
placeholder="请选择生成视频的模式"
|
||||
>
|
||||
</n-select>
|
||||
</n-form-item-gi>
|
||||
|
||||
<n-form-item-gi :span="6" label="生成视频时长">
|
||||
<n-select
|
||||
v-model:value="klingOptions.seconds"
|
||||
:options="KlingSecondsOptions"
|
||||
placeholder="请选择生成视频时长"
|
||||
>
|
||||
</n-select>
|
||||
</n-form-item-gi>
|
||||
|
||||
<n-form-item-gi :span="12" label="参考图片链接">
|
||||
<n-input v-model:value="klingOptions.image" placeholder="请输入参考图片链接"></n-input>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="12">
|
||||
<n-image width="100" :src="klingOptions.image"></n-image>
|
||||
</n-form-item-gi>
|
||||
|
||||
<n-form-item-gi :span="12" label="参考图像 - 尾帧控制">
|
||||
<n-input
|
||||
v-model:value="klingOptions.image_tail"
|
||||
placeholder="请输入参考图像 - 尾帧控制"
|
||||
></n-input>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="12">
|
||||
<n-image width="100" :src="klingOptions.image_tail"></n-image>
|
||||
</n-form-item-gi>
|
||||
</n-grid>
|
||||
</n-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import {
|
||||
NForm,
|
||||
NImage,
|
||||
NGrid,
|
||||
NFormItemGi,
|
||||
NInput,
|
||||
NCheckbox,
|
||||
NInputNumber,
|
||||
NSelect
|
||||
} from 'naive-ui'
|
||||
import { KlingMode, RunwaySeconds } from '@/define/enum/video'
|
||||
|
||||
let props = defineProps({
|
||||
klingOptions: undefined
|
||||
})
|
||||
let klingOptions = ref({
|
||||
prompt: '',
|
||||
negative_prompt: '',
|
||||
mode: KlingMode.PRO,
|
||||
seconds: RunwaySeconds.FIVE
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (props.klingOptions) {
|
||||
klingOptions.value = props.klingOptions
|
||||
}
|
||||
})
|
||||
|
||||
let KlingModeOptions = ref([
|
||||
{ label: '高表现', value: KlingMode.PRO },
|
||||
{ label: '高性能', value: KlingMode.STD }
|
||||
])
|
||||
|
||||
let KlingSecondsOptions = ref([
|
||||
{ label: '5s', value: RunwaySeconds.FIVE },
|
||||
{ label: '10s', value: RunwaySeconds.TEN }
|
||||
])
|
||||
</script>
|
||||
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-form :model="lumaOptions" label-placement="top">
|
||||
<n-grid :cols="24" :x-gap="24">
|
||||
<n-form-item-gi :span="12" label="提示词">
|
||||
<n-input v-model:value="lumaOptions.user_prompt" placeholder="请输入提示词"></n-input>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="4" label="视频比例">
|
||||
<n-input v-model:value="lumaOptions.aspect_ratio" placeholder="请输视频比例"></n-input>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="4" label="提示词优化">
|
||||
<n-checkbox v-model:checked="lumaOptions.expand_prompt">提示词优化</n-checkbox>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="4" label="循环参考图">
|
||||
<n-checkbox v-model:checked="lumaOptions.loop">循环参考图</n-checkbox>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="12" label="参考图片链接">
|
||||
<n-input v-model:value="lumaOptions.image_url" placeholder="请输入参考图片链接"></n-input>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="12">
|
||||
<n-image width="100" :src="lumaOptions.image_url"></n-image>
|
||||
</n-form-item-gi>
|
||||
|
||||
<n-form-item-gi :span="12" label="关键帧图片链接">
|
||||
<n-input
|
||||
v-model:value="lumaOptions.image_end_url"
|
||||
placeholder="请输入关键帧图片链接"
|
||||
></n-input>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="12">
|
||||
<n-image width="100" :src="lumaOptions.image_end_url"></n-image>
|
||||
</n-form-item-gi>
|
||||
</n-grid>
|
||||
</n-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { NForm, NImage, NGrid, NFormItemGi, NInput, NCheckbox } from 'naive-ui'
|
||||
|
||||
let props = defineProps({
|
||||
lumaOptions: undefined
|
||||
})
|
||||
let lumaOptions = ref({
|
||||
user_prompt: '123',
|
||||
aspect_ratio: '4:3',
|
||||
loop: false
|
||||
})
|
||||
onMounted(() => {
|
||||
if (props.lumaOptions) {
|
||||
lumaOptions.value = props.lumaOptions
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,173 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-form ref="formRef" :model="runwayOptions" label-placement="top">
|
||||
<n-grid :cols="24" :x-gap="24">
|
||||
<n-form-item-gi :span="12" label="图片链接" path="image">
|
||||
<n-input v-model:value="runwayOptions.image" placeholder="请输入图片链接" />
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="12" path="textareaValue">
|
||||
<div style="display: flex">
|
||||
<n-image width="100" :src="runwayOptions.image" />
|
||||
<div style="margin-left: 5px">123</div>
|
||||
</div>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="12" label="提示词(支持中文)" path="prompt">
|
||||
<n-input v-model:value="runwayOptions.prompt" placeholder="请输入提示词(支持中文)" />
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="6" label="runway模型" path="model">
|
||||
<n-select v-model:value="runwayOptions.model" :options="runwwayModelOptions"></n-select>
|
||||
</n-form-item-gi>
|
||||
|
||||
<n-form-item-gi :span="6" label="风格" path="style">
|
||||
<n-input v-model:value="runwayOptions.style" placeholder="请输入风格" />
|
||||
</n-form-item-gi>
|
||||
|
||||
<n-form-item-gi :span="6" label="时长(秒)" path="options">
|
||||
<n-select v-model:value="options.seconds" :options="runwwaySecondOptions"></n-select>
|
||||
</n-form-item-gi>
|
||||
|
||||
<n-form-item-gi :span="6" path="last_image" label="尾帧">
|
||||
<n-input v-model:value="runwayOptions.last_image" placeholder="请输入尾帧图片链接" />
|
||||
</n-form-item-gi>
|
||||
|
||||
<n-form-item-gi :span="6" path="options.image_as_end_frame">
|
||||
<n-checkbox v-model:checked="options.image_as_end_frame"> 是否将图片作为尾帧 </n-checkbox>
|
||||
</n-form-item-gi>
|
||||
|
||||
<n-form-item-gi :span="6" path="options.flip">
|
||||
<n-checkbox v-model:checked="options.flip"> 是否宽屏(16:9) </n-checkbox>
|
||||
</n-form-item-gi>
|
||||
</n-grid>
|
||||
</n-form>
|
||||
|
||||
<n-collapse>
|
||||
<n-collapse-item title="镜头控制" name="1">
|
||||
<n-form :model="motion_vector" label-placement="top">
|
||||
<n-grid :cols="24" :x-gap="24">
|
||||
<n-gi :span="24" style="margin-bottom: 20px">
|
||||
<n-checkbox v-model:checked="motion_vector.isUse"> 是否启用镜头控制 </n-checkbox>
|
||||
</n-gi>
|
||||
<n-form-item-gi :span="8" label="镜头控制-水平" path="x">
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
v-model:value="motion_vector.x"
|
||||
placeholder="请输入水平值"
|
||||
/>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="8" label="镜头控制-垂直" path="y">
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
v-model:value="motion_vector.y"
|
||||
placeholder="请输入垂直值"
|
||||
/>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="8" label="镜头控制-缩放" path="z">
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
v-model:value="motion_vector.z"
|
||||
placeholder="请输入缩放值"
|
||||
/>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="8" label="镜头控制-旋转" path="r">
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
v-model:value="motion_vector.r"
|
||||
placeholder="请输入旋转值"
|
||||
/>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="8" label="镜头控制-左右方向倾斜" path="bg_x_pan">
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
v-model:value="motion_vector.bg_x_pan"
|
||||
placeholder="请输入左右方向倾斜值"
|
||||
/>
|
||||
</n-form-item-gi>
|
||||
<n-form-item-gi :span="8" label="镜头控制-上下方向倾斜" path="bg_y_pan">
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
v-model:value="motion_vector.bg_y_pan"
|
||||
placeholder="请输入上下方向倾斜值"
|
||||
/>
|
||||
</n-form-item-gi>
|
||||
</n-grid>
|
||||
</n-form>
|
||||
</n-collapse-item>
|
||||
</n-collapse>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import {
|
||||
NForm,
|
||||
NCheckbox,
|
||||
NInputNumber,
|
||||
NCollapse,
|
||||
NGi,
|
||||
NCollapseItem,
|
||||
NInput,
|
||||
NGrid,
|
||||
NButton,
|
||||
NSelect,
|
||||
NFormItemGi,
|
||||
NImage
|
||||
} from 'naive-ui'
|
||||
import { useSoftwareStore } from '@/stores/software'
|
||||
import { RunawayModel, RunwaySeconds } from '@/define/enum/video'
|
||||
|
||||
let softwareStore = useSoftwareStore()
|
||||
let props = defineProps({
|
||||
motionVector: undefined,
|
||||
options: undefined
|
||||
})
|
||||
let runwayOptions = ref(props.options)
|
||||
let motion_vector = ref({
|
||||
isUse: false,
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0,
|
||||
r: 0,
|
||||
bg_x_pan: 0,
|
||||
bg_y_pan: 0
|
||||
})
|
||||
let options = ref({
|
||||
seconds: RunwaySeconds.FIVE,
|
||||
image_as_end_frame: false,
|
||||
flip: false
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (props.motionVector) {
|
||||
motion_vector.value = props.motionVector
|
||||
}
|
||||
if (props.options && props.options.options) {
|
||||
options.value = props.options.options
|
||||
}
|
||||
})
|
||||
|
||||
let runwwayModelOptions = ref([
|
||||
{
|
||||
label: 'Gen 2',
|
||||
value: RunawayModel.GNE2
|
||||
},
|
||||
{
|
||||
label: 'Gen 3',
|
||||
value: RunawayModel.GNE3
|
||||
}
|
||||
])
|
||||
let runwwaySecondOptions = ref([
|
||||
{
|
||||
label: '5秒',
|
||||
value: RunwaySeconds.FIVE
|
||||
},
|
||||
{
|
||||
label: '10秒',
|
||||
value: RunwaySeconds.TEN
|
||||
}
|
||||
])
|
||||
|
||||
defineExpose({
|
||||
motion_vector,
|
||||
options
|
||||
})
|
||||
</script>
|
||||
@@ -83,9 +83,9 @@ const columns = [
|
||||
key: 'gptPrompt',
|
||||
className: 'empty-margin',
|
||||
resizable: true,
|
||||
width: 400,
|
||||
minWidth: 400,
|
||||
maxWidth: 600,
|
||||
width: 350,
|
||||
minWidth: 300,
|
||||
maxWidth: 500,
|
||||
render(row, index) {
|
||||
if (reverseManageStore.selectBook.type == BookType.MJ_REVERSE) {
|
||||
return h(MJReversePrompt, {
|
||||
@@ -152,7 +152,6 @@ onMounted(async () => {
|
||||
div[i].style.padding = '0px 5px'
|
||||
}
|
||||
calcHeight()
|
||||
// getMaxHeight()
|
||||
}, 100)
|
||||
|
||||
// 数据加载完毕
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
classMame="cd-22223"
|
||||
:max-height="maxHeight"
|
||||
:loading="softwareStore.loading.originDatatableDataLoading"
|
||||
:columns="createColumns({})"
|
||||
:columns="columns"
|
||||
:data="reverseManageStore.selectBookTaskDetail"
|
||||
:pagination="false"
|
||||
:bordered="false"
|
||||
@@ -16,7 +16,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, h, onMounted, watch } from 'vue'
|
||||
import { ref, h, onMounted, watch, computed } from 'vue'
|
||||
import { NDataTable, useMessage } from 'naive-ui'
|
||||
import DatatableHeaderAfterGpt from '../MJReverse/DatatableHeaderAfterGpt.vue'
|
||||
import DatatableAfterGpt from '../MJReverse/DatatableAfterGpt.vue'
|
||||
@@ -27,12 +27,12 @@ import ODataTableHeaderGptPrompt from './ODataTableHeaderGptPrompt.vue'
|
||||
import ODataTableHeaderPrompt from './ODatatableHeaderPrompt.vue'
|
||||
import ODatatablePrompt from './ODatatablePrompt.vue'
|
||||
import ODataTableAction from './ODataTableAction.vue'
|
||||
import DatatableHeaderGenerateImage from '../MJReverse/DatatableHeaderGenerateImage.vue'
|
||||
import DatatableHeaderImage from '../MJReverse/DatatableHeaderImage.vue'
|
||||
import DatatableGenerateImage from '../MJReverse/DatatableGenerateImage.vue'
|
||||
import BookTaskDetailOptions from '../Components/ManageBook/BookTaskDetailOptions.vue'
|
||||
import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import { useSoftwareStore } from '../../../../../stores/software'
|
||||
import DataTableGenerateVideo from '../Components/Video/DataTableGenerateVideo.vue'
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let softwareStore = useSoftwareStore()
|
||||
let maxHeight = ref(0)
|
||||
@@ -50,13 +50,8 @@ watch(
|
||||
)
|
||||
|
||||
onMounted(async () => {
|
||||
setTimeout(() => {
|
||||
let div = document.getElementsByClassName('empty-margin')
|
||||
for (let i = 0; i < div.length; i++) {
|
||||
div[i].style.padding = '0px 5px'
|
||||
}
|
||||
getMaxHeight()
|
||||
}, 100)
|
||||
getMaxHeight()
|
||||
|
||||
// 加载初始数据
|
||||
// 这边开始加载数据(就是小说分镜任务)
|
||||
softwareStore.spin.spinning = false
|
||||
@@ -77,10 +72,16 @@ onMounted(async () => {
|
||||
async function getMaxHeight() {
|
||||
let height = window.innerHeight
|
||||
maxHeight.value = height - 100
|
||||
setTimeout(() => {
|
||||
let div = document.getElementsByClassName('empty-margin')
|
||||
for (let i = 0; i < div.length; i++) {
|
||||
div[i].style.padding = '0px 5px'
|
||||
}
|
||||
}, 10)
|
||||
}
|
||||
|
||||
const createColumns = ({}) => {
|
||||
return [
|
||||
const columns = computed(() => {
|
||||
let cols = [
|
||||
{
|
||||
title: 'No.',
|
||||
key: 'no',
|
||||
@@ -120,8 +121,8 @@ const createColumns = ({}) => {
|
||||
key: 'gpt_prompt',
|
||||
className: 'empty-margin',
|
||||
resizable: true,
|
||||
minWidth: 330,
|
||||
maxWidth: 700,
|
||||
minWidth: 350,
|
||||
maxWidth: 500,
|
||||
width: '360',
|
||||
render(row, index) {
|
||||
return h(ODataTableGptPrompt, { initData: row, index: index })
|
||||
@@ -150,6 +151,17 @@ const createColumns = ({}) => {
|
||||
return h(ODataTableAction, { initData: row, index: index })
|
||||
}
|
||||
},
|
||||
{
|
||||
// 参数
|
||||
title: '合成视频',
|
||||
key: 'generateVideoPath',
|
||||
className: 'empty-margin',
|
||||
width: '200',
|
||||
minWidth: reverseManageStore.selectBookTask.openVideoGenerate ? 130 : 0,
|
||||
render(row, index) {
|
||||
return h(DataTableGenerateVideo, { bookTaskDetail: row, index: index })
|
||||
}
|
||||
},
|
||||
{
|
||||
// 出图
|
||||
title(row) {
|
||||
@@ -167,5 +179,7 @@ const createColumns = ({}) => {
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
getMaxHeight()
|
||||
return cols.filter((i) => i.minWidth != 0)
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -15,6 +15,8 @@ import { useReverseManageStore } from '../../../../../stores/reverseManage'
|
||||
import OriginalMainButton from './OriginalMainButton.vue'
|
||||
import OriginalMainDatatale from './OriginalMainDatatable.vue'
|
||||
import { DEFINE_STRING } from '../../../../../define/define_string'
|
||||
import { ResponseMessageType } from '@/define/enum/softwareEnum'
|
||||
import { GetVideoStatus, VideoStatus } from '@/define/enum/video'
|
||||
let softwareStore = useSoftwareStore()
|
||||
let reverseManageStore = useReverseManageStore()
|
||||
let message = useMessage()
|
||||
@@ -93,6 +95,74 @@ function OriginalSDImageResponseReturn(value) {
|
||||
}
|
||||
}
|
||||
|
||||
function VideoImageToVideoReturn(value) {
|
||||
debugger
|
||||
console.log('VideoImageToVideoReturn', value)
|
||||
if (value.code == 1) {
|
||||
// 成功
|
||||
let findIndex = reverseManageStore.selectBookTaskDetail.findIndex((item) => item.id == value.id)
|
||||
if (findIndex == -1) {
|
||||
return
|
||||
}
|
||||
if (value.type == ResponseMessageType.RUNWAY_VIDEO) {
|
||||
let resultData = JSON.parse(value.data)
|
||||
let status = 0
|
||||
if (resultData.status == '0' || resultData.status == '') {
|
||||
status = VideoStatus.WAIT
|
||||
} else if (resultData.status == '1') {
|
||||
status = VideoStatus.PROCESSING
|
||||
} else if (resultData.status == '2') {
|
||||
status = VideoStatus.FAIL
|
||||
} else if (resultData.status == '3') {
|
||||
status = VideoStatus.SUCCESS
|
||||
}
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].videoMessage.taskId = resultData.task_id
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].videoMessage.status = status
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].videoMessage.messageData = value.data
|
||||
} else if (value.type == ResponseMessageType.LUMA_VIDEO) {
|
||||
let resultData = JSON.parse(value.data)
|
||||
let status = VideoStatus.WAIT
|
||||
if (resultData.state == 'pending') {
|
||||
status = VideoStatus.WAIT
|
||||
} else if (resultData.state == 'processing') {
|
||||
status = VideoStatus.PROCESSING
|
||||
} else if (resultData.state == 'completed') {
|
||||
status = VideoStatus.SUCCESS
|
||||
} else {
|
||||
status = VideoStatus.FAIL
|
||||
}
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].videoMessage.taskId = resultData.id
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].videoMessage.status = status
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].videoMessage.messageData = value.data
|
||||
} else if (value.type == ResponseMessageType.KLING_VIDEO) {
|
||||
let resultData = JSON.parse(value.data)
|
||||
let status = VideoStatus.WAIT
|
||||
if (resultData.task_status == 'submitted') {
|
||||
status = VideoStatus.WAIT
|
||||
} else if (resultData.task_status == 'processing') {
|
||||
status = VideoStatus.PROCESSING
|
||||
} else if (resultData.task_status == 'succeed') {
|
||||
status = VideoStatus.SUCCESS
|
||||
} else {
|
||||
status = VideoStatus.FAIL
|
||||
}
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].videoMessage.taskId = resultData.task_id
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].videoMessage.status = status
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].videoMessage.messageData = value.data
|
||||
} else if (value.type == ResponseMessageType.VIDEO_SUCESS) {
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].videoMessage.status = VideoStatus.SUCCESS
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].generateVideoPath = value.data
|
||||
}
|
||||
} else {
|
||||
let findIndex = reverseManageStore.selectBookTaskDetail.findIndex((item) => item.id == value.id)
|
||||
if (findIndex == -1) {
|
||||
return
|
||||
}
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].videoMessage.status = VideoStatus.FAIL
|
||||
reverseManageStore.selectBookTaskDetail[findIndex].videoMessage.msg = value.message
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
// 监听推理提示词任务返回
|
||||
window.api.setEventListen([DEFINE_STRING.BOOK.ORIGINAL_GPT_PROMPT_RETURN], (value) =>
|
||||
@@ -122,6 +192,10 @@ onMounted(async () => {
|
||||
window.api.setEventListen([DEFINE_STRING.BOOK.D3_IMAGE_GENERATE_RETURN], (value) => {
|
||||
OriginalSDImageResponseReturn(value)
|
||||
})
|
||||
|
||||
window.api.setEventListen([DEFINE_STRING.BOOK.RUNWAY_IMAGE_TO_VIDEO_RETURN], (value) => {
|
||||
VideoImageToVideoReturn(value)
|
||||
})
|
||||
})
|
||||
onUnmounted(() => {
|
||||
window.api.removeEventListen(DEFINE_STRING.BOOK.ORIGINAL_GPT_PROMPT_RETURN)
|
||||
@@ -131,5 +205,6 @@ onUnmounted(() => {
|
||||
window.api.removeEventListen(DEFINE_STRING.BOOK.FLUX_FORGE_IMAGE_GENERATE_RETURN)
|
||||
window.api.removeEventListen(DEFINE_STRING.BOOK.FLUX_API_IMAGE_GENERATE_RETURN)
|
||||
window.api.removeEventListen(DEFINE_STRING.BOOK.D3_IMAGE_GENERATE_RETURN)
|
||||
window.api.removeEventListen(DEFINE_STRING.BOOK.RUNWAY_IMAGE_TO_VIDEO_RETURN)
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -27,16 +27,12 @@
|
||||
class="url_class"
|
||||
>软件激活教程 -->
|
||||
</strong>
|
||||
<strong
|
||||
style="margin-left: 10px; color: #ea5514"
|
||||
@click="OpenTeach('lms')"
|
||||
class="url_class"
|
||||
>
|
||||
<strong style="margin-left: 10px; color: #ea5514" @click="OpenTeach('lms')" class="url_class">
|
||||
后台入口
|
||||
</strong>
|
||||
</div>
|
||||
<!-- <div style="margin: 10px; color: red">
|
||||
如未激活,将上面的码给管理员激活
|
||||
<div style="margin: 10px; color: red">
|
||||
有使用问题或者购买问题请联系客服微信
|
||||
<n-popover trigger="hover" raw :show-arrow="false">
|
||||
<template #trigger>
|
||||
<n-tag type="info"> 客服微信 </n-tag>
|
||||
@@ -47,7 +43,7 @@
|
||||
preview-disabled
|
||||
/>
|
||||
</n-popover>
|
||||
</div> -->
|
||||
</div>
|
||||
<div style="margin: 10px; font-size: large; color: red">
|
||||
教程视频:<span class="url_class" @click="OpenTeach('video')">向北-LAITool</span>
|
||||
</div>
|
||||
@@ -87,7 +83,7 @@ function OpenTeach(type) {
|
||||
'https://rvgyir5wk1c.feishu.cn/docx/RNijdu3w4o4tRlxBhdccWhRpnfg?from=from_copylink'
|
||||
)
|
||||
break
|
||||
case "lms" :
|
||||
case 'lms':
|
||||
window.api.OpenUrl('https://lms.laitool.cn')
|
||||
break
|
||||
default:
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, h, onMounted, defineComponent, toRaw } from 'vue'
|
||||
import { ref, h, onMounted, defineComponent, toRaw, computed } from 'vue'
|
||||
import { RouterLink } from 'vue-router'
|
||||
import {
|
||||
useDialog,
|
||||
@@ -78,6 +78,7 @@ let show = ref(true)
|
||||
const systemStore = useSystemStore()
|
||||
|
||||
let key_down_ref = ref(null)
|
||||
let showMenu = ref(true)
|
||||
|
||||
// 菜单列表图标渲染
|
||||
function renderMenuIcon(option) {
|
||||
@@ -322,6 +323,9 @@ onMounted(async () => {
|
||||
|
||||
window.api.getSettingDafultData(async (value) => {
|
||||
window.config = value
|
||||
if (!(window.config && window.config.showOriginal)) {
|
||||
showMenu.value = false
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -329,274 +333,296 @@ function expandIcon(value) {
|
||||
return h(NIcon, null, { default: () => h(CaretDownOutline) })
|
||||
}
|
||||
|
||||
const menuOptions = [
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'gptCopywriting'
|
||||
const menuOptions = computed(() => {
|
||||
let me = [
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'gptCopywriting'
|
||||
},
|
||||
class: 'router-link-a'
|
||||
},
|
||||
class: 'router-link-a'
|
||||
},
|
||||
{
|
||||
default: () => '文案处理'
|
||||
}
|
||||
),
|
||||
key: 'gptCopywriting'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'sdoriginal'
|
||||
{
|
||||
default: () => '文案处理'
|
||||
}
|
||||
},
|
||||
{
|
||||
default: () => '原创生图'
|
||||
}
|
||||
),
|
||||
key: 'sdoriginal'
|
||||
},
|
||||
{
|
||||
label: '超级矩阵',
|
||||
key: 'backward_matrix',
|
||||
children: [
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'getframe'
|
||||
}
|
||||
},
|
||||
{ default: () => '抽帧' }
|
||||
),
|
||||
key: 'backward_frame'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'copywriting'
|
||||
}
|
||||
},
|
||||
{ default: () => '文案洗稿' }
|
||||
),
|
||||
key: 'copywriting'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'pushBackPrompt'
|
||||
}
|
||||
},
|
||||
{ default: () => '反推提示词' }
|
||||
),
|
||||
key: 'push_back'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'regenerate'
|
||||
}
|
||||
},
|
||||
{ default: () => '批次生成' }
|
||||
),
|
||||
key: 'regenerate'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'VideoGenerate'
|
||||
}
|
||||
},
|
||||
{ default: () => '重绘/视频合成' }
|
||||
),
|
||||
key: 'VideoGenerate'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'book_management'
|
||||
),
|
||||
key: 'gptCopywriting'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'sdoriginal'
|
||||
}
|
||||
},
|
||||
{
|
||||
default: () => '原创生图(弃用)'
|
||||
}
|
||||
},
|
||||
),
|
||||
key: 'sdoriginal',
|
||||
showMenu: showMenu.value
|
||||
},
|
||||
{
|
||||
label: '超级矩阵',
|
||||
key: 'backward_matrix',
|
||||
children: [
|
||||
{
|
||||
default: () => '聚合推文'
|
||||
}
|
||||
),
|
||||
key: 'book_management'
|
||||
},
|
||||
// {
|
||||
// label: "剪辑",
|
||||
// key: "clip_options",
|
||||
// children: [
|
||||
// {
|
||||
// label: () => h(
|
||||
// RouterLink,
|
||||
// {
|
||||
// to: {
|
||||
// name: "align_draft",
|
||||
// }
|
||||
// },
|
||||
// { default: () => "剪映草稿对齐" }
|
||||
// ),
|
||||
// key: "align_draft"
|
||||
// },
|
||||
// {
|
||||
// label: () => h(
|
||||
// RouterLink,
|
||||
// {
|
||||
// to: {
|
||||
// name: "add_draft",
|
||||
// }
|
||||
// },
|
||||
// { default: () => "添加剪映草稿" }
|
||||
// ),
|
||||
// key: "add_draft"
|
||||
// }
|
||||
// ]
|
||||
|
||||
// },
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'lai_api'
|
||||
}
|
||||
},
|
||||
{
|
||||
default: () => 'API服务'
|
||||
}
|
||||
),
|
||||
key: 'lai_api'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'TTS_Services'
|
||||
}
|
||||
},
|
||||
{
|
||||
default: () => '语音服务'
|
||||
}
|
||||
),
|
||||
key: 'TTS_Services'
|
||||
},
|
||||
{
|
||||
label: '设置',
|
||||
key: 'setting',
|
||||
children: [
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'global_setting'
|
||||
}
|
||||
},
|
||||
{ default: () => '通用设置' }
|
||||
),
|
||||
key: 'global_setting'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'clip_setting'
|
||||
}
|
||||
},
|
||||
{ default: () => '剪映设置' }
|
||||
),
|
||||
key: 'clip_setting'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'videogeneratesetting'
|
||||
}
|
||||
},
|
||||
{ default: () => '生成视频设置' }
|
||||
),
|
||||
key: 'videogeneratesetting'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'sd_setting'
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'getframe'
|
||||
}
|
||||
},
|
||||
class: 'sd_setting'
|
||||
},
|
||||
{ default: () => 'SD设置' }
|
||||
),
|
||||
key: 'sd_setting'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'mj_setting'
|
||||
}
|
||||
},
|
||||
{ default: () => 'MJ设置' }
|
||||
),
|
||||
key: 'mj_setting'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
'div',
|
||||
{
|
||||
onClick: () => {
|
||||
OpneBackTask()
|
||||
},
|
||||
style: 'font-weight: bold;'
|
||||
{ default: () => '抽帧' }
|
||||
),
|
||||
key: 'backward_frame'
|
||||
},
|
||||
{
|
||||
default: () => '后台任务'
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'copywriting'
|
||||
}
|
||||
},
|
||||
{ default: () => '文案洗稿' }
|
||||
),
|
||||
key: 'copywriting'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'pushBackPrompt'
|
||||
}
|
||||
},
|
||||
{ default: () => '反推提示词' }
|
||||
),
|
||||
key: 'push_back'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'regenerate'
|
||||
}
|
||||
},
|
||||
{ default: () => '批次生成' }
|
||||
),
|
||||
key: 'regenerate'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'VideoGenerate'
|
||||
}
|
||||
},
|
||||
{ default: () => '重绘/视频合成' }
|
||||
),
|
||||
key: 'VideoGenerate'
|
||||
}
|
||||
),
|
||||
key: 'back_task'
|
||||
]
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'book_management'
|
||||
}
|
||||
},
|
||||
{
|
||||
default: () => '聚合推文'
|
||||
}
|
||||
),
|
||||
key: 'book_management'
|
||||
},
|
||||
// {
|
||||
// label: "剪辑",
|
||||
// key: "clip_options",
|
||||
// children: [
|
||||
// {
|
||||
// label: () => h(
|
||||
// RouterLink,
|
||||
// {
|
||||
// to: {
|
||||
// name: "align_draft",
|
||||
// }
|
||||
// },
|
||||
// { default: () => "剪映草稿对齐" }
|
||||
// ),
|
||||
// key: "align_draft"
|
||||
// },
|
||||
// {
|
||||
// label: () => h(
|
||||
// RouterLink,
|
||||
// {
|
||||
// to: {
|
||||
// name: "add_draft",
|
||||
// }
|
||||
// },
|
||||
// { default: () => "添加剪映草稿" }
|
||||
// ),
|
||||
// key: "add_draft"
|
||||
// }
|
||||
// ]
|
||||
|
||||
// },
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'lai_api'
|
||||
}
|
||||
},
|
||||
{
|
||||
default: () => 'API服务'
|
||||
}
|
||||
),
|
||||
key: 'lai_api'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'TTS_Services'
|
||||
}
|
||||
},
|
||||
{
|
||||
default: () => '语音服务'
|
||||
}
|
||||
),
|
||||
key: 'TTS_Services'
|
||||
},
|
||||
{
|
||||
label: '设置',
|
||||
key: 'setting',
|
||||
children: [
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'global_setting'
|
||||
}
|
||||
},
|
||||
{ default: () => '通用设置' }
|
||||
),
|
||||
key: 'global_setting'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'clip_setting'
|
||||
}
|
||||
},
|
||||
{ default: () => '剪映设置' }
|
||||
),
|
||||
key: 'clip_setting'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'videogeneratesetting'
|
||||
}
|
||||
},
|
||||
{ default: () => '生成视频设置' }
|
||||
),
|
||||
key: 'videogeneratesetting'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'sd_setting'
|
||||
},
|
||||
class: 'sd_setting'
|
||||
},
|
||||
{ default: () => 'SD设置' }
|
||||
),
|
||||
key: 'sd_setting'
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: 'mj_setting'
|
||||
}
|
||||
},
|
||||
{ default: () => 'MJ设置' }
|
||||
),
|
||||
key: 'mj_setting'
|
||||
}
|
||||
// {
|
||||
// label: () =>
|
||||
// h(
|
||||
// RouterLink,
|
||||
// {
|
||||
// to: {
|
||||
// name: 'video_setting'
|
||||
// }
|
||||
// },
|
||||
// { default: () => '视频设置' }
|
||||
// ),
|
||||
// key: 'video_setting'
|
||||
// }
|
||||
]
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
'div',
|
||||
{
|
||||
onClick: () => {
|
||||
OpneBackTask()
|
||||
},
|
||||
style: 'font-weight: bold;'
|
||||
},
|
||||
{
|
||||
default: () => '后台任务'
|
||||
}
|
||||
),
|
||||
key: 'back_task',
|
||||
showMenu: true
|
||||
}
|
||||
]
|
||||
if (window.config && window.config.showOriginal) {
|
||||
return me
|
||||
} else {
|
||||
return me.filter((item) => item.showMenu || item.showMenu == undefined)
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
function renderIcon(icon) {
|
||||
return () => h(NIcon, null, { default: () => h(icon) })
|
||||
|
||||
@@ -80,6 +80,14 @@
|
||||
style="width: 200px"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item path="defaultImageMode" style="margin-left: 10px" label="默认图生视频模式">
|
||||
<n-select
|
||||
v-model:value="formValue.defaultVideoMode"
|
||||
:options="defaultVideoModeOptions"
|
||||
placeholder="选择默认图生视频模式"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-form-item>
|
||||
<n-form-item path="gpt_setting" label="GPT设置">
|
||||
<n-form-item path="gpt_business" label="GPT接口服务商">
|
||||
@@ -195,6 +203,7 @@ import { isEmpty } from 'lodash'
|
||||
import { useSoftwareStore } from '../../../../stores/software'
|
||||
import TranslateSetting from './TranslateSetting.vue'
|
||||
import { LaiAPIType } from '../../../../define/enum/softwareEnum'
|
||||
import { ImageToVideoModels } from '@/define/enum/video'
|
||||
|
||||
let formRef = ref(null)
|
||||
let softwareStore = useSoftwareStore()
|
||||
@@ -217,7 +226,8 @@ let formValue = ref({
|
||||
window_wh_bm_remember: window.config.window_wh_bm_remember,
|
||||
laiApiSelect: window.config.laiApiSelect ? window.config.laiApiSelect : LaiAPIType.MAIN,
|
||||
hdScale: window.config.hdScale ?? 2,
|
||||
defaultImageMode: window.config.defaultImageMode ?? 'mj'
|
||||
defaultImageMode: window.config.defaultImageMode ?? 'mj',
|
||||
defaultVideoMode: window.config.defaultVideoMode ?? ImageToVideoModels.RUNWAY
|
||||
})
|
||||
let show = ref(false)
|
||||
let gpt_options = ref([])
|
||||
@@ -240,6 +250,20 @@ let hdSelectOptions = ref([
|
||||
let dialog = useDialog()
|
||||
let loading = ref(false)
|
||||
let defaultImageModeOptions = ref([])
|
||||
let defaultVideoModeOptions = ref([
|
||||
{
|
||||
label: 'Runway',
|
||||
value: ImageToVideoModels.RUNWAY
|
||||
},
|
||||
{
|
||||
label: 'Luma',
|
||||
value: ImageToVideoModels.LUMA
|
||||
},
|
||||
{
|
||||
label: '可灵',
|
||||
value: ImageToVideoModels.KLING
|
||||
}
|
||||
])
|
||||
/**
|
||||
* 加载GPT的配置信息
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<n-card>
|
||||
<div style="color: red">生成视频接口共用通用设置LAI API设置(目前只支持LAI API)</div>
|
||||
<n-tabs type="line" animated>
|
||||
<n-tab-pane name="runway-option" tab="Runway参数设置"> RUNWAY </n-tab-pane>
|
||||
<n-tab-pane name="luma-option" tab="LUMA参数设置"> RUNWAY </n-tab-pane>
|
||||
</n-tabs>
|
||||
</n-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { NCard, NTabs, NTabPane } from 'naive-ui'
|
||||
</script>
|
||||
@@ -88,6 +88,11 @@ const routes = [
|
||||
name: 'mj_setting',
|
||||
component: () => import('./components/Setting/MJSetting.vue')
|
||||
},
|
||||
{
|
||||
path: '/video_setting',
|
||||
name: 'video_setting',
|
||||
component: () => import('./components/Setting/VideoSetting.vue')
|
||||
},
|
||||
{
|
||||
path: '/book_management',
|
||||
name: 'book_management',
|
||||
|
||||
Reference in New Issue
Block a user