Selaa lähdekoodia

feat: 添加401、404页面

jiaxing.liao 2 päivää sitten
vanhempi
commit
7ae96e270c

+ 14 - 0
apps/web/src/i18n/locales/en-us.ts

@@ -1781,6 +1781,20 @@ export default {
 				output: 'Output'
 			}
 		},
+		system: {
+			actions: {
+				backHome: 'Back Home',
+				goBack: 'Go Back'
+			},
+			unauthorized: {
+				title: 'You do not have access to this page',
+				description: 'You do not have permission to open this menu. Please contact an administrator.'
+			},
+			notFound: {
+				title: 'Page Not Found',
+				description: 'The page you are looking for does not exist or the address is incorrect.'
+			}
+		},
 		nodeLibrary: {
 			groups: {
 				start: 'Start',

+ 14 - 0
apps/web/src/i18n/locales/zh-cn.ts

@@ -1681,6 +1681,20 @@ export default {
 				output: '输出'
 			}
 		},
+		system: {
+			actions: {
+				backHome: '返回首页',
+				goBack: '返回上一页'
+			},
+			unauthorized: {
+				title: '没有权限访问此页面',
+				description: '你当前没有权限访问这个菜单,请联系管理员开通权限后再试。'
+			},
+			notFound: {
+				title: '页面未找到',
+				description: '你访问的页面不存在,可能已被删除或地址输入有误。'
+			}
+		},
 		nodeLibrary: {
 			groups: {
 				start: '开始',

+ 18 - 3
apps/web/src/router/index.ts

@@ -31,6 +31,8 @@ const StoragePage = () => import('@/views/storage/index.vue')
 const VectorStorePage = () => import('@/views/vector/index.vue')
 const SkillsPage = () => import('@/views/skills/index.vue')
 const Workspace = () => import('@/views/workspace/index.vue')
+const UnauthorizedPage = () => import('@/views/system/401.vue')
+const NotFoundPage = () => import('@/views/system/404.vue')
 
 const routes = [
 	{
@@ -178,6 +180,16 @@ const routes = [
 		name: 'Chat',
 		component: Chat,
 		meta: { menuCode: 'sys_ai_chat' }
+	},
+	{
+		path: '/401',
+		name: 'Unauthorized',
+		component: UnauthorizedPage
+	},
+	{
+		path: '/404',
+		name: 'NotFound',
+		component: NotFoundPage
 	}
 ]
 
@@ -200,9 +212,7 @@ router.beforeEach(async (to, _from, next) => {
 		await permissionStore.initializePermissions()
 
 		if (!permissionStore.hasMenuAccess(menuCode)) {
-			// 有权限菜单优先作为落点,避免无权限直达页面出现空白。
-			const fallbackPath = permissionStore.getFirstAccessibleRoutePath()
-			next(fallbackPath === to.path ? '/' : fallbackPath)
+			next('/401')
 			return
 		}
 
@@ -213,6 +223,11 @@ router.beforeEach(async (to, _from, next) => {
 	}
 })
 
+router.addRoute({
+	path: '/:pathMatch(.*)*',
+	redirect: '/404'
+})
+
 router.afterEach(() => {
 	NProgress.done()
 })

+ 1 - 1
apps/web/src/views/chat/index.vue

@@ -1938,7 +1938,7 @@ const handleCancel = async () => {
 
 :global(.workflow-form-popper) {
 	max-width: calc(100vw - 24px);
-	padding: 0;
+	border-radius: 20px !important;
 }
 
 :global(.workflow-form-popper .el-popover__inner) {

+ 77 - 0
apps/web/src/views/system/401.vue

@@ -0,0 +1,77 @@
+<template>
+	<div class="system-page">
+		<div class="system-card">
+			<div class="status-code">401</div>
+			<h1>{{ t('pages.system.unauthorized.title') }}</h1>
+			<p>{{ t('pages.system.unauthorized.description') }}</p>
+			<div class="actions">
+				<el-button type="primary" @click="goHome">{{ t('pages.system.actions.backHome') }}</el-button>
+				<el-button @click="goBack">{{ t('pages.system.actions.goBack') }}</el-button>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script setup lang="ts">
+import { useRouter } from 'vue-router'
+import { useI18n } from '@/composables/useI18n'
+
+const router = useRouter()
+const { t } = useI18n()
+
+const goHome = () => {
+	router.replace('/')
+}
+
+const goBack = () => {
+	if (window.history.length > 1) {
+		router.back()
+		return
+	}
+	goHome()
+}
+</script>
+
+<style scoped lang="less">
+.system-page {
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	min-height: 100vh;
+	padding: 24px;
+	background: var(--bg-page);
+	box-sizing: border-box;
+}
+
+.system-card {
+	width: min(520px, 100%);
+	text-align: center;
+}
+
+.status-code {
+	font-size: 88px;
+	font-weight: 700;
+	line-height: 1;
+	color: var(--el-color-warning);
+}
+
+h1 {
+	margin: 18px 0 10px;
+	font-size: 26px;
+	color: var(--text-primary);
+}
+
+p {
+	margin: 0;
+	font-size: 15px;
+	line-height: 1.7;
+	color: var(--text-secondary);
+}
+
+.actions {
+	display: flex;
+	justify-content: center;
+	gap: 12px;
+	margin-top: 28px;
+}
+</style>

+ 77 - 1
apps/web/src/views/system/404.vue

@@ -1 +1,77 @@
-                                        
+<template>
+	<div class="system-page">
+		<div class="system-card">
+			<div class="status-code">404</div>
+			<h1>{{ t('pages.system.notFound.title') }}</h1>
+			<p>{{ t('pages.system.notFound.description') }}</p>
+			<div class="actions">
+				<el-button type="primary" @click="goHome">{{ t('pages.system.actions.backHome') }}</el-button>
+				<el-button @click="goBack">{{ t('pages.system.actions.goBack') }}</el-button>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script setup lang="ts">
+import { useRouter } from 'vue-router'
+import { useI18n } from '@/composables/useI18n'
+
+const router = useRouter()
+const { t } = useI18n()
+
+const goHome = () => {
+	router.replace('/')
+}
+
+const goBack = () => {
+	if (window.history.length > 1) {
+		router.back()
+		return
+	}
+	goHome()
+}
+</script>
+
+<style scoped lang="less">
+.system-page {
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	min-height: 100vh;
+	padding: 24px;
+	background: var(--bg-page);
+	box-sizing: border-box;
+}
+
+.system-card {
+	width: min(520px, 100%);
+	text-align: center;
+}
+
+.status-code {
+	font-size: 88px;
+	font-weight: 700;
+	line-height: 1;
+	color: var(--el-color-primary);
+}
+
+h1 {
+	margin: 18px 0 10px;
+	font-size: 26px;
+	color: var(--text-primary);
+}
+
+p {
+	margin: 0;
+	font-size: 15px;
+	line-height: 1.7;
+	color: var(--text-secondary);
+}
+
+.actions {
+	display: flex;
+	justify-content: center;
+	gap: 12px;
+	margin-top: 28px;
+}
+</style>