mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 10:12:51 +00:00
feat: 404 page
This commit is contained in:
parent
d94972bc9c
commit
3324d4ab35
Binary file not shown.
|
Before Width: | Height: | Size: 359 KiB After Width: | Height: | Size: 20 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.0 KiB |
|
|
@ -92,7 +92,8 @@ export default {
|
|||
selected: 'Selected',
|
||||
notFound: {
|
||||
title: '404',
|
||||
message: 'Unable to Access APP',
|
||||
NoService: 'Currently unable to access services',
|
||||
NoPermission: 'No permission to access',
|
||||
operate: 'Back to Home',
|
||||
},
|
||||
custom: 'Custom',
|
||||
|
|
|
|||
|
|
@ -96,7 +96,8 @@ export default {
|
|||
selected: '已选',
|
||||
notFound: {
|
||||
title: '404',
|
||||
message: '无法访问应用',
|
||||
NoService: '暂时无法访问服务',
|
||||
NoPermission:'没有权限访问',
|
||||
operate: '返回首页',
|
||||
},
|
||||
custom: '自定义',
|
||||
|
|
|
|||
|
|
@ -92,7 +92,8 @@ export default {
|
|||
selected: '已選',
|
||||
notFound: {
|
||||
title: '404',
|
||||
message: '無法訪問應用',
|
||||
NoService: '暫時無法訪問服務',
|
||||
NoPermission: '沒有權限訪問',
|
||||
operate: '返回首頁',
|
||||
},
|
||||
custom: '自定義',
|
||||
|
|
|
|||
|
|
@ -77,7 +77,9 @@ instance.interceptors.response.use(
|
|||
|
||||
if (err.response?.status === 403 && !err.response.config.url.includes('chat/open')) {
|
||||
MsgError(
|
||||
err.response.data && err.response.data.message ? err.response.data.message : '没有权限访问',
|
||||
err.response.data && err.response.data.message
|
||||
? err.response.data.message
|
||||
: 'No permission to access',
|
||||
)
|
||||
}
|
||||
return Promise.reject(err)
|
||||
|
|
@ -249,15 +251,15 @@ export const exportExcel: (
|
|||
|
||||
function decodeFilenameBrowser(contentDisposition: string) {
|
||||
// 提取并解码 Base64 部分
|
||||
const base64Part = contentDisposition.match(/=\?utf-8\?b\?(.*?)\?=/i)?.[1];
|
||||
if (!base64Part) return null;
|
||||
const base64Part = contentDisposition.match(/=\?utf-8\?b\?(.*?)\?=/i)?.[1]
|
||||
if (!base64Part) return null
|
||||
|
||||
// 使用 atob 解码 Base64
|
||||
const decoded = decodeURIComponent(escape(atob(base64Part)));
|
||||
const decoded = decodeURIComponent(escape(atob(base64Part)))
|
||||
|
||||
// 提取文件名
|
||||
const filenameMatch = decoded.match(/filename="(.*?)"/i);
|
||||
return filenameMatch ? filenameMatch[1] : null;
|
||||
const filenameMatch = decoded.match(/filename="(.*?)"/i)
|
||||
return filenameMatch ? filenameMatch[1] : null
|
||||
}
|
||||
|
||||
export const exportFile: (
|
||||
|
|
@ -271,37 +273,40 @@ export const exportFile: (
|
|||
params: any,
|
||||
loading?: NProgress | Ref<boolean>,
|
||||
) => {
|
||||
return promise(request({
|
||||
url: url,
|
||||
method: 'get',
|
||||
params,
|
||||
responseType: 'blob',
|
||||
transformResponse: [function (data, headers) {
|
||||
// 在这里可以访问 headers
|
||||
// const contentType = headers['content-type'];
|
||||
const contentDisposition = headers['content-disposition'];
|
||||
// console.log('Content-Type:', contentType);
|
||||
// console.log('Content-Disposition:', decodeFilenameBrowser(contentDisposition));
|
||||
// 如果没有提供文件名,则使用默认名称
|
||||
fileName = decodeFilenameBrowser(contentDisposition) || fileName;
|
||||
return data; // 必须返回数据
|
||||
}]
|
||||
}), loading).then(
|
||||
(res: any) => {
|
||||
if (res) {
|
||||
const blob = new Blob([res], {
|
||||
type: 'application/octet-stream',
|
||||
})
|
||||
const link = document.createElement('a')
|
||||
link.href = window.URL.createObjectURL(blob)
|
||||
link.download = fileName
|
||||
link.click()
|
||||
//释放内存
|
||||
window.URL.revokeObjectURL(link.href)
|
||||
}
|
||||
return true
|
||||
},
|
||||
)
|
||||
return promise(
|
||||
request({
|
||||
url: url,
|
||||
method: 'get',
|
||||
params,
|
||||
responseType: 'blob',
|
||||
transformResponse: [
|
||||
function (data, headers) {
|
||||
// 在这里可以访问 headers
|
||||
// const contentType = headers['content-type'];
|
||||
const contentDisposition = headers['content-disposition']
|
||||
// console.log('Content-Type:', contentType);
|
||||
// console.log('Content-Disposition:', decodeFilenameBrowser(contentDisposition));
|
||||
// 如果没有提供文件名,则使用默认名称
|
||||
fileName = decodeFilenameBrowser(contentDisposition) || fileName
|
||||
return data // 必须返回数据
|
||||
},
|
||||
],
|
||||
}),
|
||||
loading,
|
||||
).then((res: any) => {
|
||||
if (res) {
|
||||
const blob = new Blob([res], {
|
||||
type: 'application/octet-stream',
|
||||
})
|
||||
const link = document.createElement('a')
|
||||
link.href = window.URL.createObjectURL(blob)
|
||||
link.download = fileName
|
||||
link.click()
|
||||
//释放内存
|
||||
window.URL.revokeObjectURL(link.href)
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
export const exportExcelPost: (
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@ export const routes: Array<RouteRecordRaw> = [
|
|||
{
|
||||
path: '/404',
|
||||
name: '404',
|
||||
component: () => import('@/views/404/index.vue'),
|
||||
component: () => import('@/views/error/404.vue'),
|
||||
},
|
||||
{
|
||||
path: '/no-service',
|
||||
name: 'NoService',
|
||||
component: () => import('@/views/error/NoService.vue'),
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import type { RouteRecordRaw } from 'vue-router'
|
||||
const modules: any = import.meta.glob('./modules/*.ts', { eager: true })
|
||||
import { hasPermission, set_next_route } from '@/utils/permission/index'
|
||||
|
||||
const rolesRoutes: RouteRecordRaw[] = [...Object.keys(modules).map((key) => modules[key].default)]
|
||||
|
||||
|
|
@ -20,7 +19,7 @@ export const routes: Array<RouteRecordRaw> = [
|
|||
{
|
||||
path: '/no-permission',
|
||||
name: 'noPermissionD',
|
||||
component: () => import('@/views/no-permission/index.vue'),
|
||||
component: () => import('@/views/error/NoPermission.vue'),
|
||||
},
|
||||
],
|
||||
component: () => import('@/layout/layout-template/SimpleLayout.vue'),
|
||||
|
|
@ -69,9 +68,14 @@ export const routes: Array<RouteRecordRaw> = [
|
|||
name: 'permission',
|
||||
component: () => import('@/views/Permission.vue'),
|
||||
},
|
||||
// {
|
||||
// path: '/:pathMatch(.*)',
|
||||
// name: '404',
|
||||
// component: () => import('@/views/404/index.vue')
|
||||
// }
|
||||
{
|
||||
path: '/no-service',
|
||||
name: 'NoService',
|
||||
component: () => import('@/views/error/NoService.vue'),
|
||||
},
|
||||
{
|
||||
path: '/:pathMatch(.*)',
|
||||
name: '404',
|
||||
component: () => import('@/views/error/404.vue'),
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
<template>
|
||||
<el-row class="not-found-container">
|
||||
<el-col class="img" :xs="0" :sm="0" :md="12" :lg="12" :xl="12"> </el-col>
|
||||
<el-col class="message-container" :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
|
||||
<div class="title">{{ $t('common.notFound.title') }}</div>
|
||||
<div class="message">{{ $t('common.notFound.message') }}</div>
|
||||
<!-- TODO 暂时不处理 -->
|
||||
<!-- <div class="operate"><el-button type="primary" @click="router.push('/')">{{ $t('views.notFound.operate') }}</el-button></div> -->
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from 'vue-router'
|
||||
const router = useRouter()
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.not-found-container {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.img {
|
||||
background-image: url('@/assets/404.png');
|
||||
background-size: 100% 100%;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.message-container {
|
||||
color: var(--app-text-color);
|
||||
|
||||
.title {
|
||||
font-size: 50px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.message {
|
||||
font-size: 20px;
|
||||
margin: 30px 0 20px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1000px) {
|
||||
.not-found-container .message-container {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<template>
|
||||
<div class="not-found-container flex-center">
|
||||
<div>
|
||||
<img src="@/assets/404.png" width="250" alt="" />
|
||||
<h4 class="text-center">{{ $t('common.notFound.title') }}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from 'vue-router'
|
||||
const router = useRouter()
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.not-found-container {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<template>
|
||||
<div class="flex-center mt-24">
|
||||
<div>
|
||||
<img src="@/assets/500.png" width="250" alt="" />
|
||||
<h4 class="text-center">{{ $t('common.notFound.NoPermission') }}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from 'vue-router'
|
||||
const router = useRouter()
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<template>
|
||||
<div class="not-found-container flex-center">
|
||||
<div>
|
||||
<img src="@/assets/500.png" width="250" alt="" />
|
||||
<h4 class="text-center">{{ $t('common.notFound.NoService') }}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from 'vue-router'
|
||||
const router = useRouter()
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.not-found-container {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
<template>
|
||||
<div>没有权限访问</div>
|
||||
</template>
|
||||
<script setup lang="ts"></script>
|
||||
<style lang="scss" scoped></style>
|
||||
Loading…
Reference in New Issue