|
@@ -0,0 +1,155 @@
|
|
|
+<script lang="tsx">
|
|
|
+ import type { PropType } from 'vue';
|
|
|
+
|
|
|
+ import { Result, Button } from 'ant-design-vue';
|
|
|
+ import { defineComponent, ref, computed, unref } from 'vue';
|
|
|
+
|
|
|
+ import { ExceptionEnum } from '/@/enums/exceptionEnum';
|
|
|
+
|
|
|
+ import notDataSvg from '/@/assets/svg/no-data.svg';
|
|
|
+ import netWorkSvg from '/@/assets/svg/net-error.svg';
|
|
|
+
|
|
|
+ import { useRoute } from 'vue-router';
|
|
|
+ import { useDesign } from '/@/hooks/web/useDesign';
|
|
|
+ import { useI18n } from '/@/hooks/web/useI18n';
|
|
|
+ import { useGo, useRedo } from '/@/hooks/web/usePage';
|
|
|
+
|
|
|
+ import { PageEnum } from '/@/enums/pageEnum';
|
|
|
+
|
|
|
+ interface MapValue {
|
|
|
+ title: string;
|
|
|
+ subTitle: string;
|
|
|
+ btnText?: string;
|
|
|
+ icon?: string;
|
|
|
+ handler?: Fn;
|
|
|
+ status?: string;
|
|
|
+ }
|
|
|
+
|
|
|
+ export default defineComponent({
|
|
|
+ name: 'ErrorPage',
|
|
|
+ props: {
|
|
|
+ // 状态码
|
|
|
+ status: {
|
|
|
+ type: Number as PropType<number>,
|
|
|
+ default: ExceptionEnum.PAGE_NOT_FOUND,
|
|
|
+ },
|
|
|
+
|
|
|
+ title: {
|
|
|
+ type: String as PropType<string>,
|
|
|
+ default: '',
|
|
|
+ },
|
|
|
+
|
|
|
+ subTitle: {
|
|
|
+ type: String as PropType<string>,
|
|
|
+ default: '',
|
|
|
+ },
|
|
|
+
|
|
|
+ full: {
|
|
|
+ type: Boolean as PropType<boolean>,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ setup(props) {
|
|
|
+ const statusMapRef = ref(new Map<string | number, MapValue>());
|
|
|
+
|
|
|
+ const { query } = useRoute();
|
|
|
+ const go = useGo();
|
|
|
+ const redo = useRedo();
|
|
|
+ const { t } = useI18n();
|
|
|
+ const { prefixCls } = useDesign('app-exception-page');
|
|
|
+
|
|
|
+ const getStatus = computed(() => {
|
|
|
+ const { status: routeStatus } = query;
|
|
|
+ const { status } = props;
|
|
|
+ return Number(routeStatus) || status;
|
|
|
+ });
|
|
|
+
|
|
|
+ const getMapValue = computed(
|
|
|
+ (): MapValue => {
|
|
|
+ return unref(statusMapRef).get(unref(getStatus)) as MapValue;
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ const backLoginI18n = t('sys.exception.backLogin');
|
|
|
+ const backHomeI18n = t('sys.exception.backHome');
|
|
|
+
|
|
|
+ unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_ACCESS, {
|
|
|
+ title: '403',
|
|
|
+ status: `${ExceptionEnum.PAGE_NOT_ACCESS}`,
|
|
|
+ subTitle: t('sys.exception.subTitle403'),
|
|
|
+ btnText: props.full ? backLoginI18n : backHomeI18n,
|
|
|
+ handler: () => (props.full ? go(PageEnum.BASE_LOGIN) : go()),
|
|
|
+ });
|
|
|
+
|
|
|
+ unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_FOUND, {
|
|
|
+ title: '404',
|
|
|
+ status: `${ExceptionEnum.PAGE_NOT_FOUND}`,
|
|
|
+ subTitle: t('sys.exception.subTitle404'),
|
|
|
+ btnText: props.full ? backLoginI18n : backHomeI18n,
|
|
|
+ handler: () => (props.full ? go(PageEnum.BASE_LOGIN) : go()),
|
|
|
+ });
|
|
|
+
|
|
|
+ unref(statusMapRef).set(ExceptionEnum.ERROR, {
|
|
|
+ title: '500',
|
|
|
+ status: `${ExceptionEnum.ERROR}`,
|
|
|
+ subTitle: t('sys.exception.subTitle500'),
|
|
|
+ btnText: backHomeI18n,
|
|
|
+ handler: () => go(),
|
|
|
+ });
|
|
|
+
|
|
|
+ unref(statusMapRef).set(ExceptionEnum.PAGE_NOT_DATA, {
|
|
|
+ title: t('sys.exception.noDataTitle'),
|
|
|
+ subTitle: '',
|
|
|
+ btnText: t('common.redo'),
|
|
|
+ handler: () => redo(),
|
|
|
+ icon: notDataSvg,
|
|
|
+ });
|
|
|
+
|
|
|
+ unref(statusMapRef).set(ExceptionEnum.NET_WORK_ERROR, {
|
|
|
+ title: t('sys.exception.networkErrorTitle'),
|
|
|
+ subTitle: t('sys.exception.networkErrorSubTitle'),
|
|
|
+ btnText: t('common.redo'),
|
|
|
+ handler: () => redo(),
|
|
|
+ icon: netWorkSvg,
|
|
|
+ });
|
|
|
+
|
|
|
+ return () => {
|
|
|
+ const { title, subTitle, btnText, icon, handler, status } = unref(getMapValue) || {};
|
|
|
+ return (
|
|
|
+ <Result
|
|
|
+ class={prefixCls}
|
|
|
+ status={status as any}
|
|
|
+ title={props.title || title}
|
|
|
+ sub-title={props.subTitle || subTitle}
|
|
|
+ >
|
|
|
+ {{
|
|
|
+ extra: () =>
|
|
|
+ btnText && (
|
|
|
+ <Button type="primary" onClick={handler}>
|
|
|
+ {() => btnText}
|
|
|
+ </Button>
|
|
|
+ ),
|
|
|
+ icon: () => (icon ? <img src={icon} /> : null),
|
|
|
+ }}
|
|
|
+ </Result>
|
|
|
+ );
|
|
|
+ };
|
|
|
+ },
|
|
|
+ });
|
|
|
+</script>
|
|
|
+<style lang="less">
|
|
|
+ @prefix-cls: ~'@{namespace}-app-exception-page';
|
|
|
+
|
|
|
+ .@{prefix-cls} {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .ant-result-icon {
|
|
|
+ img {
|
|
|
+ max-width: 400px;
|
|
|
+ max-height: 300px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|