feat(frontend): 搭建桌面端基础界面与 Workspace
- App Shell 壳层:主导航、次导航、Title Bar、状态栏 - Vault 入口页:最近 Vault、打开/创建 Vault、AI Core 状态 - Workspace 与文件树:浏览、打开、创建笔记/文件夹 - Design Token:浅色/深色主题 CSS Variables - Contracts / Service / Store / Router 基础架构 - 统一 ApiClient 与 SseClient,对接后端 API 契约
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||
import { useWorkspaceStore } from '@/stores/workspace'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'vault-entry',
|
||||
component: () => import('@/features/vault/VaultEntry.vue'),
|
||||
meta: { title: '选择知识库' },
|
||||
},
|
||||
{
|
||||
path: '/workspace',
|
||||
name: 'workspace',
|
||||
component: () => import('@/features/workspace/WorkspaceView.vue'),
|
||||
meta: { title: '工作区', requiresVault: true },
|
||||
},
|
||||
{
|
||||
path: '/search',
|
||||
name: 'search',
|
||||
component: () => import('@/features/search/SearchView.vue'),
|
||||
meta: { title: '搜索', requiresVault: true },
|
||||
},
|
||||
{
|
||||
path: '/chat',
|
||||
name: 'chat',
|
||||
component: () => import('@/features/chat/ChatView.vue'),
|
||||
meta: { title: 'AI 对话', requiresVault: true },
|
||||
},
|
||||
{
|
||||
path: '/agent/runs/:runId?',
|
||||
name: 'agent',
|
||||
component: () => import('@/features/agent/AgentView.vue'),
|
||||
meta: { title: 'Agent Trace', requiresVault: true },
|
||||
},
|
||||
{
|
||||
path: '/tasks',
|
||||
name: 'tasks',
|
||||
component: () => import('@/features/tasks/TasksView.vue'),
|
||||
meta: { title: '任务', requiresVault: true },
|
||||
},
|
||||
{
|
||||
path: '/extensions/skills',
|
||||
name: 'skills',
|
||||
component: () => import('@/features/skills/SkillsView.vue'),
|
||||
meta: { title: 'Skill 管理', requiresVault: true },
|
||||
},
|
||||
{
|
||||
path: '/extensions/plugins',
|
||||
name: 'plugins',
|
||||
component: () => import('@/features/plugins/PluginsView.vue'),
|
||||
meta: { title: 'Plugin 管理', requiresVault: true },
|
||||
},
|
||||
{
|
||||
path: '/themes',
|
||||
name: 'themes',
|
||||
component: () => import('@/features/themes/ThemesView.vue'),
|
||||
meta: { title: '主题管理', requiresVault: true },
|
||||
},
|
||||
{
|
||||
path: '/settings',
|
||||
name: 'settings',
|
||||
component: () => import('@/features/settings/SettingsView.vue'),
|
||||
meta: { title: '设置', requiresVault: true },
|
||||
children: [
|
||||
{ path: '', redirect: '/settings/general' },
|
||||
{ path: 'general', component: () => import('@/features/settings/sections/GeneralSection.vue') },
|
||||
{ path: 'editor', component: () => import('@/features/settings/sections/EditorSection.vue') },
|
||||
{ path: 'providers', component: () => import('@/features/settings/sections/ProvidersSection.vue') },
|
||||
{ path: 'index', component: () => import('@/features/settings/sections/IndexSection.vue') },
|
||||
{ path: 'permissions', component: () => import('@/features/settings/sections/PermissionsSection.vue') },
|
||||
{ path: 'ai-core', component: () => import('@/features/settings/sections/AiCoreSection.vue') },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes,
|
||||
})
|
||||
|
||||
router.beforeEach((to, _from, next) => {
|
||||
const workspaceStore = useWorkspaceStore()
|
||||
if (to.meta.requiresVault && !workspaceStore.hasVault) {
|
||||
next({ path: '/' })
|
||||
return
|
||||
}
|
||||
if (to.path === '/' && workspaceStore.hasVault) {
|
||||
next({ path: '/workspace' })
|
||||
return
|
||||
}
|
||||
next()
|
||||
})
|
||||
|
||||
router.afterEach((to) => {
|
||||
const baseTitle = '知笔知己'
|
||||
const title = to.meta.title as string | undefined
|
||||
document.title = title ? `${title} · ${baseTitle}` : baseTitle
|
||||
})
|
||||
|
||||
export default router
|
||||
Reference in New Issue
Block a user