fix: 使用 NScrollbar 统一内容区滚动条
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import WorkspacePage from '../../components/ui/WorkspacePage.vue'
|
||||
import { NButton, NCollapse, NCollapseItem, NProgress, NTab, NTabs, NTag } from 'naive-ui'
|
||||
import { NScrollbar, NButton, NCollapse, NCollapseItem, NProgress, NTab, NTabs, NTag } from 'naive-ui'
|
||||
import { computed, ref } from 'vue'
|
||||
import { ArrowRight, Download, Check, Circle } from '@lucide/vue'
|
||||
import { EmptyState } from '../../components/ui'
|
||||
@@ -138,32 +138,38 @@ function exportScript() {
|
||||
<div v-if="tab === 'episodes'" class="h-full">
|
||||
<div v-if="episode" class="script-workspace">
|
||||
<aside class="episode-list">
|
||||
<p class="px-4 pb-3 pt-5 text-[11px] font-medium tracking-wider text-muted">剧集目录</p>
|
||||
<NButton
|
||||
v-for="item in episodes"
|
||||
:key="item.episode"
|
||||
:aria-pressed="episode.episode === item.episode"
|
||||
@click="selected = item.episode"
|
||||
class="episode-link"
|
||||
:class="{ active: episode.episode === item.episode }"
|
||||
><span class="episode-number">{{ String(item.episode).padStart(2, '0') }}</span
|
||||
><span class="truncate">{{ item.title }}</span></NButton
|
||||
>
|
||||
<NScrollbar class="panel-scroll" content-class="episode-list-content">
|
||||
<p class="px-4 pb-3 pt-5 text-[11px] font-medium tracking-wider text-muted">
|
||||
剧集目录
|
||||
</p>
|
||||
<NButton
|
||||
v-for="item in episodes"
|
||||
:key="item.episode"
|
||||
:aria-pressed="episode.episode === item.episode"
|
||||
@click="selected = item.episode"
|
||||
class="episode-link"
|
||||
:class="{ active: episode.episode === item.episode }"
|
||||
><span class="episode-number">{{ String(item.episode).padStart(2, '0') }}</span
|
||||
><span class="truncate">{{ item.title }}</span></NButton
|
||||
>
|
||||
</NScrollbar>
|
||||
</aside>
|
||||
<article class="script-page">
|
||||
<p class="eyebrow">第 {{ String(episode.episode).padStart(2, '0') }} 集</p>
|
||||
<h2 class="mt-3 text-2xl font-semibold">{{ episode.title }}</h2>
|
||||
<p v-if="episode.summary" class="script-summary">{{ episode.summary }}</p>
|
||||
<div class="script-body">{{ episode.content }}</div>
|
||||
<dl v-if="episode.conflict || episode.hook" class="script-notes">
|
||||
<template v-if="episode.conflict"
|
||||
><dt>核心冲突</dt>
|
||||
<dd>{{ episode.conflict }}</dd></template
|
||||
><template v-if="episode.hook"
|
||||
><dt>结尾钩子</dt>
|
||||
<dd>{{ episode.hook }}</dd></template
|
||||
>
|
||||
</dl>
|
||||
<NScrollbar class="panel-scroll" content-class="script-page-content">
|
||||
<p class="eyebrow">第 {{ String(episode.episode).padStart(2, '0') }} 集</p>
|
||||
<h2 class="mt-3 text-2xl font-semibold">{{ episode.title }}</h2>
|
||||
<p v-if="episode.summary" class="script-summary">{{ episode.summary }}</p>
|
||||
<div class="script-body">{{ episode.content }}</div>
|
||||
<dl v-if="episode.conflict || episode.hook" class="script-notes">
|
||||
<template v-if="episode.conflict"
|
||||
><dt>核心冲突</dt>
|
||||
<dd>{{ episode.conflict }}</dd></template
|
||||
><template v-if="episode.hook"
|
||||
><dt>结尾钩子</dt>
|
||||
<dd>{{ episode.hook }}</dd></template
|
||||
>
|
||||
</dl>
|
||||
</NScrollbar>
|
||||
</article>
|
||||
</div>
|
||||
<EmptyState
|
||||
@@ -172,91 +178,101 @@ function exportScript() {
|
||||
description="剧集写入数据库后会自动出现在这里。角色与世界观生成期间,可以在右侧查看已保存的执行记录。"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="tab === 'characters'" class="p-6 lg:p-8">
|
||||
<div v-if="project?.characters.length" class="divide-y divide-line">
|
||||
<article
|
||||
v-for="character in project.characters"
|
||||
:key="character.id"
|
||||
class="py-5 first:pt-0"
|
||||
>
|
||||
<div class="mb-3 flex items-center gap-3">
|
||||
<h3 class="text-lg font-semibold">{{ character.name }}</h3>
|
||||
<NTag size="small" :bordered="false">{{ character.role || '角色' }}</NTag
|
||||
><span class="text-xs text-muted">{{ character.occupation }}</span>
|
||||
</div>
|
||||
<NScrollbar v-if="tab !== 'episodes'" class="panel-scroll"
|
||||
><div v-if="tab === 'characters'" class="p-6 lg:p-8">
|
||||
<div v-if="project?.characters.length" class="divide-y divide-line">
|
||||
<article
|
||||
v-for="character in project.characters"
|
||||
:key="character.id"
|
||||
class="py-5 first:pt-0"
|
||||
>
|
||||
<div class="mb-3 flex items-center gap-3">
|
||||
<h3 class="text-lg font-semibold">{{ character.name }}</h3>
|
||||
<NTag size="small" :bordered="false">{{ character.role || '角色' }}</NTag
|
||||
><span class="text-xs text-muted">{{ character.occupation }}</span>
|
||||
</div>
|
||||
<dl class="detail-grid">
|
||||
<template
|
||||
v-for="field in [
|
||||
{ key: 'personality', label: '性格' },
|
||||
{ key: 'goal', label: '目标' },
|
||||
{ key: 'secret', label: '秘密' }
|
||||
] as const"
|
||||
:key="field.key"
|
||||
><dt>{{ field.label }}</dt>
|
||||
<dd>{{ character[field.key] || '未提供' }}</dd></template
|
||||
>
|
||||
</dl>
|
||||
</article>
|
||||
</div>
|
||||
<EmptyState v-else title="尚无角色设定" description="角色生成结束后会在这里显示。" />
|
||||
</div>
|
||||
<div v-if="tab === 'world'" class="p-6 lg:p-8">
|
||||
<div v-if="project?.world">
|
||||
<p class="eyebrow">故事的发生之地</p>
|
||||
<h2 class="mb-7 mt-3 text-xl font-semibold">
|
||||
{{ project.world.era }} · {{ project.world.location }}
|
||||
</h2>
|
||||
<dl class="detail-grid">
|
||||
<template
|
||||
v-for="field in [
|
||||
{ key: 'personality', label: '性格' },
|
||||
{ key: 'goal', label: '目标' },
|
||||
{ key: 'secret', label: '秘密' }
|
||||
{ key: 'background', label: '背景' },
|
||||
{ key: 'coreConflict', label: '核心冲突' },
|
||||
{ key: 'tone', label: '基调' }
|
||||
] as const"
|
||||
:key="field.key"
|
||||
><dt>{{ field.label }}</dt>
|
||||
<dd>{{ character[field.key] || '未提供' }}</dd></template
|
||||
<dd>{{ project.world[field.key] || '未提供' }}</dd></template
|
||||
>
|
||||
</dl>
|
||||
</article>
|
||||
</div>
|
||||
<EmptyState v-else title="尚无角色设定" description="角色生成结束后会在这里显示。" />
|
||||
</div>
|
||||
<div v-if="tab === 'world'" class="p-6 lg:p-8">
|
||||
<div v-if="project?.world">
|
||||
<p class="eyebrow">故事的发生之地</p>
|
||||
<h2 class="mb-7 mt-3 text-xl font-semibold">
|
||||
{{ project.world.era }} · {{ project.world.location }}
|
||||
</h2>
|
||||
<dl class="detail-grid">
|
||||
<template
|
||||
v-for="field in [
|
||||
{ key: 'background', label: '背景' },
|
||||
{ key: 'coreConflict', label: '核心冲突' },
|
||||
{ key: 'tone', label: '基调' }
|
||||
] as const"
|
||||
:key="field.key"
|
||||
><dt>{{ field.label }}</dt>
|
||||
<dd>{{ project.world[field.key] || '未提供' }}</dd></template
|
||||
<NCollapse v-if="project.world.rules" class="mt-6 text-sm"
|
||||
><NCollapseItem name="details"
|
||||
><template #header>世界规则</template>
|
||||
<NScrollbar class="code-scroll mt-3" x-scrollable>
|
||||
<pre class="json-view">{{
|
||||
JSON.stringify(project.world.rules, null, 2)
|
||||
}}</pre>
|
||||
</NScrollbar>
|
||||
</NCollapseItem></NCollapse
|
||||
>
|
||||
</dl>
|
||||
<NCollapse v-if="project.world.rules" class="mt-6 text-sm"
|
||||
</div>
|
||||
<EmptyState v-else title="尚无世界观" description="世界观会在角色设定之后生成。" />
|
||||
</div>
|
||||
<div v-if="tab === 'review'" class="p-6 lg:p-8">
|
||||
<div v-if="project?.reviews.length" class="space-y-5">
|
||||
<article
|
||||
v-for="review in project.reviews"
|
||||
:key="review.id"
|
||||
class="border-b border-line pb-5"
|
||||
>
|
||||
<div class="mb-3 flex justify-between gap-3">
|
||||
<span
|
||||
class="text-sm font-medium"
|
||||
:class="review.passed ? 'text-success' : 'text-danger'"
|
||||
>{{ review.passed ? '审核通过' : '需要修改' }}</span
|
||||
><time class="text-xs text-muted">{{ formatDate(review.createdAt) }}</time>
|
||||
</div>
|
||||
<p class="whitespace-pre-wrap text-sm leading-7">
|
||||
{{ review.message || '本次审核未附加说明。' }}
|
||||
</p>
|
||||
</article>
|
||||
</div>
|
||||
<EmptyState
|
||||
v-else
|
||||
title="还没有审核记录"
|
||||
description="剧集生成完成后,工作流会进行内容审核与必要的改写。"
|
||||
/><NCollapse v-if="state?.rewriteSuggestion" class="mt-5 text-sm"
|
||||
><NCollapseItem name="details"
|
||||
><template #header>世界规则</template>
|
||||
<pre class="json-view mt-3">{{ JSON.stringify(project.world.rules, null, 2) }}</pre>
|
||||
><template #header>查看改写建议原文</template>
|
||||
<NScrollbar class="code-scroll mt-3" x-scrollable>
|
||||
<pre class="json-view">{{
|
||||
JSON.stringify(state.rewriteSuggestion, null, 2)
|
||||
}}</pre>
|
||||
</NScrollbar>
|
||||
</NCollapseItem></NCollapse
|
||||
>
|
||||
</div>
|
||||
<EmptyState v-else title="尚无世界观" description="世界观会在角色设定之后生成。" />
|
||||
</div>
|
||||
<div v-if="tab === 'review'" class="p-6 lg:p-8">
|
||||
<div v-if="project?.reviews.length" class="space-y-5">
|
||||
<article
|
||||
v-for="review in project.reviews"
|
||||
:key="review.id"
|
||||
class="border-b border-line pb-5"
|
||||
>
|
||||
<div class="mb-3 flex justify-between gap-3">
|
||||
<span
|
||||
class="text-sm font-medium"
|
||||
:class="review.passed ? 'text-success' : 'text-danger'"
|
||||
>{{ review.passed ? '审核通过' : '需要修改' }}</span
|
||||
><time class="text-xs text-muted">{{ formatDate(review.createdAt) }}</time>
|
||||
</div>
|
||||
<p class="whitespace-pre-wrap text-sm leading-7">
|
||||
{{ review.message || '本次审核未附加说明。' }}
|
||||
</p>
|
||||
</article>
|
||||
</div>
|
||||
<EmptyState
|
||||
v-else
|
||||
title="还没有审核记录"
|
||||
description="剧集生成完成后,工作流会进行内容审核与必要的改写。"
|
||||
/><NCollapse v-if="state?.rewriteSuggestion" class="mt-5 text-sm"
|
||||
><NCollapseItem name="details"
|
||||
><template #header>查看改写建议原文</template>
|
||||
<pre class="json-view mt-3">{{ JSON.stringify(state.rewriteSuggestion, null, 2) }}</pre>
|
||||
</NCollapseItem></NCollapse
|
||||
>
|
||||
</div>
|
||||
</NScrollbar>
|
||||
</main>
|
||||
<HistoryPanel :checkpoints="checkpoints" workflow="create-drama" />
|
||||
</div></div
|
||||
|
||||
Reference in New Issue
Block a user