fix: 修复问题
This commit is contained in:
@@ -9,6 +9,7 @@ import GmIcon from '@/components/icons/Icon.vue'
|
||||
import { UserPromptApi } from '@/api/userPrompt'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import GradientButton from '@/components/GradientButton.vue'
|
||||
import PromptSelector from '@/components/PromptSelector.vue'
|
||||
import { setJSON, getJSON } from '@/utils/storage'
|
||||
import BasicLayout from '@/layouts/components/BasicLayout.vue'
|
||||
|
||||
@@ -38,28 +39,10 @@ const { getVoiceText } = useVoiceText()
|
||||
// 提示词相关状态
|
||||
const allPrompts = ref([])
|
||||
const loadingPrompts = ref(false)
|
||||
const showAllPromptsModal = ref(false)
|
||||
const selectedPromptId = ref(null)
|
||||
const promptSearchKeyword = ref('')
|
||||
const DISPLAY_COUNT = 6 // 展示的提示词数量
|
||||
|
||||
// 计算属性:展示的部分提示词
|
||||
const displayPrompts = computed(() => {
|
||||
return allPrompts.value.slice(0, DISPLAY_COUNT)
|
||||
})
|
||||
|
||||
// 计算属性:过滤后的全部提示词(用于"更多"弹窗)
|
||||
const filteredPrompts = computed(() => {
|
||||
if (!promptSearchKeyword.value.trim()) {
|
||||
return allPrompts.value
|
||||
}
|
||||
const keyword = promptSearchKeyword.value.trim().toLowerCase()
|
||||
return allPrompts.value.filter(p =>
|
||||
p.name.toLowerCase().includes(keyword) ||
|
||||
(p.content && p.content.toLowerCase().includes(keyword))
|
||||
)
|
||||
})
|
||||
|
||||
/**
|
||||
* 加载用户提示词列表
|
||||
* 从服务器获取当前用户的提示词,并按创建时间倒序排列
|
||||
@@ -88,9 +71,6 @@ async function loadUserPrompts() {
|
||||
const timeB = b.createTime ? new Date(b.createTime).getTime() : 0
|
||||
return timeB - timeA
|
||||
})
|
||||
|
||||
// 如果用户没有选择提示词,尝试恢复本地存储的选中项或默认选中第一个
|
||||
await restoreOrSelectPrompt()
|
||||
} else {
|
||||
throw new Error(response?.msg || response?.message || '加载失败')
|
||||
}
|
||||
@@ -102,97 +82,17 @@ async function loadUserPrompts() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存选中的提示词ID到本地存储
|
||||
*/
|
||||
async function saveSelectedPromptId(promptId) {
|
||||
if (promptId) {
|
||||
await setJSON('copywriting_selected_prompt_id', promptId)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从本地存储恢复选中的提示词ID
|
||||
*/
|
||||
async function loadSelectedPromptId() {
|
||||
try {
|
||||
const savedId = await getJSON('copywriting_selected_prompt_id', null)
|
||||
return savedId
|
||||
} catch (error) {
|
||||
console.error('加载保存的提示词ID失败:', error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID选中提示词
|
||||
*/
|
||||
async function selectPromptById(promptId) {
|
||||
if (!promptId) return false
|
||||
|
||||
const prompt = allPrompts.value.find(p => p.id === promptId)
|
||||
if (prompt && prompt.content) {
|
||||
selectedPromptId.value = prompt.id
|
||||
form.value.prompt = prompt.content
|
||||
promptStore.setPrompt(prompt.content, prompt)
|
||||
await saveSelectedPromptId(promptId)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复或选中提示词
|
||||
* 优先级:本地存储的选中项 > 第一个提示词
|
||||
*/
|
||||
async function restoreOrSelectPrompt() {
|
||||
if (allPrompts.value.length === 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 如果已经有选中项且内容存在,不需要重新选择
|
||||
if (selectedPromptId.value && form.value.prompt) {
|
||||
// 验证选中的提示词是否还在列表中
|
||||
const currentPrompt = allPrompts.value.find(p => p.id === selectedPromptId.value)
|
||||
if (currentPrompt && currentPrompt.content === form.value.prompt) {
|
||||
return true // 已经正确选中,无需操作
|
||||
}
|
||||
}
|
||||
|
||||
// 尝试恢复本地存储的选中项
|
||||
const savedPromptId = await loadSelectedPromptId()
|
||||
if (savedPromptId) {
|
||||
const restored = await selectPromptById(savedPromptId)
|
||||
if (restored) {
|
||||
return true // 成功恢复保存的选中项
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有保存的选中项或恢复失败,则选中第一个
|
||||
const firstPrompt = allPrompts.value[0]
|
||||
if (firstPrompt?.content) {
|
||||
selectedPromptId.value = firstPrompt.id
|
||||
form.value.prompt = firstPrompt.content
|
||||
promptStore.setPrompt(firstPrompt.content, firstPrompt)
|
||||
await saveSelectedPromptId(firstPrompt.id)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// 选择提示词
|
||||
async function selectPrompt(prompt) {
|
||||
// 处理提示词选择
|
||||
function handlePromptChange(prompt) {
|
||||
if (!prompt || !prompt.content) {
|
||||
message.warning('提示词内容为空')
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
selectedPromptId.value = prompt.id
|
||||
form.value.prompt = prompt.content
|
||||
promptStore.setPrompt(prompt.content, prompt)
|
||||
await saveSelectedPromptId(prompt.id)
|
||||
showAllPromptsModal.value = false
|
||||
}
|
||||
|
||||
|
||||
@@ -217,7 +117,7 @@ async function waitForUserInfo() {
|
||||
async function ensureUserInfoLoaded() {
|
||||
const isLoggedIn = userStore.isLoggedIn
|
||||
const hasNoUserId = !userStore.userId
|
||||
|
||||
|
||||
if (isLoggedIn && hasNoUserId) {
|
||||
try {
|
||||
await userStore.fetchUserInfo()
|
||||
@@ -239,13 +139,13 @@ async function initializePage() {
|
||||
if (promptStore.currentPrompt) {
|
||||
form.value.prompt = promptStore.currentPrompt
|
||||
}
|
||||
|
||||
|
||||
// 2. 等待用户信息初始化完成
|
||||
await waitForUserInfo()
|
||||
|
||||
|
||||
// 3. 确保用户信息已加载
|
||||
await ensureUserInfoLoaded()
|
||||
|
||||
|
||||
// 4. 加载提示词列表
|
||||
await loadUserPrompts()
|
||||
}
|
||||
@@ -255,34 +155,11 @@ onMounted(() => {
|
||||
initializePage()
|
||||
})
|
||||
|
||||
/**
|
||||
* keep-alive 激活时的处理
|
||||
* 1. 如果有提示词列表,尝试恢复或选中提示词
|
||||
* 2. 如果没有提示词列表但用户已登录,加载提示词列表
|
||||
*/
|
||||
onActivated(async () => {
|
||||
// 如果已经有提示词列表,尝试恢复或选中提示词
|
||||
if (allPrompts.value.length > 0) {
|
||||
await restoreOrSelectPrompt()
|
||||
}
|
||||
// 如果提示词列表为空,但用户已登录,则尝试加载
|
||||
else if (userStore.userId) {
|
||||
await loadUserPrompts()
|
||||
}
|
||||
// 如果用户未登录,等待用户信息加载
|
||||
else if (!userStore.userId && userStore.isLoggedIn) {
|
||||
await ensureUserInfoLoaded()
|
||||
if (userStore.userId) {
|
||||
await loadUserPrompts()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 监听 userId 变化:如果之前没有 userId,现在有了,则自动加载提示词
|
||||
watch(() => userStore.userId, async (newUserId, oldUserId) => {
|
||||
const userIdChanged = newUserId && !oldUserId
|
||||
const hasNoPrompts = allPrompts.value.length === 0
|
||||
|
||||
|
||||
if (userIdChanged && hasNoPrompts) {
|
||||
await loadUserPrompts()
|
||||
}
|
||||
@@ -510,47 +387,25 @@ defineOptions({ name: 'ContentStyleCopywriting' })
|
||||
<a-form :model="form" layout="vertical" class="form-container">
|
||||
<a-form-item class="form-item">
|
||||
<template #label>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<span>
|
||||
选择提示词风格
|
||||
<span class="form-tip-inline">从已保存的提示词中选择</span>
|
||||
</span>
|
||||
<a-space>
|
||||
<a-button
|
||||
size="small"
|
||||
type="link"
|
||||
@click="showAllPromptsModal = true"
|
||||
:disabled="allPrompts.length === 0">
|
||||
更多 ({{ allPrompts.length }})
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
<span>
|
||||
选择提示词风格
|
||||
<span class="form-tip-inline">从已保存的提示词中选择</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<!-- 提示词标签展示区域 -->
|
||||
<div v-if="displayPrompts.length > 0" class="prompt-tags-container">
|
||||
<div class="prompt-tags-grid">
|
||||
<div
|
||||
v-for="prompt in displayPrompts"
|
||||
:key="prompt.id"
|
||||
class="prompt-tag"
|
||||
:class="{ 'prompt-tag-selected': selectedPromptId === prompt.id }"
|
||||
@click="selectPrompt(prompt)">
|
||||
<span class="prompt-tag-name">{{ prompt.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 使用 PromptSelector 组件 -->
|
||||
<PromptSelector
|
||||
v-model="selectedPromptId"
|
||||
:prompts="allPrompts"
|
||||
:loading="loadingPrompts"
|
||||
:search-keyword="promptSearchKeyword"
|
||||
@change="handlePromptChange"
|
||||
@update:searchKeyword="promptSearchKeyword = $event"
|
||||
/>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<div v-else-if="!loadingPrompts" class="prompt-empty">
|
||||
<div style="color: var(--color-text-secondary); font-size: 14px; text-align: center; padding: 20px;">
|
||||
您可以在视频分析页面保存风格
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<div v-else class="prompt-loading">
|
||||
<a-spin size="small" />
|
||||
<!-- 空状态提示 -->
|
||||
<div v-if="!loadingPrompts && allPrompts.length === 0" class="prompt-empty" style="color: var(--color-text-secondary); font-size: 14px; text-align: center; padding: 20px;">
|
||||
您可以在视频分析页面保存风格
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
@@ -664,58 +519,6 @@ defineOptions({ name: 'ContentStyleCopywriting' })
|
||||
</a-row>
|
||||
</div>
|
||||
|
||||
<!-- 更多提示词弹窗 -->
|
||||
<a-modal
|
||||
v-model:open="showAllPromptsModal"
|
||||
title="选择提示词"
|
||||
:width="800"
|
||||
:maskClosable="false"
|
||||
>
|
||||
<div class="all-prompts-modal">
|
||||
<!-- 搜索框 -->
|
||||
<a-input
|
||||
v-model:value="promptSearchKeyword"
|
||||
placeholder="搜索提示词名称或内容..."
|
||||
allow-clear
|
||||
style="margin-bottom: 16px;"
|
||||
>
|
||||
<template #prefix>
|
||||
<GmIcon name="icon-search" :size="16" />
|
||||
</template>
|
||||
</a-input>
|
||||
|
||||
<!-- 提示词列表(标签形式) -->
|
||||
<div v-if="filteredPrompts.length > 0" class="all-prompts-tags">
|
||||
<div
|
||||
v-for="prompt in filteredPrompts"
|
||||
:key="prompt.id"
|
||||
class="all-prompt-tag"
|
||||
:class="{ 'all-prompt-tag-selected': selectedPromptId === prompt.id }"
|
||||
@click="selectPrompt(prompt)"
|
||||
>
|
||||
<span class="all-prompt-tag-name">{{ prompt.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<div v-else style="text-align: center; padding: 40px; color: var(--color-text-secondary);">
|
||||
没有找到匹配的提示词
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<a-space>
|
||||
<a-button @click="showAllPromptsModal = false">取消</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
@click="loadUserPrompts"
|
||||
:loading="loadingPrompts"
|
||||
>
|
||||
刷新列表
|
||||
</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</a-modal>
|
||||
</BasicLayout>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user