V 4.0.1(2025.09.21)
1. 修改场景推理,导入到场景预设时原创界面的自动更新分组错误 2. 文案处理,可单独设置API、密钥、推理设置,没有设置就默认使用推理设置 3. 修改MJ出图的代理模式(添加账号,修改账号,出图) 4. 优化剪映关键帧设置UI界面 5. 修复文案处理的单个清空和批量清空 6. 删除 MJ Video Extend 的尾帧链接
This commit is contained in:
parent
aa16a494bd
commit
7a16f02673
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "laitool-pro",
|
||||
"productName": "LaiToolPro",
|
||||
"version": "v4.0.0",
|
||||
"version": "v4.0.1",
|
||||
"description": "来推 Pro - 一款集音频处理、文案生成、图片生成、视频生成等功能于一体的多合一AI工具软件。",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "xiangbei",
|
||||
|
||||
@ -352,10 +352,6 @@ export async function ImageSplit(
|
||||
const smallWidth = Math.floor(metadata.width / 2)
|
||||
const smallHeight = Math.floor(metadata.height / 2)
|
||||
|
||||
// 计算最后一列和最后一行可能的额外宽度/高度(处理奇数像素)
|
||||
const rightWidth = metadata.width - smallWidth
|
||||
const bottomHeight = metadata.height - smallHeight
|
||||
|
||||
const timestamp = new Date().getTime()
|
||||
const imgs: string[] = []
|
||||
|
||||
@ -367,21 +363,57 @@ export async function ImageSplit(
|
||||
const xOffset = isRightColumn ? smallWidth : 0
|
||||
const yOffset = isBottomRow ? smallHeight : 0
|
||||
|
||||
// 使用实际宽高,确保右边和底部区块使用正确尺寸
|
||||
const blockWidth = isRightColumn ? rightWidth : smallWidth
|
||||
const blockHeight = isBottomRow ? bottomHeight : smallHeight
|
||||
// 计算实际的分块尺寸,确保不超出图片边界
|
||||
const blockWidth = isRightColumn ? metadata.width - smallWidth : smallWidth
|
||||
const blockHeight = isBottomRow ? metadata.height - smallHeight : smallHeight
|
||||
|
||||
// 安全检查:确保分块尺寸为正数且不超出边界
|
||||
if (blockWidth <= 0 || blockHeight <= 0) {
|
||||
throw new Error(t('图片分块尺寸计算错误'))
|
||||
}
|
||||
|
||||
if (xOffset + blockWidth > metadata.width || yOffset + blockHeight > metadata.height) {
|
||||
throw new Error(t('图片分块超出边界'))
|
||||
}
|
||||
|
||||
const outFile = path.join(outputDir, `${reName}_${timestamp}_${i}.png`)
|
||||
|
||||
// 提取并保存分块
|
||||
await sharp(inputPath)
|
||||
.extract({
|
||||
left: xOffset,
|
||||
top: yOffset,
|
||||
width: blockWidth,
|
||||
height: blockHeight
|
||||
})
|
||||
.toFile(outFile)
|
||||
try {
|
||||
// 验证 extract 参数的有效性
|
||||
const extractOptions = {
|
||||
left: Math.max(0, Math.floor(xOffset)),
|
||||
top: Math.max(0, Math.floor(yOffset)),
|
||||
width: Math.max(1, Math.floor(blockWidth)),
|
||||
height: Math.max(1, Math.floor(blockHeight))
|
||||
}
|
||||
|
||||
// 再次验证边界
|
||||
if (extractOptions.left + extractOptions.width > metadata.width) {
|
||||
extractOptions.width = metadata.width - extractOptions.left
|
||||
}
|
||||
if (extractOptions.top + extractOptions.height > metadata.height) {
|
||||
extractOptions.height = metadata.height - extractOptions.top
|
||||
}
|
||||
|
||||
// 使用 buffer 方式更安全,避免 sharp 直接写文件时的崩溃
|
||||
const sharpInstance = sharp(inputPath)
|
||||
const extractedImage = sharpInstance.extract(extractOptions)
|
||||
|
||||
// 先转为 buffer,再写入文件
|
||||
const buffer = await extractedImage.png().toBuffer()
|
||||
|
||||
// 确保输出文件的目录存在
|
||||
await CheckFolderExistsOrCreate(path.dirname(outFile))
|
||||
|
||||
// 写入文件
|
||||
await fs.promises.writeFile(outFile, buffer)
|
||||
} catch (extractError) {
|
||||
throw new Error(t('图片分块 {index} 处理失败: {error}', {
|
||||
index: i,
|
||||
error: (extractError as Error).message
|
||||
}))
|
||||
}
|
||||
|
||||
imgs.push(outFile)
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ export const apiDefineData = [
|
||||
value: 'b44c6f24-59e4-4a71-b2c7-3df0c4e35e65',
|
||||
id: 'b44c6f24-59e4-4a71-b2c7-3df0c4e35e65',
|
||||
gpt_url: 'https://api.laitool.cc/v1/chat/completions',
|
||||
base_url: 'https://api.laitool.cc',
|
||||
mj_url: {
|
||||
imagine: 'https://api.laitool.cc/mj/submit/imagine',
|
||||
describe: 'https://api.laitool.cc/mj/submit/describe',
|
||||
@ -23,6 +24,7 @@ export const apiDefineData = [
|
||||
value: '2b443f53-ba12-42b3-a57c-e4df92685c73',
|
||||
id: '2b443f53-ba12-42b3-a57c-e4df92685c73',
|
||||
gpt_url: 'https://laitool.net/v1/chat/completions',
|
||||
base_url: 'https://laitool.net',
|
||||
mj_url: {
|
||||
imagine: 'https://laitool.net/mj/submit/imagine',
|
||||
describe: 'https://laitool.net/mj/submit/describe',
|
||||
@ -39,6 +41,7 @@ export const apiDefineData = [
|
||||
label: t('LaiTool生图包'),
|
||||
value: '9c9023bd-871d-4b63-8004-facb3b66c5b3',
|
||||
isPackage: true,
|
||||
base_url: 'https://lms.laitool.cn',
|
||||
mj_url: {
|
||||
imagine: 'https://lms.laitool.cn/api/mjPackage/mj/submit/imagine',
|
||||
describe: 'https://lms.laitool.cn/api/mjPackage/mj/submit/describe',
|
||||
|
||||
@ -30,8 +30,8 @@ interface ISoftwareData {
|
||||
}
|
||||
|
||||
export const SoftwareData: ISoftwareData = {
|
||||
version: 'V3.4.2',
|
||||
date: '2025-09.09',
|
||||
version: 'V4.0.1',
|
||||
date: '2025-09-21',
|
||||
systemInfo: {
|
||||
documentationUrl: 'https://rvgyir5wk1c.feishu.cn/wiki/WdaWwAfDdiLOnjkywIgcaQoKnog',
|
||||
updateUrl: 'https://pvwu1oahp5m.feishu.cn/docx/CAjGdTDlboJ3nVx0cQccOuNHnvd',
|
||||
|
||||
@ -1801,7 +1801,7 @@ export default {
|
||||
'AI生成文本': 'AI Generated Text',
|
||||
'确定要清空所有的AI生成文本吗?清空后不可恢复,是否继续?': 'Are you sure to clear all AI generated text? Cannot be recovered after clearing, continue?',
|
||||
'清空成功': 'Clear successful',
|
||||
'清空失败:': 'Clear failed: {error}',
|
||||
'清空失败:{error}': 'Clear failed: {error}',
|
||||
'取消清空': 'Cancel Clear',
|
||||
'直接复制会将所有的AI生成后的数据直接进行复制,不会进行格式之类的调整,若有需求可以再下面表格直接修改,或者是再左边的显示生成文本中修改,是否继续复制?': 'Direct copy will copy all AI generated data directly without format adjustments. If needed, you can modify directly in the table below or in the display generated text on the left. Continue copying?',
|
||||
'复制失败:存在未生成的文本,请先生成文本!': 'Copy failed: Ungenerated text exists, please generate text first!',
|
||||
|
||||
@ -1801,7 +1801,7 @@ export default {
|
||||
'AI生成文本': 'AI生成文本',
|
||||
'确定要清空所有的AI生成文本吗?清空后不可恢复,是否继续?': '确定要清空所有的AI生成文本吗?清空后不可恢复,是否继续?',
|
||||
'清空成功': '清空成功',
|
||||
'清空失败:': '清空失败:{error}',
|
||||
'清空失败:{error}': '清空失败:{error}',
|
||||
'取消清空': '取消清空',
|
||||
'直接复制会将所有的AI生成后的数据直接进行复制,不会进行格式之类的调整,若有需求可以再下面表格直接修改,或者是再左边的显示生成文本中修改,是否继续复制?': '直接复制会将所有的AI生成后的数据直接进行复制,不会进行格式之类的调整,若有需求可以再下面表格直接修改,或者是再左边的显示生成文本中修改,是否继续复制?',
|
||||
'复制失败:存在未生成的文本,请先生成文本!': '复制失败:存在未生成的文本,请先生成文本!',
|
||||
|
||||
@ -527,7 +527,10 @@ export class BookImageHandle extends BookBasicHandle {
|
||||
imageRes = await ImageSplit(
|
||||
imagePath,
|
||||
bookTaskDetail.name as string,
|
||||
path.join(book.bookFolderPath as string, 'data\\MJOriginalImage')
|
||||
path.join(
|
||||
bookTask.imageFolder as string,
|
||||
`subImage\\${bookTaskDetail.name}`
|
||||
)
|
||||
)
|
||||
if (imageRes && imageRes.length < 4) {
|
||||
throw new Error(t('图片裁剪失败'))
|
||||
@ -684,7 +687,7 @@ export class BookImageHandle extends BookBasicHandle {
|
||||
bookTaskDetail.name as string,
|
||||
path.join(
|
||||
bookTask.imageFolder as string,
|
||||
`subImage\\${bookTaskDetail.name}\\${new Date().getTime()}.png`
|
||||
`subImage\\${bookTaskDetail.name}`
|
||||
)
|
||||
)
|
||||
if (imageArray && imageArray.length < 4) {
|
||||
|
||||
@ -279,6 +279,13 @@ export class MJApiService extends MJBasic {
|
||||
let headers = {
|
||||
Authorization: this.token
|
||||
}
|
||||
|
||||
if (this.mjGeneralSetting?.outputMode == ImageGenerateMode.LOCAL_MJ) {
|
||||
headers['mj-api-secret'] = this.token
|
||||
} else if (this.mjGeneralSetting?.outputMode == ImageGenerateMode.REMOTE_MJ) {
|
||||
headers['mj-api-secret'] = this.token
|
||||
}
|
||||
|
||||
// 开始请求
|
||||
let res = await axios.get(APIDescribeUrl, {
|
||||
headers: headers
|
||||
|
||||
@ -45,7 +45,7 @@ export class TranslateCommon {
|
||||
|
||||
let aiSetting = optionSerialization<SettingModal.InferenceAISettings>(
|
||||
aiSettingOptionString,
|
||||
'‘设置-> 推理设置’'
|
||||
t('设置-> 推理设置')
|
||||
)
|
||||
|
||||
let apiProvider = GetApiDefineDataById(aiSetting.apiProvider)
|
||||
|
||||
@ -10,6 +10,7 @@ import { DEFINE_STRING } from '@/define/ipcDefineString'
|
||||
import axios from 'axios'
|
||||
import { GetOpenAISuccessResponse, GetRixApiErrorResponse } from '@/define/response/openAIResponse'
|
||||
import { t } from '@/i18n'
|
||||
import { GetApiDefineDataById } from '@/define/data/apiData'
|
||||
|
||||
export class CopyWritingServiceHandle extends BookBasicHandle {
|
||||
constructor() {
|
||||
@ -56,6 +57,32 @@ export class CopyWritingServiceHandle extends BookBasicHandle {
|
||||
apiSettingOption,
|
||||
t('文案处理->设置')
|
||||
)
|
||||
if (isEmpty(apiSetting.apiKey) || isEmpty(apiSetting.gptUrl) || isEmpty(apiSetting.model)) {
|
||||
// 这边没有设置数据的话,去文案处理那边获取设置
|
||||
let cwApiSetting = this.optionRealmService.GetOptionDataByKey<SettingModal.InferenceAISettings>(OptionKeyName.InferenceAI.InferenceSetting, t('设置 -> 推理设置'));
|
||||
|
||||
// 判断是不是有API令牌,没有的话获取推理设置那边的
|
||||
if (apiSetting.apiKey == null || isEmpty(apiSetting.apiKey)) {
|
||||
apiSetting.apiKey = cwApiSetting?.apiToken || ''
|
||||
}
|
||||
|
||||
// 判断是不是有API地址,没有的话获取推理设置那边的
|
||||
if (apiSetting.gptUrl == null || isEmpty(apiSetting.gptUrl)) {
|
||||
let ApiData = GetApiDefineDataById(cwApiSetting.apiProvider);
|
||||
if (ApiData.gpt_url == null || isEmpty(ApiData.gpt_url)) {
|
||||
throw new Error(t('没有找到对应的API的配置,请先检查配置'))
|
||||
}
|
||||
// 获取他的基础地址
|
||||
apiSetting.gptUrl = ApiData.base_url
|
||||
}
|
||||
|
||||
// 判断是不是又模型名字,没有的话获取推理设置那边的
|
||||
if (apiSetting.model == null || isEmpty(apiSetting.model)) {
|
||||
apiSetting.model = cwApiSetting?.inferenceModel || ''
|
||||
}
|
||||
}
|
||||
|
||||
// 再次检查,没有就报错
|
||||
if (isEmpty(apiSetting.apiKey) || isEmpty(apiSetting.gptUrl) || isEmpty(apiSetting.model)) {
|
||||
throw new Error(t('文案处理API设置不完整,请检查API地址,密钥和模型是否设置正确'))
|
||||
}
|
||||
@ -185,6 +212,20 @@ export class CopyWritingServiceHandle extends BookBasicHandle {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* AI文案批量生成主方法
|
||||
*
|
||||
* 根据传入的文案ID数组,自动获取文案处理相关设置,循环调用AI接口(支持流式和非流式),
|
||||
* 生成新文案并通过 SendReturnMessage 实时返回结果。
|
||||
*
|
||||
* - 支持重试机制,失败自动重试3次
|
||||
* - 支持流式和非流式AI接口
|
||||
* - 处理完毕后返回所有文案结构(不做持久化保存)
|
||||
*
|
||||
* @param ids 需要处理的文案ID数组
|
||||
* @returns Promise<SuccessItem | ErrorItem> 处理结果,包含所有文案结构或错误信息
|
||||
*/
|
||||
async CopyWritingAIGeneration(ids: string[]) {
|
||||
try {
|
||||
if (ids.length === 0) {
|
||||
|
||||
@ -6,5 +6,6 @@ export class WriteHandle {
|
||||
this.copyWritingServiceHandle = new CopyWritingServiceHandle()
|
||||
}
|
||||
|
||||
/** 需要处理的文案ID数组 */
|
||||
CopyWritingAIGeneration = async (ids: string[]) => await this.copyWritingServiceHandle.CopyWritingAIGeneration(ids)
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ import { isEmpty } from 'lodash'
|
||||
import { TimeDelay } from '@/define/Tools/time'
|
||||
import TooltipButton from '../common/TooltipButton.vue'
|
||||
import { t } from '@/i18n'
|
||||
import { OptionKeyName, OptionType } from '@/define/enum/option'
|
||||
|
||||
let softwareStore = useSoftwareStore()
|
||||
|
||||
@ -41,7 +42,6 @@ const simpleSetting = computed(() => props.simpleSetting)
|
||||
|
||||
const emit = defineEmits(['split-save', 'save-simple-setting'])
|
||||
|
||||
let CopyWriting = {}
|
||||
let message = useMessage()
|
||||
let dialog = useDialog()
|
||||
|
||||
@ -50,7 +50,7 @@ let resizeObserver = null
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: t("序号"),
|
||||
title: t('序号'),
|
||||
key: 'index',
|
||||
width: 80,
|
||||
render: (_, index) => index + 1
|
||||
@ -337,10 +337,24 @@ function ClearAIGeneration() {
|
||||
simpleSetting.value.wordStruct.forEach((item) => {
|
||||
item.newWord = ''
|
||||
})
|
||||
await CopyWriting.SaveCWAISimpleSetting()
|
||||
|
||||
// 开始保存
|
||||
let res = await window.option.ModifyOptionByKey(
|
||||
OptionKeyName.InferenceAI.CW_SimpleSetting,
|
||||
JSON.stringify(simpleSetting.value),
|
||||
OptionType.JSON
|
||||
)
|
||||
if (res.code != 1) {
|
||||
message.error(
|
||||
t('清空失败:{error}', {
|
||||
error: res.message
|
||||
})
|
||||
)
|
||||
return
|
||||
}
|
||||
message.success(t('清空成功'))
|
||||
} catch (error) {
|
||||
message.error(t('清空失败:', { error: error.message }))
|
||||
message.error(t('清空失败:{error}', { error: error.message }))
|
||||
}
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
@ -511,9 +525,24 @@ const handleDelete = (id) => {
|
||||
return false
|
||||
}
|
||||
simpleSetting.value.wordStruct[index].newWord = ''
|
||||
// 保存数据
|
||||
await CopyWriting.SaveCWAISimpleSetting()
|
||||
|
||||
console.log('删除后数据:', simpleSetting.value, simpleSetting.value.wordStruct)
|
||||
|
||||
// 开始保存
|
||||
let res = await window.option.ModifyOptionByKey(
|
||||
OptionKeyName.InferenceAI.CW_SimpleSetting,
|
||||
JSON.stringify(simpleSetting.value),
|
||||
OptionType.JSON
|
||||
)
|
||||
if (res.code == 1) {
|
||||
message.success(t('清空成功'))
|
||||
} else {
|
||||
message.error(
|
||||
t('清空失败:{error}', {
|
||||
error: res.message
|
||||
})
|
||||
)
|
||||
}
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
message.info(t('取消清空'))
|
||||
|
||||
@ -133,7 +133,7 @@
|
||||
</n-form-item>
|
||||
|
||||
<!-- 尾帧图片链接 -->
|
||||
<n-form-item :label="t('尾帧图片链接(可选)')" :show-feedback="false">
|
||||
<!-- <n-form-item :label="t('尾帧图片链接(可选)')" :show-feedback="false">
|
||||
<div class="input-with-preview">
|
||||
<n-input
|
||||
v-model:value="videoMessage.mjVideoOptionsObject.extendEndImageUrl"
|
||||
@ -199,7 +199,7 @@
|
||||
<n-text depth="3" class="placeholder-text">{{ t('图片预览') }}</n-text>
|
||||
</div>
|
||||
</div>
|
||||
</n-form-item>
|
||||
</n-form-item> -->
|
||||
|
||||
<!-- 提示词 -->
|
||||
<n-form-item :label="t('提示词(可选)')" :show-feedback="false">
|
||||
|
||||
@ -211,10 +211,11 @@ const columns = [
|
||||
h(NImage, {
|
||||
src: row.outImagePath,
|
||||
height: 130,
|
||||
objectFit: 'cover',
|
||||
width: 160,
|
||||
objectFit: 'contain',
|
||||
style: {
|
||||
borderRadius: '4px',
|
||||
maxWidth: '160px',
|
||||
width: '160px',
|
||||
height: '130px'
|
||||
},
|
||||
fallbackSrc: define.zhanwei_image,
|
||||
|
||||
@ -479,7 +479,7 @@ async function handleExport() {
|
||||
message.error(res.message)
|
||||
return
|
||||
}
|
||||
presetStore.showCharacterPresetArray.unshift(res.data)
|
||||
presetStore.showScenePresetArray.unshift(res.data)
|
||||
message.success(t('导入 {name} 到场景预设成功', { name: element.name }))
|
||||
}
|
||||
presetStore.presetChangeCount++
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
<template>
|
||||
<n-card :title="t('剪映关键帧设置')">
|
||||
<div style="display: flex; height: 40px; line-height: 40px">
|
||||
<div style="margin-bottom: 10px; width: 100px">{{ t('打帧方式') }}</div>
|
||||
<n-space align="center" :size="12">
|
||||
<n-space align="center">
|
||||
<div>{{ t('打帧方式') }}</div>
|
||||
<n-select
|
||||
v-model:value="keyFrameData.keyFrame"
|
||||
:options="getJianyingKeyFrameOptions()"
|
||||
@ -12,7 +13,8 @@
|
||||
})
|
||||
"
|
||||
/>
|
||||
<div style="width: 170px">
|
||||
</n-space>
|
||||
<div>
|
||||
<disabled-wrapper
|
||||
:un-use="!softwareStore.authorization.isPro"
|
||||
one-cell="true"
|
||||
@ -32,9 +34,7 @@
|
||||
</n-tooltip>
|
||||
</disabled-wrapper>
|
||||
</div>
|
||||
|
||||
<span>{{ t('匀速关键帧时间') }}</span>
|
||||
<div>
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
:step="0.1"
|
||||
@ -43,77 +43,82 @@
|
||||
v-model:value="keyFrameData.keyFrameTime"
|
||||
style="width: 100px"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<n-button style="margin-left: 30px" type="info" @click="SaveKeyFrameSetting">保存</n-button>
|
||||
</div>
|
||||
</div>
|
||||
<n-button type="info" @click="SaveKeyFrameSetting">保存</n-button>
|
||||
</n-space>
|
||||
<n-card style="margin-top: 10px" :title="t('上下关键帧设置')">
|
||||
<div style="display: flex; height: 40px; line-height: 40px">
|
||||
<div>{{ t('上关键帧位置') }}</div>
|
||||
<n-space align="center" :size="12">
|
||||
<span>{{ t('上关键帧位置') }}</span>
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
v-model:value="keyFrameData.upDownKeyFrame.startPosition"
|
||||
style="width: 100px; margin-right: 10px"
|
||||
style="width: 100px"
|
||||
/>
|
||||
<div>{{ t('下关键帧位置') }}</div>
|
||||
<span>{{ t('下关键帧位置') }}</span>
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
v-model:value="keyFrameData.upDownKeyFrame.endPosition"
|
||||
style="width: 100px; margin-right: 10px"
|
||||
></n-input-number>
|
||||
|
||||
<div>{{ t('缩放大小') }}</div>
|
||||
style="width: 100px"
|
||||
/>
|
||||
<span>{{ t('缩放大小') }}</span>
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
v-model:value="keyFrameData.upDownKeyFrame.defaultScale"
|
||||
style="width: 100px; margin-right: 10px"
|
||||
></n-input-number>
|
||||
</div>
|
||||
style="width: 100px"
|
||||
/>
|
||||
</n-space>
|
||||
</n-card>
|
||||
<n-card :title="t('左右关键帧设置')" style="margin-top: 10px">
|
||||
<div style="display: flex; height: 40px; line-height: 40px">
|
||||
<div>{{ t('左关键帧位置') }}</div>
|
||||
<n-space align="center" :size="12">
|
||||
<span>{{ t('左关键帧位置') }}</span>
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
v-model:value="keyFrameData.leftRightKeyFrame.startPosition"
|
||||
style="width: 100px; margin-right: 10px"
|
||||
style="width: 100px"
|
||||
/>
|
||||
<div>{{ t('右关键帧位置') }}</div>
|
||||
<span>{{ t('右关键帧位置') }}</span>
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
v-model:value="keyFrameData.leftRightKeyFrame.endPosition"
|
||||
style="width: 100px; margin-right: 10px"
|
||||
></n-input-number>
|
||||
|
||||
<div>{{ t('缩放大小') }}</div>
|
||||
style="width: 100px"
|
||||
/>
|
||||
<span>{{ t('缩放大小') }}</span>
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
v-model:value="keyFrameData.leftRightKeyFrame.defaultScale"
|
||||
style="width: 100px; margin-right: 10px"
|
||||
></n-input-number>
|
||||
</div>
|
||||
style="width: 100px"
|
||||
/>
|
||||
</n-space>
|
||||
</n-card>
|
||||
<n-card :title="t('缩放关键帧设置')" style="margin-top: 10px">
|
||||
<div style="display: flex; height: 40px; line-height: 40px">
|
||||
<div>{{ t('开始缩放大小') }}</div>
|
||||
<n-space align="center" :size="12">
|
||||
<span>{{ t('开始缩放大小') }}</span>
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
v-model:value="keyFrameData.scaleKeyFrame.startPosition"
|
||||
style="width: 100px; margin-right: 10px"
|
||||
style="width: 100px"
|
||||
/>
|
||||
<div>{{ t('结束缩放大小') }}</div>
|
||||
<span>{{ t('结束缩放大小') }}</span>
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
v-model:value="keyFrameData.scaleKeyFrame.endPosition"
|
||||
></n-input-number>
|
||||
</div>
|
||||
style="width: 100px"
|
||||
/>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</n-card>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useMessage, NSelect, NCheckbox, NInputNumber, NCard, NButton, NTooltip } from 'naive-ui'
|
||||
import {
|
||||
useMessage,
|
||||
NSelect,
|
||||
NCheckbox,
|
||||
NInputNumber,
|
||||
NCard,
|
||||
NButton,
|
||||
NTooltip,
|
||||
NSpace
|
||||
} from 'naive-ui'
|
||||
import { getJianyingKeyFrameOptions, JianyingKeyFrameEnum } from '@/define/enum/jianyingEnum'
|
||||
import { defaultJianyingKeyFrameSetting } from '@/renderer/src/common/initialData'
|
||||
import { cloneDeep, isEmpty } from 'lodash'
|
||||
|
||||
@ -421,7 +421,7 @@ const handleAccountAddSuccess = async (accountData) => {
|
||||
mjBotChannelId: null,
|
||||
nijiBotChannelId: null,
|
||||
queueSize: 5,
|
||||
remark: global.machineId,
|
||||
remark: softwareStore.authorization.machineId,
|
||||
remixAutoSubmit: false,
|
||||
timeoutMinutes: 6,
|
||||
userAgent:
|
||||
@ -429,11 +429,11 @@ const handleAccountAddSuccess = async (accountData) => {
|
||||
}
|
||||
// 覆盖
|
||||
accountData = Object.assign(defaultSetting, accountData)
|
||||
accountData.id = uuidv4()
|
||||
accountData.id = crypto.randomUUID()
|
||||
accountData.createTime = new Date()
|
||||
accountData.updateTime = new Date()
|
||||
accountData.version = version
|
||||
accountData.remark = global.machineId
|
||||
accountData.version = softwareStore.versionInfo.currentVersion
|
||||
accountData.remark = softwareStore.authorization.machineId
|
||||
|
||||
if (accountData.hasOwnProperty('enable') == false) {
|
||||
accountData.enable = true
|
||||
@ -474,7 +474,7 @@ const handleAccountUpdateSuccess = async (accountData) => {
|
||||
}
|
||||
|
||||
accountData.updateTime = new Date()
|
||||
accountData.version = version
|
||||
accountData.version = softwareStore.versionInfo.currentVersion
|
||||
accountData.remark = softwareStore.authorization.machineId
|
||||
|
||||
let findIndex = remoteSettings.value.accountList.findIndex((item) => item.id === accountData.id)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user