feat: 实现剧本创作与拆解前端工作台

This commit is contained in:
GouJ
2026-08-27 19:33:51 +08:00
parent edc003443f
commit 2ee6f049f6
56 changed files with 7597 additions and 2 deletions
+100
View File
@@ -0,0 +1,100 @@
<script setup lang="ts">
import { computed, ref } from 'vue'
import { useRoute } from 'vue-router'
import { Clapperboard, FolderOpen, FileText, Layers, PanelLeftClose, PanelLeftOpen, Settings2 } from '@lucide/vue'
import { DialogTrigger } from 'reka-ui'
import { AppDialog } from './components/ui'
/** 应用框架只承载导航与连接说明,不混入 graph 业务。 */
const route = useRoute()
const collapsed = ref(false)
const settingsOpen = ref(false)
const projectId = computed(() => (route.params.projectId ? String(route.params.projectId) : ''))
const apiBase = import.meta.env.VITE_API_BASE_URL || '/api'
</script>
<template>
<div class="app-shell" :class="{ 'sidebar-collapsed': collapsed }">
<a href="#main-content" class="skip-link">跳到主要内容</a>
<aside class="sidebar">
<RouterLink to="/projects" class="brand"
><span class="brand-mark"><Clapperboard :size="21" :stroke-width="1.5" /></span
><span class="sidebar-label"
><strong>短剧工作台</strong><small>SHORT DRAMA STUDIO</small></span
></RouterLink
>
<div class="sidebar-section-label sidebar-label">工作空间</div>
<nav aria-label="主导航">
<RouterLink to="/projects" class="side-link" :class="{ selected: !projectId }" title="我的剧本"
><FolderOpen :size="18" /><span class="sidebar-label">我的剧本</span></RouterLink
>
</nav>
<template v-if="projectId"
><div class="sidebar-section-label sidebar-label mt-8">当前项目</div>
<nav aria-label="工作流导航">
<RouterLink
:to="`/projects/${projectId}/create-drama`"
class="side-link"
active-class="selected"
title="剧本创作"
><FileText :size="18" /><span class="sidebar-label">剧本创作</span
><span class="sidebar-label ml-auto text-[10px] text-stone-500">01</span></RouterLink
><RouterLink
:to="`/projects/${projectId}/breakdown`"
class="side-link"
active-class="selected"
title="剧本拆解"
><Layers :size="18" /><span class="sidebar-label">剧本拆解</span
><span class="sidebar-label ml-auto text-[10px] text-stone-500">02</span></RouterLink
>
</nav></template
>
<div class="sidebar-footer">
<AppDialog
v-model:open="settingsOpen"
title="后端连接"
description="页面直接使用现有后端接口,所有生成操作都会真实提交。"
><template #trigger
><DialogTrigger class="side-link w-full" title="后端连接"
><Settings2 :size="17" /><span class="sidebar-label">连接说明</span></DialogTrigger
></template
>
<dl class="detail-grid mt-7">
<dt>API 地址</dt>
<dd>
<code>{{ apiBase }}</code>
</dd>
<dt>开发环境</dt>
<dd>复制 .env.example .env API_PROXY_TARGET 指向你的后端服务然后重启 Vite</dd>
<dt>生产环境</dt>
<dd> /api 配置反向代理并为拆解和恢复接口设置足够长的读取超时</dd>
<dt>状态更新</dt>
<dd>项目详情每 6 秒刷新一次checkpoint 只在节点或批次结束后更新</dd>
</dl></AppDialog
>
<div class="sidebar-divider"></div>
<button
class="side-link w-full"
:aria-label="collapsed ? '展开侧栏' : '折叠侧栏'"
@click="collapsed = !collapsed"
>
<PanelLeftOpen v-if="collapsed" :size="17" /><PanelLeftClose v-else :size="17" /><span
class="sidebar-label"
>收起侧栏</span
>
</button>
<p class="sidebar-label mt-3 px-3 text-[10px] text-stone-500">创作 · 整理 · 逐镜成形</p>
</div>
</aside>
<div class="app-main">
<header class="topbar">
<span class="text-xs text-muted"
>短剧制作 / <span class="text-ink">{{ route.meta.title || '工作空间' }}</span></span
><span class="topbar-note"
>创作工作区 <span class="ml-2 font-mono text-[10px] text-faint">v0.1</span></span
>
</header>
<main id="main-content" tabindex="-1"><RouterView /></main>
</div>
</div>
</template>