feat: ScriptDetailView 增强展示用户心愿和大纲元数据
This commit is contained in:
@@ -14,6 +14,10 @@
|
|||||||
<text class="eyebrow">PARALLEL LIFE</text>
|
<text class="eyebrow">PARALLEL LIFE</text>
|
||||||
<text class="script-title">{{ script?.title || '未命名剧本' }}</text>
|
<text class="script-title">{{ script?.title || '未命名剧本' }}</text>
|
||||||
<text class="script-summary">{{ script?.summary || '命运正在整理章节。' }}</text>
|
<text class="script-summary">{{ script?.summary || '命运正在整理章节。' }}</text>
|
||||||
|
<view v-if="userWish" class="wish-block">
|
||||||
|
<text class="wish-label">💭 用户心愿</text>
|
||||||
|
<text class="wish-text">{{ userWish }}</text>
|
||||||
|
</view>
|
||||||
<view class="stats">
|
<view class="stats">
|
||||||
<view class="stat">
|
<view class="stat">
|
||||||
<text class="stat-value">{{ script?.style || '爽文' }}</text>
|
<text class="stat-value">{{ script?.style || '爽文' }}</text>
|
||||||
@@ -39,8 +43,17 @@
|
|||||||
<Markdown :content="fullContent" />
|
<Markdown :content="fullContent" />
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-else class="outline-list">
|
<view v-else-if="activeTab === 'outline'" class="outline-list">
|
||||||
<view v-for="(item, index) in outline" :key="index" class="outline-card kos-card">
|
<!-- 优先展示从后端保存的真实大纲(来自 conversation.message.metadata) -->
|
||||||
|
<view v-if="outlineFromMeta && outlineFromMeta.length" v-for="(item, index) in outlineFromMeta" :key="'meta-' + index" class="outline-card kos-card">
|
||||||
|
<view class="outline-node">{{ index + 1 }}</view>
|
||||||
|
<view class="outline-body">
|
||||||
|
<text class="outline-title">{{ item.title }}</text>
|
||||||
|
<text class="outline-text">{{ item.text }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- fallback 到本地解析 -->
|
||||||
|
<view v-else v-for="(item, index) in outline" :key="'local-' + index" class="outline-card kos-card">
|
||||||
<view class="outline-node">{{ index + 1 }}</view>
|
<view class="outline-node">{{ index + 1 }}</view>
|
||||||
<view class="outline-body">
|
<view class="outline-body">
|
||||||
<text class="outline-title">{{ item.title }}</text>
|
<text class="outline-title">{{ item.title }}</text>
|
||||||
@@ -83,6 +96,34 @@ const lengthText = computed(() => {
|
|||||||
return map[script.value?.length] || script.value?.length || '中篇'
|
return map[script.value?.length] || script.value?.length || '中篇'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户心愿原文(从 EpicScript.theme 字段读取)
|
||||||
|
*/
|
||||||
|
const userWish = computed(() => script.value?.theme || '')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 大纲(从 plotJson.stages.outline 读取后端真实保存的 outline JSON)
|
||||||
|
* 后端 ShortNovelServiceImpl 在 novel_done 时会把 outline_created 事件累积到 metadata.stages.outline
|
||||||
|
*/
|
||||||
|
const outlineFromMeta = computed(() => {
|
||||||
|
const stages = script.value?.plotJson?.stages
|
||||||
|
if (!stages || !stages.outline) return []
|
||||||
|
const outline = stages.outline
|
||||||
|
const items = []
|
||||||
|
if (outline.title) items.push({ title: '标题', text: outline.title })
|
||||||
|
if (outline.logline) items.push({ title: '简介', text: outline.logline })
|
||||||
|
if (Array.isArray(outline.beats)) {
|
||||||
|
outline.beats.forEach((beat, i) => {
|
||||||
|
items.push({
|
||||||
|
title: beat.title || `章节 ${i + 1}`,
|
||||||
|
text: beat.text || beat.description || JSON.stringify(beat)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (outline.ending) items.push({ title: '结局', text: outline.ending })
|
||||||
|
return items
|
||||||
|
})
|
||||||
|
|
||||||
const detailTtsActionText = computed(() => {
|
const detailTtsActionText = computed(() => {
|
||||||
if (!script.value?.id) return '播放'
|
if (!script.value?.id) return '播放'
|
||||||
if (ttsPlayer.loading.value) return '生成中'
|
if (ttsPlayer.loading.value) return '生成中'
|
||||||
@@ -271,6 +312,30 @@ onUnmounted(() => {
|
|||||||
line-height: 1.62;
|
line-height: 1.62;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wish-block {
|
||||||
|
margin-top: 24rpx;
|
||||||
|
padding: 20rpx 22rpx;
|
||||||
|
border-radius: 22rpx;
|
||||||
|
background: linear-gradient(135deg, rgba(168, 85, 247, 0.16), rgba(232, 121, 249, 0.08));
|
||||||
|
border: 1rpx solid rgba(168, 85, 247, 0.24);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wish-label {
|
||||||
|
display: block;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #c186ff;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 2rpx;
|
||||||
|
margin-bottom: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wish-text {
|
||||||
|
display: block;
|
||||||
|
font-size: 26rpx;
|
||||||
|
line-height: 1.62;
|
||||||
|
color: rgba(255, 255, 255, 0.92);
|
||||||
|
}
|
||||||
|
|
||||||
.stats {
|
.stats {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
|||||||
Reference in New Issue
Block a user