3c9b65d982
- Nuxt 4 + Nuxt UI 4 + AI SDK 7 + Drizzle/SQLite - 主编规划大纲与章节简报、选派作家;作家流式写入章节文件并实时推送前端 - 逐章确认模式(默认)与自动模式;摘要与故事记忆 - 酒馆角色卡(PNG/JSON,V1-V3)与世界书导入 - 自定义最高优先级系统提示词、审稿/修改/多版本、任务日志与提示词检视 - 模拟 LLM 服务与端到端测试脚本 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
76 lines
2.8 KiB
Vue
76 lines
2.8 KiB
Vue
<script setup lang="ts">
|
|
import type { NavigationMenuItem } from '@nuxt/ui'
|
|
|
|
const route = useRoute()
|
|
const projectId = computed(() => (route.params.id as string | undefined) ?? null)
|
|
|
|
const { data: projectTitle } = useAsyncData(
|
|
'layout-project-title',
|
|
async () => (projectId.value ? (await $fetch<ProjectDetail>(`/api/projects/${projectId.value}`)).title : ''),
|
|
{ watch: [projectId], default: () => '' }
|
|
)
|
|
|
|
const mainItems = computed<NavigationMenuItem[]>(() => [
|
|
{ label: '我的作品', icon: 'i-lucide-library', to: '/', exact: true },
|
|
{ label: '模型与 API', icon: 'i-lucide-plug-zap', to: '/settings' }
|
|
])
|
|
|
|
const projectItems = computed<NavigationMenuItem[]>(() => {
|
|
if (!projectId.value) return []
|
|
const base = `/projects/${projectId.value}`
|
|
return [
|
|
{ label: '写作台', icon: 'i-lucide-pen-line', to: base, exact: true },
|
|
{ label: '故事设定', icon: 'i-lucide-book-open', to: `${base}/setting` },
|
|
{ label: '角色与世界书', icon: 'i-lucide-users', to: `${base}/characters` },
|
|
{ label: 'AI 团队', icon: 'i-lucide-bot', to: `${base}/team` },
|
|
{ label: '故事记忆', icon: 'i-lucide-brain', to: `${base}/memory` },
|
|
{ label: '任务日志', icon: 'i-lucide-list-checks', to: `${base}/jobs` }
|
|
]
|
|
})
|
|
|
|
const colorMode = useColorMode()
|
|
const isDark = computed({
|
|
get: () => colorMode.value === 'dark',
|
|
set: v => (colorMode.preference = v ? 'dark' : 'light')
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<UDashboardGroup unit="rem">
|
|
<UDashboardSidebar collapsible resizable :default-size="15" :ui="{ footer: 'border-t border-default' }">
|
|
<template #header="{ collapsed }">
|
|
<NuxtLink to="/" class="flex items-center gap-2 font-semibold">
|
|
<UIcon name="i-lucide-feather" class="size-5 text-primary shrink-0" />
|
|
<span v-if="!collapsed" class="truncate">AI 小说工坊</span>
|
|
</NuxtLink>
|
|
</template>
|
|
|
|
<template #default="{ collapsed }">
|
|
<UNavigationMenu :collapsed="collapsed" :items="mainItems" orientation="vertical" />
|
|
|
|
<template v-if="projectId">
|
|
<USeparator class="my-1" />
|
|
<div v-if="!collapsed" class="px-2.5 text-xs text-muted truncate" :title="projectTitle">
|
|
{{ projectTitle || '加载中…' }}
|
|
</div>
|
|
<UNavigationMenu :collapsed="collapsed" :items="projectItems" orientation="vertical" />
|
|
</template>
|
|
</template>
|
|
|
|
<template #footer="{ collapsed }">
|
|
<UButton
|
|
:icon="isDark ? 'i-lucide-moon' : 'i-lucide-sun'"
|
|
:label="collapsed ? undefined : (isDark ? '深色模式' : '浅色模式')"
|
|
color="neutral"
|
|
variant="ghost"
|
|
class="w-full"
|
|
:block="collapsed"
|
|
@click="isDark = !isDark"
|
|
/>
|
|
</template>
|
|
</UDashboardSidebar>
|
|
|
|
<slot />
|
|
</UDashboardGroup>
|
|
</template>
|