修改剪映草稿生成,修改字幕分组报错,优化加载标签信息,修改预设样式
This commit is contained in:
parent
3db9352a42
commit
aa16a494bd
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "laitool-pro",
|
||||
"productName": "LaiToolPro",
|
||||
"version": "v3.4.9",
|
||||
"version": "v4.0.0",
|
||||
"description": "来推 Pro - 一款集音频处理、文案生成、图片生成、视频生成等功能于一体的多合一AI工具软件。",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "xiangbei",
|
||||
@ -84,6 +84,7 @@
|
||||
"resources/image/zhanwei.png",
|
||||
"resources/scripts/model/**",
|
||||
"resources/scripts/Lai.exe",
|
||||
"resources/scripts/xiangbei_jianying_main.exe",
|
||||
"resources/scripts/discordScript.js",
|
||||
"resources/tmp/**",
|
||||
"resources/icon.ico"
|
||||
|
||||
@ -31,7 +31,7 @@ interface ISoftwareData {
|
||||
|
||||
export const SoftwareData: ISoftwareData = {
|
||||
version: 'V3.4.2',
|
||||
date: '2025-08-08',
|
||||
date: '2025-09.09',
|
||||
systemInfo: {
|
||||
documentationUrl: 'https://rvgyir5wk1c.feishu.cn/wiki/WdaWwAfDdiLOnjkywIgcaQoKnog',
|
||||
updateUrl: 'https://pvwu1oahp5m.feishu.cn/docx/CAjGdTDlboJ3nVx0cQccOuNHnvd',
|
||||
|
||||
@ -462,6 +462,14 @@ export class BookTaskService extends RealmBaseService {
|
||||
modifyBookTask.subImageFolder = []
|
||||
modifyBookTask.srtPath = book.srtPath ?? undefined
|
||||
modifyBookTask.audioPath = book.audioPath ?? undefined
|
||||
} else {
|
||||
// 不重置基础数据的话,做一下数据的继承
|
||||
if (isEmpty(modifyBookTask.srtPath)) {
|
||||
modifyBookTask.srtPath = book.srtPath ?? undefined
|
||||
}
|
||||
if (isEmpty(modifyBookTask.audioPath)) {
|
||||
modifyBookTask.audioPath = book.audioPath ?? undefined
|
||||
}
|
||||
}
|
||||
|
||||
// 继承小说的srt和配音文件
|
||||
|
||||
@ -1411,7 +1411,7 @@ export default {
|
||||
'智能合并失败,{error}': 'Smart merge failed, {error}',
|
||||
'智能批量合并完成,所有字幕都已正确匹配': 'Smart batch merge completed, all subtitles matched correctly',
|
||||
'智能合并完成,{count} 个剩余字幕已写入后续行': 'Smart merge completed, {count} remaining subtitles written to subsequent lines',
|
||||
'处理过程中遇到错误,已停止智能匹配:\n\n{message}\n\n已处理字幕:${totalProcessed} 个\n剩余字幕:${totalRemaining} 个\n\n剩余字幕已按顺序写入后续行中,请手动调整文案匹配。': 'Error encountered during processing, smart matching stopped:\n\n{message}\n\nProcessed subtitles: ${totalProcessed}\nRemaining subtitles: ${totalRemaining}\n\nRemaining subtitles have been written to subsequent lines in order, please manually adjust content matching.',
|
||||
'处理过程中遇到错误,已停止智能匹配:\n\n{message}\n\n已处理字幕:{totalProcessed} 个\n剩余字幕:{totalRemaining} 个\n\n剩余字幕已按顺序写入后续行中,请手动调整文案匹配。': 'Error encountered during processing, smart matching stopped:\n\n{message}\n\nProcessed subtitles: ${totalProcessed}\nRemaining subtitles: ${totalRemaining}\n\nRemaining subtitles have been written to subsequent lines in order, please manually adjust content matching.',
|
||||
'第 {rowIndex} 行没有找到任何匹配的字幕': 'No matching subtitles found for line {rowIndex}',
|
||||
'第 {rowIndex} 行在处理字幕 “{subtitleText}” 时无法匹配,已累积文本 “{accumulatedText}” 与目标文案 “{text}”不匹配': 'Unable to match subtitle "{subtitleText}" on line {rowIndex}, accumulated text "{accumulatedText}" does not match target content "{text}"',
|
||||
'第 {rowIndex} 行的第一个字幕 “{subtitleText}” 与文案 “{text}” 不匹配': 'The first subtitle "{subtitleText}" on line {rowIndex} does not match the content "{text}"',
|
||||
|
||||
@ -1411,7 +1411,7 @@ export default {
|
||||
'智能合并失败,{error}': '智能合并失败,{error}',
|
||||
'智能批量合并完成,所有字幕都已正确匹配': '智能批量合并完成,所有字幕都已正确匹配',
|
||||
'智能合并完成,{count} 个剩余字幕已写入后续行': '智能合并完成,{count} 个剩余字幕已写入后续行',
|
||||
'处理过程中遇到错误,已停止智能匹配:\n\n{message}\n\n已处理字幕:${totalProcessed} 个\n剩余字幕:${totalRemaining} 个\n\n剩余字幕已按顺序写入后续行中,请手动调整文案匹配。': '处理过程中遇到错误,已停止智能匹配:\n\n{message}\n\n已处理字幕:${totalProcessed} 个\n剩余字幕:${totalRemaining} 个\n\n剩余字幕已按顺序写入后续行中,请手动调整文案匹配。',
|
||||
'处理过程中遇到错误,已停止智能匹配:\n\n{message}\n\n已处理字幕:{totalProcessed} 个\n剩余字幕:{totalRemaining} 个\n\n剩余字幕已按顺序写入后续行中,请手动调整文案匹配。': '处理过程中遇到错误,已停止智能匹配:\n\n{message}\n\n已处理字幕:{totalProcessed} 个\n剩余字幕:{totalRemaining} 个\n\n剩余字幕已按顺序写入后续行中,请手动调整文案匹配。',
|
||||
'第 {rowIndex} 行没有找到任何匹配的字幕': '第 {rowIndex} 行没有找到任何匹配的字幕',
|
||||
'第 {rowIndex} 行在处理字幕 “{subtitleText}” 时无法匹配,已累积文本 “{accumulatedText}” 与目标文案 “{text}”不匹配': '第 {rowIndex} 行在处理字幕 “{subtitleText}” 时无法匹配,已累积文本 “{accumulatedText}” 与目标文案 “{text}”不匹配',
|
||||
'第 {rowIndex} 行的第一个字幕 “{subtitleText}” 与文案 “{text}” 不匹配': '第 {rowIndex} 行的第一个字幕 “{subtitleText}” 与文案 “{text}” 不匹配',
|
||||
|
||||
@ -18,7 +18,6 @@ import { isEmpty } from 'lodash'
|
||||
import { define } from '@/define/define'
|
||||
import util from 'util'
|
||||
import { exec } from 'child_process'
|
||||
import { BookTaskDetail } from '@/define/model/book/bookTaskDetail'
|
||||
import { ValidateJson } from '@/define/Tools/validate'
|
||||
const execAsync = util.promisify(exec)
|
||||
import JianyingService from '../../jianying/jianyingService'
|
||||
@ -184,18 +183,6 @@ export class BookExportHandle extends BookBasicHandle {
|
||||
}
|
||||
}
|
||||
|
||||
// 时间单位转换:从毫秒转换为秒
|
||||
element.startTime = (element.startTime as number) / 1000
|
||||
element.endTime = (element.endTime as number) / 1000
|
||||
|
||||
// 处理子字幕数组,同样进行时间单位转换
|
||||
element.subValue = Array.isArray(element.subValue)
|
||||
? (element.subValue as BookTaskDetail.CopywritingSubValue[]).map((sub) => {
|
||||
sub.start_time = sub.start_time / 1000
|
||||
sub.end_time = sub.end_time / 1000
|
||||
return sub
|
||||
})
|
||||
: []
|
||||
|
||||
// 构建单帧数据对象
|
||||
let frameData = {
|
||||
|
||||
@ -1,96 +1,9 @@
|
||||
import { PresetCategory } from '@/define/data/presetData'
|
||||
import { Book } from '@/define/model/book/book'
|
||||
import { ErrorItem, SuccessItem } from '@/define/model/generalResponse'
|
||||
import { PresetModel } from '@/define/model/preset'
|
||||
import { errorMessage, successMessage } from '@/public/generalTools'
|
||||
import { usePresetStore } from '@renderer/stores'
|
||||
import { isEmpty } from 'lodash'
|
||||
import { checkImageExists } from './image'
|
||||
import { t } from '@/i18n'
|
||||
const presetStore = usePresetStore()
|
||||
|
||||
/**
|
||||
* 获取并处理预设列表数据
|
||||
*
|
||||
* 该方法根据指定条件从数据库获取预设数据,并进行适当处理后按类别分组返回。
|
||||
* 处理内容包括:
|
||||
* - 确保图片路径格式正确(添加file://前缀)
|
||||
* - 添加时间戳避免缓存问题
|
||||
* - 初始化选中状态标记
|
||||
* - 将预设按类型分组(角色、风格、场景)
|
||||
*
|
||||
* @param {PresetModel.QueryPresetCondition} [condition] - 查询条件,不提供则使用预设仓库的当前条件
|
||||
*
|
||||
* @returns {Promise<PresetModel.PresetCategoryCollection>} 按类别分组的预设集合
|
||||
* - character: 角色类预设数组
|
||||
* - style: 风格类预设数组
|
||||
* - scene: 场景类预设数组
|
||||
*
|
||||
* @throws {Error} 当获取预设数据失败时抛出错误
|
||||
*
|
||||
* @example
|
||||
* // 使用默认条件获取预设
|
||||
* const presets = await getShowTagsData();
|
||||
*
|
||||
* // 使用自定义条件获取预设
|
||||
* const presets = await getShowTagsData({
|
||||
* keyword: '自然',
|
||||
* category: PresetCategory.Scene
|
||||
* });
|
||||
*/
|
||||
export async function getShowTagsData(
|
||||
condition?: PresetModel.QueryPresetCondition
|
||||
): Promise<PresetModel.PresetCategoryCollection> {
|
||||
|
||||
if (!condition) {
|
||||
condition = {
|
||||
...presetStore.queryPresetCondition
|
||||
}
|
||||
}
|
||||
let res = await window.preset.GetPresetByCondition(condition)
|
||||
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message)
|
||||
}
|
||||
|
||||
let characterShowPreset: PresetModel.Preset[] = []
|
||||
let styleShowPreset: PresetModel.Preset[] = []
|
||||
let sceneShowPreset: PresetModel.Preset[] = []
|
||||
|
||||
for (let i = 0; res.data.presetArray && i < res.data.presetArray.length; i++) {
|
||||
const element = res.data.presetArray[i] as PresetModel.Preset
|
||||
if (element.showImage && element.showImage.length > 0) {
|
||||
// 处理路径中的特殊字符和中文
|
||||
let imagePath = element.showImage[0]
|
||||
// 确保本地文件路径有file://前缀
|
||||
if (
|
||||
!imagePath.startsWith('file://') &&
|
||||
(imagePath.startsWith('/') || imagePath.includes(':\\') || imagePath.startsWith('..'))
|
||||
) {
|
||||
imagePath = `file://${imagePath}`.replaceAll(/\\/g, '/')
|
||||
}
|
||||
|
||||
element.coverImage = imagePath + `?${Date.now()}` // 添加时间戳以避免缓存问题
|
||||
element.checked = false // 初始化checked属性
|
||||
} else {
|
||||
element.coverImage = ''
|
||||
element.checked = false // 初始化checked属性
|
||||
}
|
||||
|
||||
if (element.type == PresetCategory.Character) {
|
||||
characterShowPreset.push(element)
|
||||
} else if (element.type == PresetCategory.Style) {
|
||||
styleShowPreset.push(element)
|
||||
} else if (element.type == PresetCategory.Scene) {
|
||||
sceneShowPreset.push(element)
|
||||
}
|
||||
}
|
||||
return {
|
||||
character: characterShowPreset,
|
||||
style: styleShowPreset,
|
||||
scene: sceneShowPreset
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查分镜图片是否全部存在
|
||||
|
||||
@ -1,42 +1,50 @@
|
||||
<template>
|
||||
<div class="all-image-preview-container">
|
||||
<div v-for="(image, index) in images" :key="index" :style="{ margin: '5px' }">
|
||||
<div class="image-item" :class="{ placeholder: !isValidImage(image.url) }">
|
||||
<!-- 有效图片 -->
|
||||
<div v-if="isValidImage(image.url)" class="image-wrapper">
|
||||
<n-image
|
||||
:src="image.url"
|
||||
:alt="t('图片 {index}', { index: index + 1 })"
|
||||
object-fit="cover"
|
||||
:width="150"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div v-if="!comLoading" class="all-image-preview-container">
|
||||
<div v-for="(image, index) in images" :key="index" :style="{ margin: '5px' }">
|
||||
<div class="image-item" :class="{ placeholder: !isValidImage(image.url) }">
|
||||
<!-- 有效图片 -->
|
||||
<div v-if="isValidImage(image.url)" class="image-wrapper">
|
||||
<n-image
|
||||
:src="image.url"
|
||||
:alt="t('图片 {index}', { index: index + 1 })"
|
||||
object-fit="cover"
|
||||
:width="150"
|
||||
lazy="true"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 占位符 - 修改为与图片结构一致 -->
|
||||
<div
|
||||
v-else
|
||||
class="image-wrapper image-placeholder"
|
||||
:style="{
|
||||
width: `150px`,
|
||||
height: `150px`,
|
||||
backgroundColor: themeStore.menuPrimaryColor
|
||||
}"
|
||||
>
|
||||
<n-icon size="24" color="#fff">
|
||||
<image-outline />
|
||||
</n-icon>
|
||||
</div>
|
||||
<!-- 占位符 - 修改为与图片结构一致 -->
|
||||
<div
|
||||
v-else
|
||||
class="image-wrapper image-placeholder"
|
||||
:style="{
|
||||
width: `150px`,
|
||||
height: `150px`,
|
||||
backgroundColor: themeStore.menuPrimaryColor
|
||||
}"
|
||||
>
|
||||
<n-icon size="24" color="#fff">
|
||||
<image-outline />
|
||||
</n-icon>
|
||||
</div>
|
||||
|
||||
<!-- 左上角文本标识 -->
|
||||
<div class="image-label">{{ image.name }}</div>
|
||||
<!-- 右下角定位图标 -->
|
||||
<div class="image-locate" @click.stop="locateTableRow(image.id)" :title="t('定位到对应行')">
|
||||
<n-icon size="20" color="#fff">
|
||||
<locate-outline />
|
||||
</n-icon>
|
||||
<!-- 左上角文本标识 -->
|
||||
<div class="image-label">{{ image.name }}</div>
|
||||
<!-- 右下角定位图标 -->
|
||||
<div
|
||||
class="image-locate"
|
||||
@click.stop="locateTableRow(image.id)"
|
||||
:title="t('定位到对应行')"
|
||||
>
|
||||
<n-icon size="20" color="#fff">
|
||||
<locate-outline />
|
||||
</n-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<LoadingComponent v-else :description="t('加载中...')" size="large" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -48,16 +56,24 @@ import { LocateOutline } from '@vicons/ionicons5' // 添加定位图标
|
||||
import { useBookStore, useThemeStore } from '@/renderer/src/stores'
|
||||
import { isEmpty } from 'lodash'
|
||||
import { t } from '@/i18n'
|
||||
import { checkImageExists } from '@/renderer/src/common/image'
|
||||
|
||||
const bookStore = useBookStore()
|
||||
const themeStore = useThemeStore()
|
||||
const message = useMessage()
|
||||
|
||||
const images = ref([])
|
||||
const comLoading = ref(true)
|
||||
|
||||
onMounted(() => {
|
||||
bookStore.selectBookTaskDetail.forEach((item) => {
|
||||
if (!isEmpty(item.outImagePath)) {
|
||||
onMounted(async () => {
|
||||
await waitForImagesToLoad()
|
||||
window.addEventListener('locate-table-row', handleLocateTableRow)
|
||||
})
|
||||
|
||||
async function waitForImagesToLoad() {
|
||||
for (let i = 0; i < bookStore.selectBookTaskDetail.length; i++) {
|
||||
const item = bookStore.selectBookTaskDetail[i]
|
||||
if (!isEmpty(item.outImagePath) && (await checkImageExists(item.outImagePath))) {
|
||||
images.value.push({
|
||||
url: item.outImagePath.split('?t')[0] + '?t=' + Date.now(), // 添加时间戳以避免缓存
|
||||
alt: t('分镜_{name}', {
|
||||
@ -76,9 +92,9 @@ onMounted(() => {
|
||||
id: item.id // 保存ID用于定位
|
||||
})
|
||||
}
|
||||
})
|
||||
window.addEventListener('locate-table-row', handleLocateTableRow)
|
||||
})
|
||||
}
|
||||
comLoading.value = false
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('locate-table-row', handleLocateTableRow)
|
||||
@ -151,7 +167,7 @@ const labelBackgroundColor = computed(() => {
|
||||
}
|
||||
|
||||
.image-item:hover .image-wrapper {
|
||||
transform: scale(1.2);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* 添加阴影效果到父元素 */
|
||||
|
||||
@ -177,6 +177,7 @@ watch(
|
||||
watch(
|
||||
() => presetStore.presetChangeCount,
|
||||
(newValue, oldValue) => {
|
||||
console.log('presetChangeCount变化了,重新获取标签数据', newValue, oldValue)
|
||||
if (newValue !== oldValue) {
|
||||
fecthTagsData()
|
||||
}
|
||||
@ -241,7 +242,7 @@ function fecthTagsData() {
|
||||
})
|
||||
} catch (error) {
|
||||
message.error(t('获取标签数据失败,{error}', { error: error.message }))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 角色标签的点击事件
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
:width="dialogWidth"
|
||||
:height="dialogHeight"
|
||||
:content-component="dialogComponent"
|
||||
@close="handleOnclose"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@ -127,4 +128,13 @@ async function SelectConfirm(selectedStyles) {
|
||||
function OpenPresetLibraryHome() {
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
// 关闭预设库
|
||||
async function handleOnclose() {
|
||||
// 重新加载一个预设数据
|
||||
await presetStore.LoadPresetArray({
|
||||
isShow: true
|
||||
})
|
||||
presetStore.presetChangeCount++
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -221,7 +221,7 @@ onMounted(() => {
|
||||
}, 15000)
|
||||
})
|
||||
|
||||
function ErrorPosition(type) {
|
||||
async function ErrorPosition(type) {
|
||||
let id = ''
|
||||
softwareStore.skipRowIndex = 0
|
||||
if (type == 'gptPrompt') {
|
||||
@ -249,7 +249,12 @@ function ErrorPosition(type) {
|
||||
}
|
||||
} else if (type == 'image') {
|
||||
for (let i = 0; i < bookStore.selectBookTaskDetail.length; i++) {
|
||||
if (isEmpty(bookStore.selectBookTaskDetail[i].outImagePath)) {
|
||||
let item = bookStore.selectBookTaskDetail[i]
|
||||
if (
|
||||
!item.outImagePath ||
|
||||
isEmpty(item.outImagePath) ||
|
||||
!(await checkImageExists(item.outImagePath))
|
||||
) {
|
||||
id = bookStore.selectBookTaskDetail[i].id
|
||||
break
|
||||
}
|
||||
|
||||
@ -100,7 +100,6 @@ async function handleSave() {
|
||||
// 初始化数据
|
||||
onMounted(() => {
|
||||
console.log('初始化数据:', props.initData)
|
||||
debugger
|
||||
if (props.initData.value && props.initData.value.length > 0) {
|
||||
const lines = props.initData.value
|
||||
.map((item) => {
|
||||
|
||||
@ -253,7 +253,7 @@ const columns = [
|
||||
function computedInputContent() {
|
||||
inputContent.value = tableData.value
|
||||
.map((item) => {
|
||||
let w = item.afterGpt || ''
|
||||
let w = item.afterGpt || item.subValue?.map(v => v.srt_value).join(',') || ''
|
||||
if (!w.endsWith('。')) {
|
||||
w = w + '。'
|
||||
}
|
||||
|
||||
@ -132,9 +132,6 @@ export function useWordGroupBase(initData) {
|
||||
// 从后往前遍历,避免删除时索引变化的问题
|
||||
for (let i = data.value.length - 1; i >= 0; i--) {
|
||||
const currentRow = data.value[i]
|
||||
if (i == 64) {
|
||||
debugger
|
||||
}
|
||||
|
||||
// 检查当前行是否为空
|
||||
if (isRowEmpty(currentRow)) {
|
||||
@ -381,7 +378,7 @@ export function useWordGroupBase(initData) {
|
||||
initData: data,
|
||||
onSaveWord: (newWords) => {
|
||||
da?.destroy()
|
||||
|
||||
debugger
|
||||
for (let i = 0; i < data.value.length; i++) {
|
||||
const element = data.value[i]
|
||||
element.afterGpt = ''
|
||||
@ -444,11 +441,32 @@ export function useWordGroupBase(initData) {
|
||||
onPositiveClick: async () => {
|
||||
try {
|
||||
da?.destroy()
|
||||
debugger
|
||||
|
||||
// 深度清理数据,移除不可序列化的属性
|
||||
const cleanData = toRaw(data.value).map(item => ({
|
||||
no: item.no,
|
||||
id: item.id,
|
||||
lastId: item.lastId,
|
||||
word: item.word || '',
|
||||
afterGpt: item.afterGpt || '',
|
||||
startTime: item.startTime || 0,
|
||||
endTime: item.endTime || 0,
|
||||
timeLimit: item.timeLimit || '',
|
||||
subValue: (item.subValue || []).map(subItem => ({
|
||||
id: subItem.id,
|
||||
srt_value: subItem.srt_value,
|
||||
start_time: subItem.start_time,
|
||||
end_time: subItem.end_time
|
||||
}))
|
||||
}))
|
||||
|
||||
console.log("保存的数据", cleanData)
|
||||
softwareStore.spin.spinning = true
|
||||
softwareStore.spin.tip = t('正在保存文案信息...')
|
||||
let res = await window.book.SaveCopywritingInfo(
|
||||
bookStore.selectBookTask.id,
|
||||
toRaw(data.value),
|
||||
cleanData,
|
||||
OperateBookType.BOOKTASK
|
||||
)
|
||||
if (res.code != 1) {
|
||||
@ -514,7 +532,7 @@ export function useWordGroupBase(initData) {
|
||||
title: t('智能批量合并'),
|
||||
showIcon: true,
|
||||
content: t('确定要进行智能批量合并吗?将从第 {startIndex} 行开始处理。此操作会根据分镜文案内容自动将字幕合并到对应的行中。', {
|
||||
startFromIndex: startFromIndex
|
||||
startIndex: startFromIndex
|
||||
}),
|
||||
style: 'width: 500px',
|
||||
maskClosable: false,
|
||||
@ -853,7 +871,7 @@ export function useWordGroupBase(initData) {
|
||||
dialog.create({
|
||||
type: 'warning',
|
||||
title: t('智能合并部分完成'),
|
||||
content: t('处理过程中遇到错误,已停止智能匹配:\n\n{message}\n\n已处理字幕:${totalProcessed} 个\n剩余字幕:${totalRemaining} 个\n\n剩余字幕已按顺序写入后续行中,请手动调整文案匹配。', {
|
||||
content: t('处理过程中遇到错误,已停止智能匹配:\n\n{message}\n\n已处理字幕:{totalProcessed} 个\n剩余字幕:{totalRemaining} 个\n\n剩余字幕已按顺序写入后续行中,请手动调整文案匹配。', {
|
||||
message: processingError.message,
|
||||
totalProcessed: totalProcessed,
|
||||
totalRemaining: totalRemaining
|
||||
|
||||
@ -210,7 +210,7 @@ import {
|
||||
useBookStore
|
||||
} from '@/renderer/src/stores'
|
||||
|
||||
import { checBookTaskDetailImageExist, getShowTagsData } from '@/renderer/src/common/book'
|
||||
import { checBookTaskDetailImageExist } from '@/renderer/src/common/book'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useBookTaskCardOption } from '@/renderer/src/hooks/useBookTaskCardOption'
|
||||
import TooltipDropdown from '../../common/TooltipDropdown.vue'
|
||||
@ -368,14 +368,10 @@ async function handleOpenTask() {
|
||||
bookStore.selectBookTaskDetail = res.data
|
||||
bookStore.selectBookTask = { ...props.bookTask }
|
||||
|
||||
// 加载标签信息
|
||||
let tagRes = await getShowTagsData({
|
||||
// 加载一个预设数据
|
||||
await presetStore.LoadPresetArray({
|
||||
isShow: true
|
||||
})
|
||||
// 做一下数据的处理
|
||||
presetStore.showCharacterPresetArray = tagRes.character
|
||||
presetStore.showScenePresetArray = tagRes.scene
|
||||
presetStore.showStylePresetArray = tagRes.style
|
||||
|
||||
router.push('/original-book-detail/' + props.bookTask.id)
|
||||
} catch (error) {
|
||||
|
||||
@ -179,6 +179,7 @@ let contentBackgroundColor = computed(() => {
|
||||
.preset-card {
|
||||
transition: all 0.3s;
|
||||
height: 280px; /* 固定卡片高度 */
|
||||
width: 200px; /* 固定卡片宽度 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
|
||||
@ -68,10 +68,14 @@ const he = ref(props.height) // 使用const而不是let
|
||||
// 每次visible变为true时,重新计算尺寸
|
||||
watch(
|
||||
visible,
|
||||
(newVal) => {
|
||||
(newVal, oldVal) => {
|
||||
if (newVal === true) {
|
||||
calculateDimensions()
|
||||
}
|
||||
// 当 modal 从显示变为隐藏时,发出 close 事件
|
||||
if (oldVal === true && newVal === false) {
|
||||
emit('close')
|
||||
}
|
||||
emit('update:show', newVal)
|
||||
}
|
||||
)
|
||||
@ -107,7 +111,6 @@ const actualHeight = computed(() => he.value)
|
||||
|
||||
const handleClose = () => {
|
||||
visible.value = false
|
||||
emit('close')
|
||||
}
|
||||
|
||||
const handleConfirm = () => {
|
||||
|
||||
@ -45,6 +45,62 @@ export const usePresetStore = defineStore('preset', {
|
||||
}),
|
||||
getters: {},
|
||||
actions: {
|
||||
|
||||
async LoadPresetArray(condition?: PresetModel.QueryPresetCondition) {
|
||||
try {
|
||||
if (!condition) {
|
||||
condition = {
|
||||
...this.queryPresetCondition
|
||||
}
|
||||
}
|
||||
let res = await window.preset.GetPresetByCondition(condition)
|
||||
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message)
|
||||
}
|
||||
|
||||
let characterShowPreset: PresetModel.Preset[] = []
|
||||
let styleShowPreset: PresetModel.Preset[] = []
|
||||
let sceneShowPreset: PresetModel.Preset[] = []
|
||||
|
||||
for (let i = 0; res.data.presetArray && i < res.data.presetArray.length; i++) {
|
||||
const element = res.data.presetArray[i] as PresetModel.Preset
|
||||
if (element.showImage && element.showImage.length > 0) {
|
||||
// 处理路径中的特殊字符和中文
|
||||
let imagePath = element.showImage[0]
|
||||
// 确保本地文件路径有file://前缀
|
||||
if (
|
||||
!imagePath.startsWith('file://') &&
|
||||
(imagePath.startsWith('/') || imagePath.includes(':\\') || imagePath.startsWith('..'))
|
||||
) {
|
||||
imagePath = `file://${imagePath}`.replaceAll(/\\/g, '/')
|
||||
}
|
||||
|
||||
element.coverImage = imagePath + `?${Date.now()}` // 添加时间戳以避免缓存问题
|
||||
element.checked = false // 初始化checked属性
|
||||
} else {
|
||||
element.coverImage = ''
|
||||
element.checked = false // 初始化checked属性
|
||||
}
|
||||
|
||||
if (element.type == PresetCategory.Character) {
|
||||
characterShowPreset.push(element)
|
||||
} else if (element.type == PresetCategory.Style) {
|
||||
styleShowPreset.push(element)
|
||||
} else if (element.type == PresetCategory.Scene) {
|
||||
sceneShowPreset.push(element)
|
||||
}
|
||||
}
|
||||
|
||||
// 更新数据
|
||||
this.showCharacterPresetArray = characterShowPreset
|
||||
this.showScenePresetArray = sceneShowPreset
|
||||
this.showStylePresetArray = styleShowPreset
|
||||
} catch (error) {
|
||||
console.error('加载预设数据失败:', error)
|
||||
throw error
|
||||
}
|
||||
},
|
||||
ResetSelectPreset() {
|
||||
const now = new Date()
|
||||
const formattedDate = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`
|
||||
|
||||
@ -195,7 +195,6 @@ let selectBorderColor = computed(() => {
|
||||
}
|
||||
|
||||
.preset-flex-item {
|
||||
width: 200px; /* 固定卡片宽度 */
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user