修复MJ设置 添加开启图转视频 删除ai推理参数 添加一键清空ai推理提示词

This commit is contained in:
lq1405 2025-09-14 23:21:26 +08:00
parent d94e21b3b2
commit 65e3ca3ce1
34 changed files with 304 additions and 64 deletions

1
123.txt Normal file
View File

@ -0,0 +1 @@
D:\LaiTool\LaiTool_Pro\Database\option.realm

View File

@ -1,7 +1,7 @@
{ {
"name": "laitool-pro", "name": "laitool-pro",
"productName": "来推 Pro", "productName": "LaiToolPro",
"version": "v3.4.6", "version": "v3.4.7",
"description": "来推 Pro - 一款集音频处理、文案生成、图片生成、视频生成等功能于一体的多合一AI工具软件。", "description": "来推 Pro - 一款集音频处理、文案生成、图片生成、视频生成等功能于一体的多合一AI工具软件。",
"main": "./out/main/index.js", "main": "./out/main/index.js",
"author": "xiangbei", "author": "xiangbei",
@ -69,6 +69,8 @@
"vue-tsc": "^2.2.2" "vue-tsc": "^2.2.2"
}, },
"build": { "build": {
"productName": "来推 Pro",
"appId": "com.laitool.pro",
"asar": true, "asar": true,
"files": [ "files": [
"out/**/*", "out/**/*",
@ -88,7 +90,8 @@
], ],
"nsis": { "nsis": {
"oneClick": false, "oneClick": false,
"allowToChangeInstallationDirectory": true "allowToChangeInstallationDirectory": true,
"shortcutName": "来推 Pro"
}, },
"win": { "win": {
"target": "nsis", "target": "nsis",

View File

@ -4,7 +4,6 @@
export const AICharacterAnalyseRequestData: OpenAIRequest.Request = { export const AICharacterAnalyseRequestData: OpenAIRequest.Request = {
model: 'deepseek-chat', model: 'deepseek-chat',
stream: false, stream: false,
temperature: 0.3,
messages: [ messages: [
{ {
role: 'system', role: 'system',

View File

@ -4,7 +4,6 @@
export const AISceneAnalyseRequestData: OpenAIRequest.Request = { export const AISceneAnalyseRequestData: OpenAIRequest.Request = {
model: 'deepseek-chat', model: 'deepseek-chat',
stream: false, stream: false,
temperature: 0.3,
messages: [ messages: [
{ {
role: 'system', role: 'system',

View File

@ -1,7 +1,6 @@
export const AIWordMergeLong: OpenAIRequest.Request = { export const AIWordMergeLong: OpenAIRequest.Request = {
model: 'deepseek-chat', model: 'deepseek-chat',
stream: false, stream: false,
temperature: 0.3,
messages: [ messages: [
{ {
role: 'system', role: 'system',

View File

@ -1,7 +1,6 @@
export const AIWordMergeShort = { export const AIWordMergeShort = {
model: 'deepseek-chat', model: 'deepseek-chat',
stream: false, stream: false,
temperature: 0.3,
messages: [ messages: [
{ {
role: 'system', role: 'system',

View File

@ -3,7 +3,6 @@
*/ */
export const AIStoryboardMasterAIEnhance: OpenAIRequest.Request = { export const AIStoryboardMasterAIEnhance: OpenAIRequest.Request = {
model: 'deepseek-chat', model: 'deepseek-chat',
temperature: 0.3,
stream: false, stream: false,
messages: [ messages: [

View File

@ -4,7 +4,6 @@
export const AIStoryboardMasterGeneral: OpenAIRequest.Request = { export const AIStoryboardMasterGeneral: OpenAIRequest.Request = {
model: 'deepseek-chat', model: 'deepseek-chat',
temperature: 0.3,
stream: false, stream: false,
messages: [ messages: [
{ {

View File

@ -3,7 +3,6 @@
*/ */
export const AIStoryboardMasterMJAncientStyle: OpenAIRequest.Request = { export const AIStoryboardMasterMJAncientStyle: OpenAIRequest.Request = {
model: 'deepseek-chat', model: 'deepseek-chat',
temperature: 1.3,
stream: false, stream: false,
messages: [ messages: [

View File

@ -4,7 +4,6 @@
export const AIStoryboardMasterOptimize: OpenAIRequest.Request = { export const AIStoryboardMasterOptimize: OpenAIRequest.Request = {
model: 'deepseek-chat', model: 'deepseek-chat',
temperature: 0.3,
stream: false, stream: false,
messages: [ messages: [

View File

@ -4,7 +4,6 @@
export const AIStoryboardMasterSDEnglish: OpenAIRequest.Request = { export const AIStoryboardMasterSDEnglish: OpenAIRequest.Request = {
model: 'deepseek-chat', model: 'deepseek-chat',
stream: false, stream: false,
temperature: 0.3,
messages: [ messages: [
{ {
role: 'system', role: 'system',

View File

@ -4,7 +4,6 @@
export const AIStoryboardMasterScenePrompt: OpenAIRequest.Request = { export const AIStoryboardMasterScenePrompt: OpenAIRequest.Request = {
model: 'deepseek-chat', model: 'deepseek-chat',
stream: false, stream: false,
temperature: 0.3,
messages: [ messages: [
{ {
role: 'system', role: 'system',

View File

@ -5,7 +5,6 @@
export const AIStoryboardMasterSingleFrame: OpenAIRequest.Request = { export const AIStoryboardMasterSingleFrame: OpenAIRequest.Request = {
model: 'deepseek-chat', model: 'deepseek-chat',
stream: false, stream: false,
temperature: 0.3,
messages: [ messages: [
{ {
role: 'system', role: 'system',

View File

@ -5,7 +5,6 @@
export const AIStoryboardMasterSingleFrameWithCharacter: OpenAIRequest.Request = { export const AIStoryboardMasterSingleFrameWithCharacter: OpenAIRequest.Request = {
model: 'deepseek-chat', model: 'deepseek-chat',
temperature: 0.3,
stream: false, stream: false,
messages: [ messages: [
{ {

View File

@ -4,7 +4,6 @@
export const AIStoryboardMasterSpecialEffects: OpenAIRequest.Request = { export const AIStoryboardMasterSpecialEffects: OpenAIRequest.Request = {
model: 'deepseek-chat', model: 'deepseek-chat',
stream: false, stream: false,
temperature: 0.3,
messages: [ messages: [
{ {
role: 'system', role: 'system',

View File

@ -1,6 +1,7 @@
import Realm from 'realm' import Realm from 'realm'
import { BaseService } from './baseService' import { BaseService } from './baseService'
import path from 'path' import path from 'path'
import fs from 'fs'
import { BookModel } from '../../model/book' import { BookModel } from '../../model/book'
import { import {
BookTaskDetailModel, BookTaskDetailModel,
@ -38,6 +39,8 @@ export class RealmBaseService extends BaseService {
public static async getInstance() { public static async getInstance() {
if (RealmBaseService.instance === null) { if (RealmBaseService.instance === null) {
// 将数写道本地文件
await fs.promises.writeFile(path.join(process.cwd(), '123.txt'), dbPath, 'utf-8')
RealmBaseService.instance = new RealmBaseService() RealmBaseService.instance = new RealmBaseService()
await RealmBaseService.instance.open() await RealmBaseService.instance.open()
} }

View File

@ -74,7 +74,8 @@ const define = (() => {
add_keyframe_tmp_path: path.join(base, 'tmp/Clip/keyframe_tmp.json'), add_keyframe_tmp_path: path.join(base, 'tmp/Clip/keyframe_tmp.json'),
lms_url: 'https://lms.laitool.cn', lms_url: 'https://lms.laitool.cn',
remotemj_api: 'https://api.laitool.net/', remotemj_api: 'https://api.laitool.net/',
remote_token: 'f85d39ed5a40fd09966f13f12b6cf0f0' remote_token: 'f85d39ed5a40fd09966f13f12b6cf0f0',
devPasswaord: 'woshinidaye'
}) })
return createPaths(basePath) return createPaths(basePath)
@ -109,7 +110,8 @@ const define = (() => {
add_keyframe_tmp_path: joinPath(base, 'tmp/Clip/keyframe_tmp.json'), add_keyframe_tmp_path: joinPath(base, 'tmp/Clip/keyframe_tmp.json'),
lms_url: 'https://lms.laitool.cn', lms_url: 'https://lms.laitool.cn',
remotemj_api: 'https://api.laitool.net/', remotemj_api: 'https://api.laitool.net/',
remote_token: 'f85d39ed5a40fd09966f13f12b6cf0f0' remote_token: 'f85d39ed5a40fd09966f13f12b6cf0f0',
devPasswaord: 'woshinidaye'
}) })
return createPaths(basePath) return createPaths(basePath)

View File

@ -23,7 +23,7 @@ declare namespace OpenAIRequest {
/** 是否启用流式输出 */ /** 是否启用流式输出 */
stream: boolean stream: boolean
/** 温度参数,控制生成内容的随机性 (0-1) */ /** 温度参数,控制生成内容的随机性 (0-1) */
temperature: number temperature?: number
/** 消息列表,包含系统提示和用户输入 */ /** 消息列表,包含系统提示和用户输入 */
messages: AIMessage[] messages: AIMessage[]
} }
@ -39,6 +39,6 @@ declare namespace OpenAIRequest {
/** 是否启用流式输出 */ /** 是否启用流式输出 */
stream: boolean stream: boolean
/** 温度参数 (0-1) */ /** 温度参数 (0-1) */
temperature: number temperature?: number
} }
} }

View File

@ -309,6 +309,10 @@ export default {
'检查所有的分镜信息,判断分镜的子图文件夹中的图片是否都在分镜的子图列表中,若没有,则添加进去!\n\n 注意:该操作不会删除分镜中已经有的子图信息!而是根据文件中的图片信息添加到分镜的子图数据中\n\n 该操作适用于手动将子图放入子图文件夹后,同步到分镜中!点击右侧"打开文件夹"打开当前批次的图片输出文件夹': 'Check all storyboard information, determine if the images in the storyboard\'s sub-image folder are all in the storyboard\'s sub-image list, if not, add them!\n\n Note: This operation will not delete existing sub-image information in the storyboard! Instead, it adds image information from the folder to the storyboard\'s sub-image data\n\n This operation is suitable for manually placing sub-images into the sub-image folder and then syncing to the storyboard! Click "Open Folder" on the right to open the current batch\'s image output folder', '检查所有的分镜信息,判断分镜的子图文件夹中的图片是否都在分镜的子图列表中,若没有,则添加进去!\n\n 注意:该操作不会删除分镜中已经有的子图信息!而是根据文件中的图片信息添加到分镜的子图数据中\n\n 该操作适用于手动将子图放入子图文件夹后,同步到分镜中!点击右侧"打开文件夹"打开当前批次的图片输出文件夹': 'Check all storyboard information, determine if the images in the storyboard\'s sub-image folder are all in the storyboard\'s sub-image list, if not, add them!\n\n Note: This operation will not delete existing sub-image information in the storyboard! Instead, it adds image information from the folder to the storyboard\'s sub-image data\n\n This operation is suitable for manually placing sub-images into the sub-image folder and then syncing to the storyboard! Click "Open Folder" on the right to open the current batch\'s image output folder',
'正在同步主图信息,请稍后...': 'Syncing main image information, please wait...', '正在同步主图信息,请稍后...': 'Syncing main image information, please wait...',
'同步主图信息失败,{error}': 'Failed to sync main image information, {error}', '同步主图信息失败,{error}': 'Failed to sync main image information, {error}',
'该操作会将当前批次的所有分镜的提示词全部重置为空,此操作不可撤销,重置的数据不可恢复,是否继续?': 'This operation will reset all storyboards\' prompts in the current batch to empty. This action is irreversible, and reset data cannot be recovered. Do you want to continue?',
'正在执行重置提示词任务,请稍等...': 'Resetting prompts, please wait...',
"重置提示词失败,{error}": "重置提示词失败,{error}",
"重置提示词成功": "Reset prompts successfully",
//#endregion //#endregion
//#region 出图 //#region 出图
@ -1319,6 +1323,7 @@ export default {
'将项目数据恢复至新建状态,所有的分镜数据都会被删除,包含提示词、图片等信息': 'Restore project data to newly created state, all storyboard data will be deleted, including prompts, images and other information', '将项目数据恢复至新建状态,所有的分镜数据都会被删除,包含提示词、图片等信息': 'Restore project data to newly created state, all storyboard data will be deleted, including prompts, images and other information',
"将当前批次任务导出到剪映草稿,包含背景音乐、字幕、图片、关键帧等信息": "Export current batch task to JianYing draft, including background music, subtitles, images, keyframes and other information", "将当前批次任务导出到剪映草稿,包含背景音乐、字幕、图片、关键帧等信息": "Export current batch task to JianYing draft, including background music, subtitles, images, keyframes and other information",
"编辑当前批次任务可以修改批次名称、SRT地址、配音地址等信息": "Edit current batch task, can modify batch name, SRT address, voice address and other information", "编辑当前批次任务可以修改批次名称、SRT地址、配音地址等信息": "Edit current batch task, can modify batch name, SRT address, voice address and other information",
"开启图文转视频功能,会将当前任务添加到图文转视频的任务列表中,并自动跳转到图文转视频界面": "Enable image-to-video function, will add current task to image-to-video task list and automatically jump to image-to-video interface",
"打开当前任务,进入分镜操作的详细界面": "Open current task and enter detailed storyboard operation interface", "打开当前任务,进入分镜操作的详细界面": "Open current task and enter detailed storyboard operation interface",
"删除服务器账号失败,{error}": "Failed to delete server account, {error}", "删除服务器账号失败,{error}": "Failed to delete server account, {error}",
"确定要删除服务器ID为 “{guildId}” 的服务器账号吗?此操作会从服务器删除账号,并同时删除本地记录,操作不可撤销!": 'Are you sure you want to delete the server account with server ID "{guildId}"? This operation will delete the account from the server and simultaneously delete local records, and cannot be undone!', "确定要删除服务器ID为 “{guildId}” 的服务器账号吗?此操作会从服务器删除账号,并同时删除本地记录,操作不可撤销!": 'Are you sure you want to delete the server account with server ID "{guildId}"? This operation will delete the account from the server and simultaneously delete local records, and cannot be undone!',
@ -1586,6 +1591,14 @@ export default {
"视频生成成功": "Video generation successful", "视频生成成功": "Video generation successful",
"图转视频失败,失败信息如下:{error}": "Image-to-video conversion failed, error details: {error}", "图转视频失败,失败信息如下:{error}": "Image-to-video conversion failed, error details: {error}",
'不支持的图片链接,仅支持网络图片链接!': 'Unsupported image link, only network image links are supported!', '不支持的图片链接,仅支持网络图片链接!': 'Unsupported image link, only network image links are supported!',
"是否上传图片文件到LaiTool云端\n\n上传后会返回一个全球可分享的网络链接地址但是每日限制五十次上传。上传后的图片可用于MJ垫图转视频等功能。\n\n注意上传后的图片会再Laitool服务器留存若介意请勿上传。": "Do you want to upload the image file to LaiTool cloud?\n\nAfter uploading, a globally shareable network link address will be returned, but there is a daily limit of fifty uploads. The uploaded images can be used for MJ background images, video conversion, and other functions.\n\nNote: Uploaded images will be retained on Laitool servers, please do not upload if you mind.",
"是否将任务 {bookTaskName} 添加到图文转视频的任务列表中?\n\n添加后会自动跳转到图文转视频界面若当前任务已经存在于图文转视频任务列表中则不会重复添加。": "Do you want to add task {bookTaskName} to the image-to-video task list?\n\nAfter adding, it will automatically jump to the image-to-video interface. If the current task already exists in the image-to-video task list, it will not be added again.",
"开启图文转视频失败,{error}": "Failed to enable image-to-video conversion, {error}",
"任务已添加到图文转视频模块": "Task has been added to the image-to-video module",
"是否现在就跳转到图文转视频界面?": "Do you want to jump to the image-to-video interface now?",
"当前批次任务已经开启图转视频,是否直接跳转到图文转视频界面?": "Current batch task has enabled image-to-video conversion, do you want to jump directly to the image-to-video interface?",
"正在跳转到图文转视频界面...": "Jumping to image-to-video interface...",
"已取消跳转,你可以在转视频模块中查看该任务": "Jump cancelled, you can view the task in the video conversion module",
//#region MJ //#region MJ
'基本信息': 'Basic Information', '基本信息': 'Basic Information',

View File

@ -309,6 +309,10 @@ export default {
'检查所有的分镜信息,判断分镜的子图文件夹中的图片是否都在分镜的子图列表中,若没有,则添加进去!\n\n 注意:该操作不会删除分镜中已经有的子图信息!而是根据文件中的图片信息添加到分镜的子图数据中\n\n 该操作适用于手动将子图放入子图文件夹后,同步到分镜中!点击右侧"打开文件夹"打开当前批次的图片输出文件夹': '检查所有的分镜信息,判断分镜的子图文件夹中的图片是否都在分镜的子图列表中,若没有,则添加进去!\n\n 注意:该操作不会删除分镜中已经有的子图信息!而是根据文件中的图片信息添加到分镜的子图数据中\n\n 该操作适用于手动将子图放入子图文件夹后,同步到分镜中!点击右侧"打开文件夹"打开当前批次的图片输出文件夹', '检查所有的分镜信息,判断分镜的子图文件夹中的图片是否都在分镜的子图列表中,若没有,则添加进去!\n\n 注意:该操作不会删除分镜中已经有的子图信息!而是根据文件中的图片信息添加到分镜的子图数据中\n\n 该操作适用于手动将子图放入子图文件夹后,同步到分镜中!点击右侧"打开文件夹"打开当前批次的图片输出文件夹': '检查所有的分镜信息,判断分镜的子图文件夹中的图片是否都在分镜的子图列表中,若没有,则添加进去!\n\n 注意:该操作不会删除分镜中已经有的子图信息!而是根据文件中的图片信息添加到分镜的子图数据中\n\n 该操作适用于手动将子图放入子图文件夹后,同步到分镜中!点击右侧"打开文件夹"打开当前批次的图片输出文件夹',
'正在同步主图信息,请稍后...': '正在同步主图信息,请稍后...', '正在同步主图信息,请稍后...': '正在同步主图信息,请稍后...',
'同步主图信息失败,{error}': '同步主图信息失败,{error}', '同步主图信息失败,{error}': '同步主图信息失败,{error}',
'该操作会将当前批次的所有分镜的提示词全部重置为空,此操作不可撤销,重置的数据不可恢复,是否继续?': '该操作会将当前批次的所有分镜的提示词全部重置为空,此操作不可撤销,重置的数据不可恢复,是否继续?',
'正在执行重置提示词任务,请稍等...': '正在执行重置提示词任务,请稍等...',
"重置提示词失败,{error}": "重置提示词失败,{error}",
"重置提示词成功": "重置提示词成功",
//#endregion //#endregion
//#region 出图 //#region 出图
@ -1319,6 +1323,7 @@ export default {
'将项目数据恢复至新建状态,所有的分镜数据都会被删除,包含提示词、图片等信息': '将项目数据恢复至新建状态,所有的分镜数据都会被删除,包含提示词、图片等信息', '将项目数据恢复至新建状态,所有的分镜数据都会被删除,包含提示词、图片等信息': '将项目数据恢复至新建状态,所有的分镜数据都会被删除,包含提示词、图片等信息',
"将当前批次任务导出到剪映草稿,包含背景音乐、字幕、图片、关键帧等信息": "将当前批次任务导出到剪映草稿,包含背景音乐、字幕、图片、关键帧等信息", "将当前批次任务导出到剪映草稿,包含背景音乐、字幕、图片、关键帧等信息": "将当前批次任务导出到剪映草稿,包含背景音乐、字幕、图片、关键帧等信息",
"编辑当前批次任务可以修改批次名称、SRT地址、配音地址等信息": "编辑当前批次任务可以修改批次名称、SRT地址、配音地址等信息", "编辑当前批次任务可以修改批次名称、SRT地址、配音地址等信息": "编辑当前批次任务可以修改批次名称、SRT地址、配音地址等信息",
"开启图文转视频功能,会将当前任务添加到图文转视频的任务列表中,并自动跳转到图文转视频界面": "开启图文转视频功能,会将当前任务添加到图文转视频的任务列表中,并自动跳转到图文转视频界面",
"打开当前任务,进入分镜操作的详细界面": "打开当前任务,进入分镜操作的详细界面", "打开当前任务,进入分镜操作的详细界面": "打开当前任务,进入分镜操作的详细界面",
"删除服务器账号失败,{error}": "删除服务器账号失败,{error}", "删除服务器账号失败,{error}": "删除服务器账号失败,{error}",
"确定要删除服务器ID为 “{guildId}” 的服务器账号吗?此操作会从服务器删除账号,并同时删除本地记录,操作不可撤销!": "确定要删除服务器ID为 “{guildId}” 的服务器账号吗?此操作会从服务器删除账号,并同时删除本地记录,操作不可撤销!", "确定要删除服务器ID为 “{guildId}” 的服务器账号吗?此操作会从服务器删除账号,并同时删除本地记录,操作不可撤销!": "确定要删除服务器ID为 “{guildId}” 的服务器账号吗?此操作会从服务器删除账号,并同时删除本地记录,操作不可撤销!",
@ -1586,6 +1591,14 @@ export default {
"视频生成成功": "视频生成成功", "视频生成成功": "视频生成成功",
"图转视频失败,失败信息如下:{error}": "图转视频失败,失败信息如下:{error}", "图转视频失败,失败信息如下:{error}": "图转视频失败,失败信息如下:{error}",
'不支持的图片链接,仅支持网络图片链接!': '不支持的图片链接,仅支持网络图片链接!', '不支持的图片链接,仅支持网络图片链接!': '不支持的图片链接,仅支持网络图片链接!',
"是否上传图片文件到LaiTool云端\n\n上传后会返回一个全球可分享的网络链接地址但是每日限制五十次上传。上传后的图片可用于MJ垫图转视频等功能。\n\n注意上传后的图片会再Laitool服务器留存若介意请勿上传。": "是否上传图片文件到LaiTool云端\n\n上传后会返回一个全球可分享的网络链接地址但是每日限制五十次上传。上传后的图片可用于MJ垫图转视频等功能。\n\n注意上传后的图片会再Laitool服务器留存若介意请勿上传。",
"是否将任务 {bookTaskName} 添加到图文转视频的任务列表中?\n\n添加后会自动跳转到图文转视频界面若当前任务已经存在于图文转视频任务列表中则不会重复添加。": "是否将任务 {bookTaskName} 添加到图文转视频的任务列表中?\n\n添加后会自动跳转到图文转视频界面若当前任务已经存在于图文转视频任务列表中则不会重复添加。",
"开启图文转视频失败,{error}": "开启图文转视频失败,{error}",
"任务已添加到图文转视频模块": "任务已添加到图文转视频模块",
"是否现在就跳转到图文转视频界面?": "是否现在就跳转到图文转视频界面?",
"当前批次任务已经开启图转视频,是否直接跳转到图文转视频界面?": "当前批次任务已经开启图转视频,是否直接跳转到图文转视频界面?",
"正在跳转到图文转视频界面...": "正在跳转到图文转视频界面...",
"已取消跳转,你可以在转视频模块中查看该任务": "已取消跳转,你可以在转视频模块中查看该任务",
//#region MJ //#region MJ
'基本信息': '基本信息', '基本信息': '基本信息',

View File

@ -149,8 +149,9 @@
class="image-input" class="image-input"
> >
<template #suffix> <template #suffix>
<n-button <TooltipButton
size="tiny" size="tiny"
:tooltip="t('上传图片到LaiTool图床获取图片链接')"
quaternary quaternary
@click=" @click="
handleUploadImage( handleUploadImage(
@ -182,7 +183,7 @@
</svg> </svg>
</n-icon> </n-icon>
</template> </template>
</n-button> </TooltipButton>
</template> </template>
</n-input> </n-input>
<n-image <n-image

View File

@ -12,8 +12,9 @@
class="image-input" class="image-input"
> >
<template #suffix> <template #suffix>
<n-button <TooltipButton
size="tiny" size="tiny"
:tooltip="t('上传图片到LaiTool图床获取图片链接')"
quaternary quaternary
@click="handleUploadImage(videoMessage.imageUrl, 'video', 'imageUrl')" @click="handleUploadImage(videoMessage.imageUrl, 'video', 'imageUrl')"
:disabled="loading" :disabled="loading"
@ -39,7 +40,7 @@
</svg> </svg>
</n-icon> </n-icon>
</template> </template>
</n-button> </TooltipButton>
</template> </template>
</n-input> </n-input>
<n-image <n-image
@ -71,8 +72,9 @@
class="image-input" class="image-input"
> >
<template #suffix> <template #suffix>
<n-button <TooltipButton
size="tiny" size="tiny"
:tooltip="t('上传图片到LaiTool图床获取图片链接')"
quaternary quaternary
@click=" @click="
handleUploadImage( handleUploadImage(
@ -104,7 +106,7 @@
</svg> </svg>
</n-icon> </n-icon>
</template> </template>
</n-button> </TooltipButton>
</template> </template>
</n-input> </n-input>
<n-image <n-image
@ -442,6 +444,7 @@ import {
} from '@/define/enum/video' } from '@/define/enum/video'
import { isEmpty } from 'lodash' import { isEmpty } from 'lodash'
import { t } from '@/i18n' import { t } from '@/i18n'
import TooltipButton from '../../../common/TooltipButton.vue'
const message = useMessage() const message = useMessage()

View File

@ -384,14 +384,16 @@ const tagHeight = computed(() => {
.tags-wrapper { .tags-wrapper {
padding-bottom: 4px; padding-bottom: 4px;
white-space: nowrap; white-space: normal;
overflow-x: auto; overflow-x: visible;
display: flex;
flex-wrap: wrap;
gap: 6px;
} }
.tag-item { .tag-item {
cursor: default; cursor: default;
margin-right: 6px; margin-bottom: 0;
margin-bottom: 4px;
} }
.tag-item-character { .tag-item-character {

View File

@ -95,9 +95,11 @@ import JianyingGenerateInformation from './JianyingGenerateInformation.vue'
import WordGroup from '../Copywriter/WordGroup.vue' import WordGroup from '../Copywriter/WordGroup.vue'
import AIGroup from '../Copywriter/AIGroup.vue' import AIGroup from '../Copywriter/AIGroup.vue'
import { t } from '@/i18n' import { t } from '@/i18n'
import { useMD } from '@/renderer/src/hooks/useMD'
const bookStore = useBookStore() const bookStore = useBookStore()
const softwareStore = useSoftwareStore() const softwareStore = useSoftwareStore()
const { showErrorDialog, showSuccessDialog } = useMD()
const dialog = useDialog() const dialog = useDialog()
const router = useRouter() const router = useRouter()
@ -174,6 +176,14 @@ const promptOptions = ref([
{ {
label: '2. ' + t('推理空白分镜提示词'), label: '2. ' + t('推理空白分镜提示词'),
key: 'original-get-all-empty-ai-prompt' key: 'original-get-all-empty-ai-prompt'
},
{
type: 'divider',
key: 'd5_1'
},
{
label: '3. ' + t('重置所有提示词'),
key: 'reset-all-prompt'
} }
]) ])
@ -530,6 +540,49 @@ async function handleOriginalGetAIPrompt(coverData, content) {
}) })
} }
//
async function handleResetAllPrompt() {
let da = dialog.warning({
title: t('操作确认'),
content: t(
'该操作会将当前批次的所有分镜的提示词全部重置为空,此操作不可撤销,重置的数据不可恢复,是否继续?'
),
closable: true,
maskClosable: false,
positiveText: t('确定'),
negativeText: t('取消'),
onPositiveClick: async () => {
da?.destroy()
try {
debugger
softwareStore.spin.spinning = true
softwareStore.spin.tip = t('正在执行重置提示词任务,请稍等...')
for (let i = 0; i < bookStore.selectBookTaskDetail.length; i++) {
const bookTaskDetail = bookStore.selectBookTaskDetail[i]
let res = await window.book.ModifyBookTaskDetailById(bookTaskDetail.id, {
gptPrompt: '',
prompt: ''
})
if (res.code != 1) {
showErrorDialog(t('失败'), t('重置提示词失败,{error}', { error: res.message }))
return
}
//
bookStore.selectBookTaskDetail[i].gptPrompt = ''
bookStore.selectBookTaskDetail[i].prompt = ''
}
showSuccessDialog(t('成功'), t('重置提示词成功'))
} catch (error) {
showErrorDialog(t('失败'), t('重置提示词失败,{error}', { error: error.message }))
} finally {
softwareStore.spin.spinning = false
}
}
})
}
// //
async function handlePromptSelect(key) { async function handlePromptSelect(key) {
if (key === 'original-get-all-ai-prompt') { if (key === 'original-get-all-ai-prompt') {
@ -542,6 +595,8 @@ async function handlePromptSelect(key) {
false, false,
t('会将当前批次的不存在提示词的分镜进行推理,不会影响已有提示词的分镜,是否继续?') t('会将当前批次的不存在提示词的分镜进行推理,不会影响已有提示词的分镜,是否继续?')
) )
} else if (key == 'reset-all-prompt') {
await handleResetAllPrompt()
} else { } else {
message.error(t('未知一键推理操作')) message.error(t('未知一键推理操作'))
} }

View File

@ -222,6 +222,7 @@ import { isEmpty } from 'lodash'
import { OptionKeyName } from '@/define/enum/option' import { OptionKeyName } from '@/define/enum/option'
import { optionSerialization } from '@/main/service/option/optionSerialization' import { optionSerialization } from '@/main/service/option/optionSerialization'
import { t } from '@/i18n' import { t } from '@/i18n'
import { TimeDelay } from '@/define/Tools/time'
const router = useRouter() const router = useRouter()
@ -300,6 +301,9 @@ async function handleTaskAction(key) {
case 'edit': case 'edit':
editBookTask(props.bookTask) editBookTask(props.bookTask)
break break
case 'open-media-to-video':
handleOpenMediaToVideo(props.bookTask)
break
case 'export-jianying': case 'export-jianying':
await ExportJianyingDraft() await ExportJianyingDraft()
break break
@ -541,6 +545,83 @@ async function editBookTask(bookTask) {
}) })
} }
async function handleOpenMediaToVideo(bookTask) {
let da = dialog.warning({
title: t('操作确认'),
content: () =>
h(
'div',
{ style: 'white-space: pre-wrap;' },
t(
'是否将任务 {bookTaskName} 添加到图文转视频的任务列表中?\n\n添加后会自动跳转到图文转视频界面若当前任务已经存在于图文转视频任务列表中则不会重复添加。',
{
bookTaskName: bookTask.name
}
)
),
positiveText: t('确定'),
negativeText: t('取消'),
onPositiveClick: async () => {
try {
da?.destroy()
debugger
softwareStore.spin.spinning = true
softwareStore.spin.tip = t('正在添加任务到图文转视频模块...')
//
if (!bookTask.openVideoGenerate) {
let res = await window.book.ModifyBookTaskDataById(bookTask.id, {
openVideoGenerate: true
})
if (res.code != 1) {
message.error(t('开启图文转视频失败,{error}', { error: res.message }))
return
}
message.success(t('任务已添加到图文转视频模块'))
}
//
let cm = dialog.warning({
title: t('操作确认'),
content: bookTask.openVideoGenerate
? t('当前批次任务已经开启图转视频,是否直接跳转到图文转视频界面?')
: t('是否现在就跳转到图文转视频界面?'),
positiveText: t('确定'),
negativeText: t('取消'),
closable: true,
maskClosable: true,
onPositiveClick: async () => {
try {
cm.destroy()
message.success(t('正在跳转到图文转视频界面...'))
await TimeDelay(1000)
bookStore.selectBookTask = bookTask
bookStore.selectBook = props.book
//
router.push({
name: 'mediaToVideo'
})
} catch (error) {
message.error(t('跳转失败,{error}', { error: error.message }))
} finally {
softwareStore.spin.spinning = false
}
},
onNegativeClick: () => {
message.info(t('已取消跳转,你可以在转视频模块中查看该任务'))
}
})
} catch (error) {
message.error(t('开启图文转视频失败,{error}', { error: error.message }))
} finally {
softwareStore.spin.spinning = false
}
//
}
})
}
// 稿 // 稿
// 稿 // 稿
async function ExportJianyingDraft() { async function ExportJianyingDraft() {

View File

@ -322,14 +322,12 @@ const handleSave = async () => {
display: flex; display: flex;
justify-content: center; justify-content: center;
padding: 8px; padding: 8px;
background-color: rgba(255, 255, 255, 0.9);
} }
/* 上传卡片样式 */ /* 上传卡片样式 */
.upload-card { .upload-card {
cursor: pointer; cursor: pointer;
border: 2px dashed #e0e0e0; border: 2px dashed #e0e0e0;
background-color: #f9f9f9;
height: 168px; /* 与图片项高度保持一致 */ height: 168px; /* 与图片项高度保持一致 */
display: flex; display: flex;
align-items: center; align-items: center;
@ -339,7 +337,6 @@ const handleSave = async () => {
.upload-card:hover { .upload-card:hover {
border-color: #2080f0; border-color: #2080f0;
background-color: #f0f7ff;
} }
.upload-placeholder { .upload-placeholder {
@ -389,7 +386,6 @@ const handleSave = async () => {
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
z-index: 1; z-index: 1;
background-color: rgba(255, 255, 255, 0.8);
border-radius: 50%; border-radius: 50%;
} }
</style> </style>

View File

@ -6,6 +6,16 @@
:class="{ 'preset-card-selected': preset.isShow }" :class="{ 'preset-card-selected': preset.isShow }"
@click="togglePresetSelection(preset)" @click="togglePresetSelection(preset)"
> >
<!-- 左上角的 checkbox -->
<n-checkbox
v-if="!isPresetShow"
:checked="preset.isShow"
@click.stop="togglePresetSelection(preset)"
size="small"
class="preset-checkbox"
>
</n-checkbox>
<template #cover> <template #cover>
<div <div
class="preset-cover-bg" class="preset-cover-bg"
@ -15,20 +25,19 @@
></div> ></div>
</template> </template>
<div class="preset-desc">{{ preset.label }}</div> <div class="preset-desc">{{ preset.label }}</div>
<div class="preset-meta"> <n-space class="preset-meta">
<n-tag :bordered="false" :type="getTagType(preset.type)" size="small">{{ <n-space justify="center">
getPresetCategoryLabel(preset.type) <n-tag :bordered="false" :type="getTagType(preset.type)" size="small"
}}</n-tag> >{{ getPresetCategoryLabel(preset.type) }}
</n-tag>
<n-tag :bordered="false" v-if="preset.isShow" type="primary" size="small"
>{{ t('显示') }}
</n-tag>
</n-space>
<span>{{ formattedDate(preset.createTime) }}</span> <span>{{ formattedDate(preset.createTime) }}</span>
</div> </n-space>
<template #footer> <template #footer>
<div class="preset-actions" v-if="!isPresetShow"> <div class="preset-actions" v-if="!isPresetShow">
<n-checkbox
:checked="preset.isShow"
@click.stop="togglePresetSelection(preset)"
size="small"
>{{ t('显示') }}</n-checkbox
>
<n-button size="small" @click.stop="handleEditPreset(preset)">{{ t('编辑') }}</n-button> <n-button size="small" @click.stop="handleEditPreset(preset)">{{ t('编辑') }}</n-button>
<n-button size="small" type="error" @click.stop="handleDeletePreset(preset.id)">{{ <n-button size="small" type="error" @click.stop="handleDeletePreset(preset.id)">{{
t('删除') t('删除')
@ -40,7 +49,7 @@
<script setup> <script setup>
import { getPresetCategoryLabel, PresetCategory } from '@/define/data/presetData' import { getPresetCategoryLabel, PresetCategory } from '@/define/data/presetData'
import { formattedDate, TimeDelay } from '@/define/Tools/time' import { formattedDate } from '@/define/Tools/time'
import { usePresetStore, useThemeStore } from '@/renderer/src/stores' import { usePresetStore, useThemeStore } from '@/renderer/src/stores'
import AddOrModifyPreset from './AddOrModifyPreset.vue' import AddOrModifyPreset from './AddOrModifyPreset.vue'
import { createLighterColor } from '@/renderer/src/common/color' import { createLighterColor } from '@/renderer/src/common/color'
@ -177,6 +186,18 @@ let contentBackgroundColor = computed(() => {
background-color: v-bind(backgroundColor); background-color: v-bind(backgroundColor);
} }
/* 左上角 checkbox 样式 */
.preset-checkbox {
position: absolute;
top: 8px;
left: 8px;
z-index: 10;
background-color: rgba(255, 255, 255, 0.9);
border-radius: 4px;
padding: 2px;
backdrop-filter: blur(4px);
}
/* 设置卡片内容区域的 padding */ /* 设置卡片内容区域的 padding */
.preset-card :deep(.n-card__content) { .preset-card :deep(.n-card__content) {
padding: 0 12px 0 16px; /* 自定义 padding 值 */ padding: 0 12px 0 16px; /* 自定义 padding 值 */
@ -211,22 +232,15 @@ let contentBackgroundColor = computed(() => {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
display: -webkit-box; display: -webkit-box;
-webkit-line-clamp: 1; /* Limit to 2 lines */ -webkit-line-clamp: 1; /* Limit to 1 line */
line-clamp: 1; /* Standard property for compatibility */
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
flex: 1; flex: 1;
} }
.preset-meta {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 12px;
padding: 0px;
}
.preset-actions { .preset-actions {
display: flex; display: flex;
justify-content: space-between; justify-content: center;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
} }

View File

@ -1,4 +1,4 @@
<template> r<template>
<n-card :title="t('通用设置')"> <n-card :title="t('通用设置')">
<n-form <n-form
v-if="!isLoading" v-if="!isLoading"

View File

@ -554,7 +554,6 @@ const handleSave = async () => {
let requestBody = { let requestBody = {
model: apiSetting.value.inferenceModel, model: apiSetting.value.inferenceModel,
temperature: 1.3,
stream: false, stream: false,
messages: [ messages: [
{ {

View File

@ -113,7 +113,6 @@ import { useSoftwareStore } from '@/renderer/src/stores'
import { nanoid } from 'nanoid' import { nanoid } from 'nanoid'
import { ValidateErrorString } from '@/define/Tools/validate' import { ValidateErrorString } from '@/define/Tools/validate'
import { t } from '@/i18n' import { t } from '@/i18n'
import { data } from '@volcengine/openapi/lib/services/vikingdb'
// message // message
const message = useMessage() const message = useMessage()

View File

@ -611,8 +611,6 @@ function getOutputFileName(originalName, format) {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: var(--n-card-color);
border: 1px solid var(--n-border-color);
border-radius: 6px; border-radius: 6px;
overflow: hidden; overflow: hidden;
} }
@ -646,7 +644,6 @@ function getOutputFileName(originalName, format) {
.size-reduction { .size-reduction {
text-align: center; text-align: center;
padding: 12px; padding: 12px;
background: var(--n-primary-color-suppl);
border-radius: 6px; border-radius: 6px;
margin-bottom: 16px; margin-bottom: 16px;
} }

View File

@ -30,6 +30,12 @@ const originOptions = [
icon: () => h(NIcon, null, () => h(CreateOutline)), icon: () => h(NIcon, null, () => h(CreateOutline)),
tooltip: t('编辑当前批次任务可以修改批次名称、SRT地址、配音地址等信息') tooltip: t('编辑当前批次任务可以修改批次名称、SRT地址、配音地址等信息')
}, },
{
label: t('开启图转视频'),
key: 'open-media-to-video',
icon: () => h(NIcon, null, () => h(CreateOutline)),
tooltip: t('开启图文转视频功能,会将当前任务添加到图文转视频的任务列表中,并自动跳转到图文转视频界面')
},
{ {
label: t('导出剪映草稿'), label: t('导出剪映草稿'),
key: 'export-jianying', key: 'export-jianying',

View File

@ -105,6 +105,8 @@ import CommonDialog from '../components/common/CommonDialog.vue'
import { useThemeStore, useMenuStore } from '../stores' import { useThemeStore, useMenuStore } from '../stores'
import { DEFINE_STRING } from '@/define/ipcDefineString' import { DEFINE_STRING } from '@/define/ipcDefineString'
import { t } from '@/i18n' import { t } from '@/i18n'
import InputDialogContent from '../components/common/InputDialogContent.vue'
import { define } from '@/define/define'
const router = useRouter() const router = useRouter()
const themeStore = useThemeStore() const themeStore = useThemeStore()
@ -114,6 +116,37 @@ const message = useMessage()
const dialog = useDialog() const dialog = useDialog()
const notification = useNotification() const notification = useNotification()
//
function syncMenuWithRoute() {
const currentRoute = router.currentRoute.value.path
//
const matchedMenuItem = menuStore.menuItems.find(item => {
if (!item.route) return false
//
if (item.route === currentRoute) return true
//
if (currentRoute.startsWith(item.route + '/')) return true
return false
})
if (matchedMenuItem) {
menuStore.setActiveMenu(matchedMenuItem.key)
}
}
//
watch(
() => router.currentRoute.value.path,
() => {
syncMenuWithRoute()
},
{ immediate: true }
)
// //
const mainMenuRef = ref(null) const mainMenuRef = ref(null)
const footerMenuRef = ref(null) const footerMenuRef = ref(null)
@ -310,6 +343,7 @@ watch(
onMounted(() => { onMounted(() => {
// //
window.addEventListener('resize', handleResize) window.addEventListener('resize', handleResize)
OpenDevTools()
// ResizeObserver // ResizeObserver
setTimeout(() => { setTimeout(() => {
@ -363,6 +397,37 @@ onMounted(() => {
}) })
}) })
async function OpenDevTools(params) {
window.addEventListener('keydown', (e) => {
if (e.ctrlKey && e.altKey && e.key === 'l') {
let dialogWidth = 400
let dialogHeight = 150
dialog.create({
title: '输入管理控制密码',
showIcon: false,
closeOnEsc: false,
content: () =>
h(InputDialogContent, {
initData: null,
type: 'password',
placeholder: '请输入管理控制密码',
onButtonClick: async (value) => {
let password = value
if (password == define.devPasswaord) {
window.system.OpenDEVTools()
} else {
message.error('密码错误,无法打开开发者工具')
return
}
}
}),
style: `width : ${dialogWidth}px; min-height : ${dialogHeight}px`,
maskClosable: false
})
}
})
}
onUnmounted(() => { onUnmounted(() => {
// //
window.removeEventListener('resize', handleResize) window.removeEventListener('resize', handleResize)

View File

@ -195,7 +195,7 @@ let selectBorderColor = computed(() => {
} }
.preset-flex-item { .preset-flex-item {
width: 240px; /* 固定卡片宽度 */ width: 200px; /* 固定卡片宽度 */
flex-grow: 0; flex-grow: 0;
flex-shrink: 0; flex-shrink: 0;
} }