提示词保存

This commit is contained in:
2025-11-13 01:06:28 +08:00
parent fc7d2ccea5
commit c652d0ddf3
49 changed files with 4072 additions and 2452 deletions

View File

@@ -0,0 +1,242 @@
<script setup>
import { ref, watch } from 'vue'
import { EditOutlined, CopyOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import ChatMessageRenderer from '@/components/ChatMessageRenderer.vue'
import { ChatMessageApi } from '@/api/chat'
import { streamChat } from '@/utils/streamChat'
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
mergedText: {
type: String,
default: '',
},
textCount: {
type: Number,
default: 0,
},
})
const emit = defineEmits(['update:visible', 'copy', 'save', 'use'])
const batchPrompt = ref('')
const batchPromptEditMode = ref(false)
const batchPromptGenerating = ref(false)
const hasGenerated = ref(false)
watch(() => props.visible, (newVal) => {
if (newVal && props.mergedText && !hasGenerated.value) {
generateBatchPrompt()
} else if (!newVal) {
batchPrompt.value = ''
batchPromptEditMode.value = false
batchPromptGenerating.value = false
hasGenerated.value = false
}
})
watch(() => props.mergedText, (newVal) => {
if (props.visible && newVal && !hasGenerated.value) {
generateBatchPrompt()
}
})
async function generateBatchPrompt() {
if (!props.mergedText || hasGenerated.value) return
hasGenerated.value = true
try {
batchPromptGenerating.value = true
const createPayload = { roleId: 20 }
console.debug('createChatConversationMy payload(batch):', createPayload)
const conversationResp = await ChatMessageApi.createChatConversationMy(createPayload)
let conversationId = null
if (conversationResp?.data) {
conversationId = typeof conversationResp.data === 'object' ? conversationResp.data.id : conversationResp.data
}
if (!conversationId) {
throw new Error('创建对话失败:未获取到 conversationId')
}
const aiContent = await streamChat({
conversationId,
content: props.mergedText,
onUpdate: (fullText) => {
batchPrompt.value = fullText
},
enableTypewriter: true,
typewriterSpeed: 10,
typewriterBatchSize: 2
})
if (aiContent && aiContent !== batchPrompt.value) {
batchPrompt.value = aiContent
}
message.success(`批量分析完成:已基于 ${props.textCount} 个视频的文案生成综合提示词`)
} catch (aiError) {
console.error('AI生成失败:', aiError)
message.error('AI生成失败请稍后重试')
} finally {
batchPromptGenerating.value = false
}
}
function handleClose() {
emit('update:visible', false)
}
function handleCopy() {
emit('copy', batchPrompt.value)
}
function handleSave() {
emit('save', batchPrompt.value)
}
function handleUse() {
emit('use', batchPrompt.value)
}
</script>
<template>
<a-modal
:open="visible"
title="综合分析结果"
:width="800"
:maskClosable="false"
:keyboard="false"
@cancel="handleClose">
<div class="batch-prompt-modal">
<div v-if="!batchPromptEditMode" class="batch-prompt-display">
<ChatMessageRenderer
:content="batchPrompt"
:is-streaming="batchPromptGenerating"
/>
</div>
<a-textarea
v-else
v-model:value="batchPrompt"
:rows="15"
placeholder="内容将在这里显示..." />
</div>
<template #footer>
<a-space>
<a-button size="small" :title="batchPromptEditMode ? '取消编辑' : '编辑'" @click="batchPromptEditMode = !batchPromptEditMode">
<template #icon>
<EditOutlined />
</template>
</a-button>
<a-button size="small" title="复制" @click="handleCopy">
<template #icon>
<CopyOutlined />
</template>
</a-button>
<a-button size="small" title="保存提示词" @click="handleSave" :disabled="!batchPrompt.trim()">
保存提示词
</a-button>
<a-button @click="handleClose">取消</a-button>
<a-button
type="primary"
:disabled="batchPromptGenerating || !batchPrompt.trim()"
@click="handleUse">去创作</a-button>
</a-space>
</template>
</a-modal>
</template>
<style scoped>
.batch-prompt-modal {
min-height: 200px;
}
.batch-prompt-display {
min-height: 300px;
max-height: 500px;
overflow-y: auto;
padding: 12px;
background: #0d0d0d;
border: 1px solid var(--color-border);
border-radius: 6px;
line-height: 1.6;
}
.batch-prompt-display :deep(h1) {
font-size: 18px;
font-weight: 600;
margin: 12px 0;
color: var(--color-text);
}
.batch-prompt-display :deep(h2) {
font-size: 16px;
font-weight: 600;
margin: 16px 0 8px 0;
color: var(--color-text);
}
.batch-prompt-display :deep(h3) {
font-size: 14px;
font-weight: 600;
margin: 12px 0 6px 0;
color: var(--color-text-secondary);
}
.batch-prompt-display :deep(p) {
margin: 8px 0;
color: var(--color-text-secondary);
}
.batch-prompt-display :deep(ul),
.batch-prompt-display :deep(ol) {
margin: 8px 0;
padding-left: 20px;
}
.batch-prompt-display :deep(li) {
margin: 4px 0;
color: var(--color-text-secondary);
}
.batch-prompt-display :deep(strong) {
font-weight: 600;
color: var(--color-text);
}
.batch-prompt-display :deep(code) {
background: #1a1a1a;
padding: 2px 6px;
border-radius: 4px;
font-family: 'Courier New', monospace;
font-size: 12px;
color: #e11d48;
}
.batch-prompt-display :deep(pre) {
background: #1a1a1a;
padding: 12px;
border-radius: 6px;
overflow-x: auto;
margin: 8px 0;
}
.batch-prompt-display :deep(pre code) {
background: transparent;
padding: 0;
}
.batch-prompt-display :deep(blockquote) {
border-left: 3px solid var(--color-primary);
padding-left: 12px;
margin: 8px 0;
color: var(--color-text-secondary);
}
</style>