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 |
BIN
ui/src/assets/500.png
Normal file
BIN
ui/src/assets/500.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.0 KiB |
@ -92,7 +92,8 @@ export default {
|
|||||||
selected: 'Selected',
|
selected: 'Selected',
|
||||||
notFound: {
|
notFound: {
|
||||||
title: '404',
|
title: '404',
|
||||||
message: 'Unable to Access APP',
|
NoService: 'Currently unable to access services',
|
||||||
|
NoPermission: 'No permission to access',
|
||||||
operate: 'Back to Home',
|
operate: 'Back to Home',
|
||||||
},
|
},
|
||||||
custom: 'Custom',
|
custom: 'Custom',
|
||||||
|
|||||||
@ -96,7 +96,8 @@ export default {
|
|||||||
selected: '已选',
|
selected: '已选',
|
||||||
notFound: {
|
notFound: {
|
||||||
title: '404',
|
title: '404',
|
||||||
message: '无法访问应用',
|
NoService: '暂时无法访问服务',
|
||||||
|
NoPermission:'没有权限访问',
|
||||||
operate: '返回首页',
|
operate: '返回首页',
|
||||||
},
|
},
|
||||||
custom: '自定义',
|
custom: '自定义',
|
||||||
|
|||||||
@ -92,7 +92,8 @@ export default {
|
|||||||
selected: '已選',
|
selected: '已選',
|
||||||
notFound: {
|
notFound: {
|
||||||
title: '404',
|
title: '404',
|
||||||
message: '無法訪問應用',
|
NoService: '暫時無法訪問服務',
|
||||||
|
NoPermission: '沒有權限訪問',
|
||||||
operate: '返回首頁',
|
operate: '返回首頁',
|
||||||
},
|
},
|
||||||
custom: '自定義',
|
custom: '自定義',
|
||||||
|
|||||||
@ -77,7 +77,9 @@ instance.interceptors.response.use(
|
|||||||
|
|
||||||
if (err.response?.status === 403 && !err.response.config.url.includes('chat/open')) {
|
if (err.response?.status === 403 && !err.response.config.url.includes('chat/open')) {
|
||||||
MsgError(
|
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)
|
return Promise.reject(err)
|
||||||
@ -249,15 +251,15 @@ export const exportExcel: (
|
|||||||
|
|
||||||
function decodeFilenameBrowser(contentDisposition: string) {
|
function decodeFilenameBrowser(contentDisposition: string) {
|
||||||
// 提取并解码 Base64 部分
|
// 提取并解码 Base64 部分
|
||||||
const base64Part = contentDisposition.match(/=\?utf-8\?b\?(.*?)\?=/i)?.[1];
|
const base64Part = contentDisposition.match(/=\?utf-8\?b\?(.*?)\?=/i)?.[1]
|
||||||
if (!base64Part) return null;
|
if (!base64Part) return null
|
||||||
|
|
||||||
// 使用 atob 解码 Base64
|
// 使用 atob 解码 Base64
|
||||||
const decoded = decodeURIComponent(escape(atob(base64Part)));
|
const decoded = decodeURIComponent(escape(atob(base64Part)))
|
||||||
|
|
||||||
// 提取文件名
|
// 提取文件名
|
||||||
const filenameMatch = decoded.match(/filename="(.*?)"/i);
|
const filenameMatch = decoded.match(/filename="(.*?)"/i)
|
||||||
return filenameMatch ? filenameMatch[1] : null;
|
return filenameMatch ? filenameMatch[1] : null
|
||||||
}
|
}
|
||||||
|
|
||||||
export const exportFile: (
|
export const exportFile: (
|
||||||
@ -271,37 +273,40 @@ export const exportFile: (
|
|||||||
params: any,
|
params: any,
|
||||||
loading?: NProgress | Ref<boolean>,
|
loading?: NProgress | Ref<boolean>,
|
||||||
) => {
|
) => {
|
||||||
return promise(request({
|
return promise(
|
||||||
url: url,
|
request({
|
||||||
method: 'get',
|
url: url,
|
||||||
params,
|
method: 'get',
|
||||||
responseType: 'blob',
|
params,
|
||||||
transformResponse: [function (data, headers) {
|
responseType: 'blob',
|
||||||
// 在这里可以访问 headers
|
transformResponse: [
|
||||||
// const contentType = headers['content-type'];
|
function (data, headers) {
|
||||||
const contentDisposition = headers['content-disposition'];
|
// 在这里可以访问 headers
|
||||||
// console.log('Content-Type:', contentType);
|
// const contentType = headers['content-type'];
|
||||||
// console.log('Content-Disposition:', decodeFilenameBrowser(contentDisposition));
|
const contentDisposition = headers['content-disposition']
|
||||||
// 如果没有提供文件名,则使用默认名称
|
// console.log('Content-Type:', contentType);
|
||||||
fileName = decodeFilenameBrowser(contentDisposition) || fileName;
|
// console.log('Content-Disposition:', decodeFilenameBrowser(contentDisposition));
|
||||||
return data; // 必须返回数据
|
// 如果没有提供文件名,则使用默认名称
|
||||||
}]
|
fileName = decodeFilenameBrowser(contentDisposition) || fileName
|
||||||
}), loading).then(
|
return data // 必须返回数据
|
||||||
(res: any) => {
|
},
|
||||||
if (res) {
|
],
|
||||||
const blob = new Blob([res], {
|
}),
|
||||||
type: 'application/octet-stream',
|
loading,
|
||||||
})
|
).then((res: any) => {
|
||||||
const link = document.createElement('a')
|
if (res) {
|
||||||
link.href = window.URL.createObjectURL(blob)
|
const blob = new Blob([res], {
|
||||||
link.download = fileName
|
type: 'application/octet-stream',
|
||||||
link.click()
|
})
|
||||||
//释放内存
|
const link = document.createElement('a')
|
||||||
window.URL.revokeObjectURL(link.href)
|
link.href = window.URL.createObjectURL(blob)
|
||||||
}
|
link.download = fileName
|
||||||
return true
|
link.click()
|
||||||
},
|
//释放内存
|
||||||
)
|
window.URL.revokeObjectURL(link.href)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const exportExcelPost: (
|
export const exportExcelPost: (
|
||||||
|
|||||||
@ -17,6 +17,11 @@ export const routes: Array<RouteRecordRaw> = [
|
|||||||
{
|
{
|
||||||
path: '/404',
|
path: '/404',
|
||||||
name: '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'
|
import type { RouteRecordRaw } from 'vue-router'
|
||||||
const modules: any = import.meta.glob('./modules/*.ts', { eager: true })
|
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)]
|
const rolesRoutes: RouteRecordRaw[] = [...Object.keys(modules).map((key) => modules[key].default)]
|
||||||
|
|
||||||
@ -20,7 +19,7 @@ export const routes: Array<RouteRecordRaw> = [
|
|||||||
{
|
{
|
||||||
path: '/no-permission',
|
path: '/no-permission',
|
||||||
name: 'noPermissionD',
|
name: 'noPermissionD',
|
||||||
component: () => import('@/views/no-permission/index.vue'),
|
component: () => import('@/views/error/NoPermission.vue'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
component: () => import('@/layout/layout-template/SimpleLayout.vue'),
|
component: () => import('@/layout/layout-template/SimpleLayout.vue'),
|
||||||
@ -69,9 +68,14 @@ export const routes: Array<RouteRecordRaw> = [
|
|||||||
name: 'permission',
|
name: 'permission',
|
||||||
component: () => import('@/views/Permission.vue'),
|
component: () => import('@/views/Permission.vue'),
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// path: '/:pathMatch(.*)',
|
path: '/no-service',
|
||||||
// name: '404',
|
name: 'NoService',
|
||||||
// component: () => import('@/views/404/index.vue')
|
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>
|
|
||||||
18
ui/src/views/error/404.vue
Normal file
18
ui/src/views/error/404.vue
Normal file
@ -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>
|
||||||
13
ui/src/views/error/NoPermission.vue
Normal file
13
ui/src/views/error/NoPermission.vue
Normal file
@ -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>
|
||||||
18
ui/src/views/error/NoService.vue
Normal file
18
ui/src/views/error/NoService.vue
Normal file
@ -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
Block a user