From ff283013dafe64af5261e32fb64c4956f6411a52 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Mon, 4 May 2026 20:15:49 +0800 Subject: [PATCH] feat(web): prompt-templates view + chat/admin routes + nav + isAdmin guard --- web/src/components/layout/NavBar.vue | 39 ++++ web/src/router/index.ts | 59 ++++++ web/src/stores/auth.ts | 3 +- .../prompt-templates/PromptTemplatesView.vue | 184 ++++++++++++++++++ 4 files changed, 284 insertions(+), 1 deletion(-) create mode 100644 web/src/views/prompt-templates/PromptTemplatesView.vue diff --git a/web/src/components/layout/NavBar.vue b/web/src/components/layout/NavBar.vue index fba8a7d..6aa4c6e 100644 --- a/web/src/components/layout/NavBar.vue +++ b/web/src/components/layout/NavBar.vue @@ -19,6 +19,45 @@ > 项目 + + 对话 + + + 模板 + + + 我的用量 + + import('@/views/workspaces/WorkspaceHomeView.vue'), meta: { requiresAuth: true }, }, + { + path: '/chat', + name: 'chat-home', + component: () => import('@/views/chat/ChatHomeView.vue'), + meta: { requiresAuth: true }, + }, + { + path: '/chat/:conversationId', + name: 'chat-detail', + component: () => import('@/views/chat/ChatDetailView.vue'), + meta: { requiresAuth: true }, + }, + { + path: '/projects/:pid/chat', + name: 'project-chat-home', + component: () => import('@/views/chat/ChatHomeView.vue'), + meta: { requiresAuth: true }, + }, + { + path: '/projects/:pid/chat/:conversationId', + name: 'project-chat-detail', + component: () => import('@/views/chat/ChatDetailView.vue'), + meta: { requiresAuth: true }, + }, + { + path: '/prompt-templates', + name: 'prompt-templates', + component: () => + import('@/views/prompt-templates/PromptTemplatesView.vue'), + meta: { requiresAuth: true }, + }, + { + path: '/me/usage', + name: 'me-usage', + component: () => import('@/views/admin/UsageView.vue'), + meta: { requiresAuth: true }, + }, + { + path: '/admin/llm-endpoints', + name: 'admin-llm-endpoints', + component: () => import('@/views/admin/LLMEndpointsView.vue'), + meta: { requiresAuth: true, requiresAdmin: true }, + }, + { + path: '/admin/llm-models', + name: 'admin-llm-models', + component: () => import('@/views/admin/LLMModelsView.vue'), + meta: { requiresAuth: true, requiresAdmin: true }, + }, + { + path: '/admin/usage', + name: 'admin-usage', + component: () => import('@/views/admin/UsageView.vue'), + props: { adminMode: true }, + meta: { requiresAuth: true, requiresAdmin: true }, + }, ] const router = createRouter({ @@ -74,6 +130,9 @@ router.beforeEach((to) => { if (to.meta.requiresAuth && !auth.isAuthenticated) { return { name: 'login', query: { next: to.fullPath } } } + if (to.meta.requiresAdmin && !auth.isAdmin) { + return { name: 'home' } + } if (to.name === 'login' && auth.isAuthenticated) { return { name: 'home' } } diff --git a/web/src/stores/auth.ts b/web/src/stores/auth.ts index 14b0162..2ea507d 100644 --- a/web/src/stores/auth.ts +++ b/web/src/stores/auth.ts @@ -53,6 +53,7 @@ export const useAuthStore = defineStore('auth', () => { const user = ref(safeReadJSON('user', null)) const isAuthenticated = computed(() => !!token.value) + const isAdmin = computed(() => !!user.value?.is_admin) function setSession(t: string, u: User) { token.value = t @@ -68,5 +69,5 @@ export const useAuthStore = defineStore('auth', () => { safeRemove('user') } - return { token, user, isAuthenticated, setSession, clearSession } + return { token, user, isAuthenticated, isAdmin, setSession, clearSession } }) diff --git a/web/src/views/prompt-templates/PromptTemplatesView.vue b/web/src/views/prompt-templates/PromptTemplatesView.vue new file mode 100644 index 0000000..386840a --- /dev/null +++ b/web/src/views/prompt-templates/PromptTemplatesView.vue @@ -0,0 +1,184 @@ + + +