新增一键提交comfyUI任务
This commit is contained in:
lq1405 2025-11-06 20:13:39 +08:00
parent b5ed4e313d
commit b4ee555c03
10 changed files with 304 additions and 23 deletions

View File

@ -17,6 +17,8 @@ interface ISoftwareData {
authUrl: string,
/** ComfyUI 文档链接 */
comfyUIWorkflowDoc: string
/** 新工云链接 */
xiangongYunUrl: string
}
/** MJ相关文档链接 */
mjDoc: {
@ -41,7 +43,8 @@ export const SoftwareData: ISoftwareData = {
wikiUrl:
'https://rvgyir5wk1c.feishu.cn/wiki/space/7481893355360190492?ccm_open_type=lark_wiki_spaceLink&open_tab_from=wiki_home',
authUrl: "https://rvgyir5wk1c.feishu.cn/wiki/UUbrwAalJiq9BUkHymscD0E8nCc",
comfyUIWorkflowDoc: 'https://rvgyir5wk1c.feishu.cn/wiki/Je8Twp3d0i9TpekoWB9cLss4n17'
comfyUIWorkflowDoc: 'https://rvgyir5wk1c.feishu.cn/wiki/Je8Twp3d0i9TpekoWB9cLss4n17',
xiangongYunUrl : "https://www.xiangongyun.com/register/T2K6IG"
},
mjDoc: {
mjAPIDoc: 'https://rvgyir5wk1c.feishu.cn/wiki/OEj7wIdD6ivvCAkez4OcUPLcnIf',

View File

@ -1362,7 +1362,7 @@ export default {
'正在重置小说数据。。。': 'Resetting novel data...',
'是否重置小说数据,重置后数据将恢复至新建状态,所有的批次数据和文件数据都会被删除,请确认是否继续!': 'Do you want to reset novel data? After reset, data will return to newly created state, all batch data and file data will be deleted. Please confirm whether to continue!',
"查看小说,名称 '{name}'": "View novel, name '{name}'",
'永久删除项目数据,所有的批次数据和文件数据都会被删除': 'Permanently delete project data, all batch data and file data will be deleted',
'永久删除项目数据,所有的批次数据和文件数据都会被删除': 'Permanently delete project data, all batch data and file data will be deleted',
'将项目数据恢复至新建状态,所有的批次数据和文件数据都会被删除': 'Restore project data to newly created state, all batch data and file data will be deleted',
'修改小说名称、配音地址和SRT地址等基本信息': 'Modify basic information such as novel name, voiceover address, and SRT address',
' {count} 个子项目': ' {count} sub-projects',
@ -2056,6 +2056,26 @@ export default {
"同步生图提示词": "Sync Image Generation Prompts",
"选择一个文本文件,导入其中的提示词,按行分割,依次应用到所有的分镜中。": "Select a text file, import the prompts within, split by lines, and apply them sequentially to all storyboards.",
"同步当前分镜的生图提示词到图转视频的提示词中。": "Sync the current storyboard's image generation prompts to the image-to-video prompts.",
"【LaiTool】分镜大师-高图文/视频一致版SD/ComfyUI上下文-人物固定-消耗高)": "【LaiTool】Storyboard Master - High Image-Text/Video Consistency (SD/ComfyUI) (Context-Character Fixed-High Consumption)",
"【LaiTool】分镜大师-高图文/视频一致版MJ上下文-人物固定-消耗高)": "【LaiTool】Storyboard Master - High Image-Text/Video Consistency (MJ) (Context-Character Fixed-High Consumption)"
"【LaiTool】分镜大师-高图文/视频一致版SD/ComfyUI上下文-人物固定-消耗高)": "【LaiTool】Storyboard Master - High Image-Text/Video Consistency (SD/ComfyUI) (Context-Character Fixed-High Consumption)",
"【LaiTool】分镜大师-高图文/视频一致版MJ上下文-人物固定-消耗高)": "【LaiTool】Storyboard Master - High Image-Text/Video Consistency (MJ) (Context-Character Fixed-High Consumption)",
"停止转视频任务失败,参数错误": "Stop video conversion task failed, parameter error",
"停止转视频任务失败,没有需要停止的任务": "Stop video conversion task failed, no tasks to stop",
"停止所有批次的转视频任务成功": "Stop all batch video conversion tasks successful",
"停止当前批次的转视频任务成功": "Stop current batch video conversion tasks successful",
"该操作会将所有的转视频类型为 ComfyUI 的分镜,全部添加到转视频任务队列中,非 ComfyUI 的分镜不受影响,\n\n是否继续": "This operation will add all storyboards of type ComfyUI for video conversion to the video conversion task queue, non-ComfyUI storyboards will not be affected,\n\nContinue?",
"正在一键添加转视频任务...": "Adding video conversion tasks in one click...",
"一键添加失败,当前分镜没有 ComfyUI 转视频类型的任务": "One-click addition failed, current storyboard has no ComfyUI video conversion type tasks",
"已成功添加 {taskCount} 个转视频任务到队列中": "Successfully added {taskCount} video conversion tasks to the queue",
"一键添加转视频任务失败,{error}": "One-click addition of video conversion tasks failed, {error}",
"确定要停止当前批次的所有转视频任务吗?\n\n只能停止在等待中的任务。已开始生成的视频任务无法停止。\n\n是否继续": "Confirm to stop all video conversion tasks in the current batch?\n\nOnly tasks that are waiting can be stopped. Video tasks that have started generating cannot be stopped.\n\nContinue?",
"确定要停止所有的转视频任务吗?\n\n只能停止在等待中的任务。已开始生成的视频任务无法停止。\n\n是否继续": "Confirm to stop all video conversion tasks?\n\nOnly tasks that are waiting can be stopped. Video tasks that have started generating cannot be stopped.\n\nContinue?",
"一键提交转视频任务": "One-Click Submit Video Conversion Tasks",
"将所有转视频类型为 ComfyUI 的分镜,一键提交生成视频任务。": "Submit all storyboards of type ComfyUI for video conversion in one click.",
"停止当前批次转视频任务": "Stop Current Batch Video Conversion Tasks",
"停止当前批次中所有正在等待的转视频任务。": "Stop all waiting video conversion tasks in the current batch.",
"停止所有转视频任务": "Stop All Video Conversion Tasks",
"停止所有正在等待的转视频任务。": "Stop all waiting video conversion tasks.",
"云端使用推荐仙宫云": "Cloud usage recommends Xiangong Cloud",
"登录/注册": "Login/Register",
"开启图转视频": "Enable Image to Video",
}

View File

@ -1362,7 +1362,7 @@ export default {
'正在重置小说数据。。。': '正在重置小说数据。。。',
'是否重置小说数据,重置后数据将恢复至新建状态,所有的批次数据和文件数据都会被删除,请确认是否继续!': '是否重置小说数据,重置后数据将恢复至新建状态,所有的批次数据和文件数据都会被删除,请确认是否继续!',
"查看小说,名称 '{name}'": "查看小说,名称 '{name}'",
'永久删除项目数据,所有的批次数据和文件数据都会被删除': '永久删除项目数据,所有的批次数据和文件数据都会被删除',
'永久删除项目数据,所有的批次数据和文件数据都会被删除': '永久删除项目数据,所有的批次数据和文件数据都会被删除',
'将项目数据恢复至新建状态,所有的批次数据和文件数据都会被删除': '将项目数据恢复至新建状态,所有的批次数据和文件数据都会被删除',
'修改小说名称、配音地址和SRT地址等基本信息': '修改小说名称、配音地址和SRT地址等基本信息',
' {count} 个子项目': ' {count} 个子项目',
@ -2057,5 +2057,25 @@ export default {
"选择一个文本文件,导入其中的提示词,按行分割,依次应用到所有的分镜中。": "选择一个文本文件,导入其中的提示词,按行分割,依次应用到所有的分镜中。",
"同步当前分镜的生图提示词到图转视频的提示词中。": "同步当前分镜的生图提示词到图转视频的提示词中。",
"【LaiTool】分镜大师-高图文/视频一致版SD/ComfyUI上下文-人物固定-消耗高)": "【LaiTool】分镜大师-高图文/视频一致版SD/ComfyUI上下文-人物固定-消耗高)",
"【LaiTool】分镜大师-高图文/视频一致版MJ上下文-人物固定-消耗高)": "【LaiTool】分镜大师-高图文/视频一致版MJ上下文-人物固定-消耗高)"
"【LaiTool】分镜大师-高图文/视频一致版MJ上下文-人物固定-消耗高)": "【LaiTool】分镜大师-高图文/视频一致版MJ上下文-人物固定-消耗高)",
"停止转视频任务失败,参数错误": "停止转视频任务失败,参数错误",
"停止转视频任务失败,没有需要停止的任务": "停止转视频任务失败,没有需要停止的任务",
"停止所有批次的转视频任务成功": "停止所有批次的转视频任务成功",
"停止当前批次的转视频任务成功": "停止当前批次的转视频任务成功",
"该操作会将所有的转视频类型为 ComfyUI 的分镜,全部添加到转视频任务队列中,非 ComfyUI 的分镜不受影响,\n\n是否继续": "该操作会将所有的转视频类型为 ComfyUI 的分镜,全部添加到转视频任务队列中,非 ComfyUI 的分镜不受影响,\n\n是否继续",
"正在一键添加转视频任务...": "正在一键添加转视频任务...",
"一键添加失败,当前分镜没有 ComfyUI 转视频类型的任务": "一键添加失败,当前分镜没有 ComfyUI 转视频类型的任务",
"已成功添加 {taskCount} 个转视频任务到队列中": "已成功添加 {taskCount} 个转视频任务到队列中",
"一键添加转视频任务失败,{error}": "一键添加转视频任务失败,{error}",
"确定要停止当前批次的所有转视频任务吗?\n\n只能停止在等待中的任务。已开始生成的视频任务无法停止。\n\n是否继续": "确定要停止当前批次的所有转视频任务吗?\n\n只能停止在等待中的任务。已开始生成的视频任务无法停止。\n\n是否继续",
"确定要停止所有的转视频任务吗?\n\n只能停止在等待中的任务。已开始生成的视频任务无法停止。\n\n是否继续": "确定要停止所有的转视频任务吗?\n\n只能停止在等待中的任务。已开始生成的视频任务无法停止。\n\n是否继续",
"一键提交转视频任务": "一键提交转视频任务",
"将所有转视频类型为 ComfyUI 的分镜,一键提交生成视频任务。": "将所有转视频类型为 ComfyUI 的分镜,一键提交生成视频任务。",
"停止当前批次转视频任务": "停止当前批次转视频任务",
"停止当前批次中所有正在等待的转视频任务。": "停止当前批次中所有正在等待的转视频任务。",
"停止所有转视频任务": "停止所有转视频任务",
"停止所有正在等待的转视频任务。": "停止所有正在等待的转视频任务。",
"云端使用推荐仙宫云": "云端使用推荐仙宫云",
"登录/注册": "登录/注册",
"开启图转视频" : "开启图转视频",
}

View File

@ -207,7 +207,7 @@ export async function AddMultiImageTask(
//#endregion
//#region 停止指定类型的任务
//#region 停止图片生成任务
/**
*
*
@ -286,10 +286,82 @@ export async function StopImageTask(type: string): Promise<SuccessItem | ErrorIt
}
}
if (type == 'all') {
return successMessage(null, t('停止所有批次的出图任务成功'), 'StopImageTask')
return successMessage(null, t('停止所有批次的出图任务成功'))
} else {
return successMessage(null, t('停止当前批次的出图任务成功'), 'StopImageTask')
return successMessage(null, t('停止当前批次的出图任务成功'))
}
}
//#endregion
//#region 停止视频生成任务
export async function StopToVideoTask(type: "all" | "this"): Promise<SuccessItem | ErrorItem> {
if (type != 'all' && type != 'this') {
return errorMessage(t('停止转视频任务失败,参数错误'))
}
let taskTypes = [
BookBackTaskType.COMFYUI_VIDEO,
BookBackTaskType.RUNWAY_VIDEO,
BookBackTaskType.LUMA_VIDEO,
BookBackTaskType.KLING_VIDEO,
BookBackTaskType.KLING_VIDEO_EXTEND,
BookBackTaskType.MJ_VIDEO,
BookBackTaskType.MJ_VIDEO_EXTEND,
BookBackTaskType.HAILUO_TEXT_TO_VIDEO,
BookBackTaskType.HAILUO_IMAGE_TO_VIDEO,
BookBackTaskType.HAILUO_FIRST_LAST_FRAME
]
let queryCondition = {
bookTaskName: bookStore.selectBookTask.name,
taskStatus: BookBackTaskStatus.WAIT,
page: 1,
pageSize: 10000
}
if (type == 'all') {
delete queryCondition.bookTaskName
}
let stopTasks: any[] = []
for (let i = 0; i < taskTypes.length; i++) {
const element = taskTypes[i]
let taskRes = await window.task.GetTaskCollection({
...queryCondition,
taskType: element
})
if (taskRes.code != 1) {
return taskRes
}
if (taskRes.data?.data.length > 0) {
stopTasks.push(...taskRes.data?.data)
}
}
if (stopTasks.length <= 0) {
return errorMessage(t('停止转视频任务失败,没有需要停止的任务'))
}
// 开始执行停止的任务
for (let i = 0; i < stopTasks.length; i++) {
const element = stopTasks[i]
let res = await window.task.UpdateTaskStatus({
id: element.id,
status: BookBackTaskStatus.FAIL,
errorMessage: t('用户手动取消了任务')
})
if (res.code != 1) {
return res
}
}
if (type == 'all') {
return successMessage(null, t('停止所有批次的转视频任务成功'))
} else {
return successMessage(null, t('停止当前批次的转视频任务成功'))
}
}
//#endregion

View File

@ -70,10 +70,15 @@ import VideoDisplay from '@/renderer/src/components/common/VideoDisplay.vue'
import MediaToVideoVideoConfigHeader from './MediaToVideoVideoConfigHeader.vue'
import { OptionKeyName, OptionType } from '@/define/enum/option'
import { useBookStore, useSoftwareStore } from '@/renderer/src/stores'
import { GetImageToVideoModelsOptions } from '@/define/enum/video'
import { GetImageToVideoModelsOptions, ImageToVideoModels } from '@/define/enum/video'
import { t } from '@/i18n'
import { TimeDelay } from '@/define/Tools/time'
import { isEmpty } from 'lodash'
import DialogTextContent from '../../common/DialogTextContent.vue'
import { BookBackTaskType, TaskExecuteType } from '@/define/enum/bookEnum'
import { DEFINE_STRING } from '@/define/ipcDefineString'
import { AddOneTask, StopToVideoTask } from '@/renderer/src/common/task'
import { useMD } from '@/renderer/src/hooks/useMD'
const bookStore = useBookStore()
const softwareStore = useSoftwareStore()
@ -81,6 +86,7 @@ const softwareStore = useSoftwareStore()
const message = useMessage()
const dialog = useDialog()
const router = useRouter()
const { showErrorDialog, showSuccessDialog } = useMD()
// emits
const emit = defineEmits(['toggle-right-panel', 'view-detail'])
@ -535,6 +541,108 @@ async function handleSyncImagePrompts() {
})
}
//
async function handleOneClickToVideo() {
let da = dialog.warning({
title: t('操作确认'),
content: () =>
h(
DialogTextContent,
{
text: t(
`该操作会将所有的转视频类型为 ComfyUI 的分镜,全部添加到转视频任务队列中,非 ComfyUI 的分镜不受影响,\n\n是否继续`
)
},
{}
),
negativeText: t('取消'),
positiveText: t('继续'),
onPositiveClick: async () => {
da?.destroy()
await TimeDelay(200)
try {
softwareStore.spin.spinning = true
softwareStore.spin.tip = t('正在一键添加转视频任务...')
let taskCount = 0
//
for (let i = 0; i < bookStore.selectBookTaskDetail.length; i++) {
let element = bookStore.selectBookTaskDetail[i]
// ComfyUI
if (element.videoMessage?.videoType != ImageToVideoModels.COMFY_UI) {
continue
}
let res = await AddOneTask({
bookId: element.bookId,
type: BookBackTaskType.COMFYUI_VIDEO,
executeType: TaskExecuteType.AUTO,
bookTaskId: element.bookTaskId,
bookTaskDetailId: element.id,
messageName: DEFINE_STRING.BOOK.COMFYUI_TO_VIDEO_RETURN
})
if (res.code != 1) {
message.error(res.message)
return
}
taskCount++
}
if (taskCount === 0) {
showErrorDialog(t('失败'), t('一键添加失败,当前分镜没有 ComfyUI 转视频类型的任务'))
return
}
await TimeDelay(500)
showSuccessDialog(
t('成功'),
t('已成功添加 {taskCount} 个转视频任务到队列中', { taskCount })
)
} catch (error) {
showErrorDialog(t('失败'), t('一键添加转视频任务失败,{error}', { error: error.message }))
} finally {
da?.destroy()
softwareStore.spin.spinning = false
}
},
onNegativeClick: () => {
message.info(t('取消操作'))
},
closable: true,
maskClosable: false
})
}
//
async function handleStopToVideoTask(content, key) {
let da = dialog.warning({
title: t('操作提示'),
content: () =>
h(DialogTextContent, {
text: content
}),
closable: true,
maskClosable: false,
positiveText: t('确定'),
negativeText: t('取消'),
onPositiveClick: async () => {
da?.destroy()
let type = 'this'
if (key === 'stop-all-video-tasks') {
type = 'all'
}
let res = await StopToVideoTask(type)
//
await TimeDelay(500)
if (res.code != 1) {
showErrorDialog(t('失败'), res.message)
} else {
showSuccessDialog(t('成功'), res.message)
}
}
})
}
//
async function handleActionDropdownSelect(key) {
switch (key) {
@ -544,6 +652,26 @@ async function handleActionDropdownSelect(key) {
case 'sync-image-prompts':
await handleSyncImagePrompts()
break
case 'one-click-to-video':
await handleOneClickToVideo()
break
case 'stop-current-batch-tasks':
await handleStopToVideoTask(
t(
'确定要停止当前批次的所有转视频任务吗?\n\n只能停止在等待中的任务。已开始生成的视频任务无法停止。\n\n是否继续'
),
'stop-current-batch-tasks'
)
break
case 'stop-all-video-tasks':
await handleStopToVideoTask(
t(
'确定要停止所有的转视频任务吗?\n\n只能停止在等待中的任务。已开始生成的视频任务无法停止。\n\n是否继续'
),
'stop-all-video-tasks'
)
break
default:
message.error(t('未知操作'))
break

View File

@ -79,6 +79,21 @@ const blockOptions = computed(() => {
label: t('同步生图提示词'),
tooltip: t('同步当前分镜的生图提示词到图转视频的提示词中。'),
key: 'sync-image-prompts'
},
{
label: t('一键提交转视频任务'),
tooltip: t('将所有转视频类型为 ComfyUI 的分镜,一键提交生成视频任务。'),
key: 'one-click-to-video'
},
{
label: t('停止当前批次转视频任务'),
tooltip: t('停止当前批次中所有正在等待的转视频任务。'),
key: 'stop-current-batch-tasks'
},
{
label: t('停止所有转视频任务'),
tooltip: t('停止所有正在等待的转视频任务。'),
key: 'stop-all-video-tasks'
}
]

View File

@ -217,7 +217,7 @@ function getProjectMenuOptions() {
h('div', { style: 'color: #e74c3c; display: flex; align-items: center;' }, [
h(NIcon, null, () => h(TrashOutline))
]),
tooltip: '永久删除项目数据,所有的批次数据和文件数据都会被删除'
tooltip: t('永久删除项目数据,所有的批次数据和文件数据都会被删除')
}
]
}

View File

@ -82,14 +82,24 @@
embedded
style="margin: 16px 0; border: 2px solid #ff4d4f; background: #fff1f0"
>
<div style="display: flex; align-items: center; justify-content: space-between">
<div style="font-size: 18px; color: #d4380d; font-weight: bold">
{{ t('⚠️ ComfyUI 工作流配置请严格参考文档,否则无法正常生成!') }}
<n-space vertical :size="12">
<div style="display: flex; align-items: center">
<div style="font-size: 18px; color: #d4380d; font-weight: bold">
{{ t('云端使用推荐仙宫云') }}
</div>
<n-button type="error" size="large" @click="openXingongYun" style="margin-left: 24px">
{{ t('登录/注册') }}
</n-button>
</div>
<n-button type="error" size="large" @click="openComfyUIDoc" style="margin-left: 24px">
{{ t('查看文档') }}
</n-button>
</div>
<div style="display: flex; align-items: center; justify-content: space-between">
<div style="font-size: 18px; color: #d4380d; font-weight: bold">
{{ t('⚠️ ComfyUI 工作流配置请严格参考文档,否则无法正常生成!') }}
</div>
<n-button type="error" size="large" @click="openComfyUIDoc" style="margin-left: 24px">
{{ t('查看文档') }}
</n-button>
</div>
</n-space>
</n-card>
<n-divider title-placement="left"> {{ t('工作流设置') }} </n-divider>
@ -408,6 +418,11 @@ function openComfyUIDoc() {
window.system.OpenUrl(SoftwareData.systemInfo.comfyUIWorkflowDoc)
}
//
function openXingongYun() {
window.system.OpenUrl(SoftwareData.systemInfo.xiangongYunUrl)
}
//
const tableContainer = ref(null)
const tableHeight = ref(300) //

View File

@ -257,7 +257,7 @@ async function InitServerGptOptions() {
async function InitCopyWritingAISetting() {
try {
let dafaultData = {
gptUrl: 'https://api.laitool.cc',
gptUrl: 'https://zhiluoai.net',
apiKey: '',
model: ''
}

View File

@ -1,10 +1,10 @@
{
"latestVersion": "v4.0.4",
"updateDate": "2025-11-05",
"updateDate": "2025-11-06",
"updateInfo": [
{
"version": "v4.0.4",
"updateDate": "2025-11-05",
"updateDate": "2025-11-06",
"status": "unreleased",
"changes": [
{
@ -13,7 +13,15 @@
},
{
"type": "add",
"description": "添加两个高图文一致性推理预设"
"description": "添加两个高图文一致性推理出图提示词预设"
},
{
"type": "add",
"description": "新增两个通用的高图文一致性推理出图和图转视频提示词预设"
},
{
"type": "add",
"description": "文案处理新增两个分镜的推理提示词预设"
},
{
"type": "add",
@ -21,7 +29,7 @@
},
{
"type": "improvement",
"description": "优化 ComfyUI 设置"
"description": "优化 ComfyUI 设置(之前的工作流需要重新配置)"
},
{
"type": "add",