Files
short-drama-agent-front/src/features/projects/ProjectLayout.vue
T

77 lines
3.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { computed, provide } from 'vue'
import { useRoute } from 'vue-router'
import {
ArrowLeft,
RefreshCw,
FileText,
Layers,
Camera,
Images,
Palette,
Fingerprint,
LoaderCircle,
Clapperboard
} from '@lucide/vue'
import { StatusBadge } from '../../components/ui'
import { projectContextKey, useProjectData } from './context'
import { getOperation } from '../workflows/operations'
/** 项目级数据与操作状态跨 graph 页面共享。 */
const route = useRoute()
const id = computed(() => String(route.params.projectId))
const context = useProjectData(id)
provide(projectContextKey, context)
const operation = computed(() => getOperation(id.value))
</script>
<template>
<section class="page-container">
<RouterLink to="/projects" class="back-link"><ArrowLeft :size="14" />全部剧本</RouterLink>
<div class="page-heading mt-5">
<div class="min-w-0">
<p class="eyebrow">项目工作台</p>
<h1 class="break-words">
{{ context.project.value?.title || context.project.value?.topic || '读取项目' }}
</h1>
<p class="page-description">{{ context.project.value?.style || '剧本与拆解结果' }}</p>
</div>
<div class="flex shrink-0 items-center gap-3">
<StatusBadge v-if="context.project.value" :status="context.project.value.status" /><button
class="button button-secondary"
:disabled="context.loading.value"
@click="context.refresh"
>
<RefreshCw :size="14" :class="{ 'animate-spin': context.loading.value }" /><span
class="hidden sm:inline"
>刷新</span
>
</button>
</div>
</div>
<nav class="workflow-nav" aria-label="项目工作流">
<RouterLink :to="`/projects/${id}/create-drama`"><FileText :size="17" />剧本创作</RouterLink>
<RouterLink :to="`/projects/${id}/breakdown`"><Layers :size="17" />剧本拆解</RouterLink>
<RouterLink :to="`/projects/${id}/visual-style`"><Palette :size="17" />视觉风格</RouterLink>
<RouterLink :to="`/projects/${id}/subject-identity`"><Fingerprint :size="17" />主体身份</RouterLink>
<RouterLink :to="`/projects/${id}/subject-images`"><Images :size="17" />形态图片</RouterLink>
<RouterLink :to="`/projects/${id}/storyboard`"><Camera :size="17" />分镜设计</RouterLink>
<RouterLink :to="`/projects/${id}/production`"><Clapperboard :size="17" />镜头生产</RouterLink>
</nav>
<p v-if="context.error.value" class="alert alert-error mt-4" role="alert">
{{ context.error.value }}<span v-if="context.project.value"> 当前保留上次成功读取的数据</span>
</p>
<p v-if="operation.pending" class="alert mt-4 flex items-center gap-2" role="status">
<LoaderCircle :size="16" class="shrink-0 animate-spin" />{{
operation.label
}}可切换页面查看结果请勿重复提交或关闭浏览器关闭页面不会取消后端任务
</p>
<p v-if="operation.error" class="alert alert-error mt-4" role="alert">{{ operation.error }}</p>
<p v-if="operation.notice" class="alert mt-4" role="status">{{ operation.notice }}</p>
<RouterView v-if="context.project.value" :key="id" />
<div v-else-if="context.loading.value" class="py-12 text-sm text-muted" role="status">
正在读取项目和工作流记录……
</div>
</section>
</template>