30 changed files with 251 additions and 388 deletions
|
Before Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 10 KiB |
@ -1,51 +0,0 @@ |
|||
import { isServer } from '/@/utils/is'; |
|||
let lastTime = 0; |
|||
const prefixes = 'webkit moz ms o'.split(' '); |
|||
|
|||
let requestAnimationFrame: typeof window.requestAnimationFrame; |
|||
let cancelAnimationFrame: typeof window.cancelAnimationFrame; |
|||
(() => { |
|||
const NO_LOOP: any = () => {}; |
|||
const getWindowFrame = (name: string) => { |
|||
return name as any; |
|||
}; |
|||
if (isServer) { |
|||
requestAnimationFrame = cancelAnimationFrame = NO_LOOP; |
|||
} else { |
|||
requestAnimationFrame = window.requestAnimationFrame; |
|||
cancelAnimationFrame = window.cancelAnimationFrame; |
|||
let prefix; |
|||
for (let i = 0; i < prefixes.length; i++) { |
|||
if (requestAnimationFrame && cancelAnimationFrame) { |
|||
break; |
|||
} |
|||
prefix = prefixes[i]; |
|||
requestAnimationFrame = |
|||
requestAnimationFrame || window[getWindowFrame(prefix + 'RequestAnimationFrame')]; |
|||
cancelAnimationFrame = |
|||
cancelAnimationFrame || |
|||
window[getWindowFrame(prefix + 'CancelAnimationFrame')] || |
|||
window[getWindowFrame(prefix + 'CancelRequestAnimationFrame')]; |
|||
} |
|||
|
|||
// If the current browser does not support requestAnimationFrame and cancelAnimationFrame, it will fall back to setTimeout
|
|||
if (!requestAnimationFrame || !cancelAnimationFrame) { |
|||
requestAnimationFrame = function (callback: Fn) { |
|||
const currTime = new Date().getTime(); |
|||
const timeToCall = Math.max(0, 16 - (currTime - lastTime)); |
|||
const id = window.setTimeout(() => { |
|||
/* eslint-disable-next-line */ |
|||
callback(currTime + timeToCall); |
|||
}, timeToCall); |
|||
lastTime = currTime + timeToCall; |
|||
return id; |
|||
}; |
|||
|
|||
cancelAnimationFrame = function (id: number) { |
|||
window.clearTimeout(id); |
|||
}; |
|||
} |
|||
} |
|||
})(); |
|||
|
|||
export { requestAnimationFrame, cancelAnimationFrame }; |
|||
@ -1,101 +0,0 @@ |
|||
function getTypeVersion() { |
|||
const userAgent = navigator.userAgent.toLowerCase(); |
|||
|
|||
const browserTypes = { |
|||
IE: /(?:msie|trident.*rv).([\d.]+)/, |
|||
Edge: /edge.([\d.]+)/, |
|||
Chrome: /chrome.([\d.]+)/, |
|||
Firefox: /firefox.([\d.]+)/, |
|||
Opera: /opera.([\d.]+)/, |
|||
Safari: /(?:safari|version).([\d.]+)/, |
|||
}; |
|||
type BrowserKeys = keyof typeof browserTypes; |
|||
|
|||
/** browser type */ |
|||
let type!: BrowserKeys | null; |
|||
/** browser version */ |
|||
let version!: string | null; |
|||
|
|||
for (type in browserTypes) { |
|||
if ((version = browserTypes[type as BrowserKeys].exec(userAgent) as any)) { |
|||
version = version[1]; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if (version) { |
|||
if (type === 'IE') { |
|||
try { |
|||
document.execCommand('BackgroundImageCache', false, true as any); |
|||
} catch (error) { |
|||
console.log(error); |
|||
} |
|||
} |
|||
} else { |
|||
type = version = null; |
|||
} |
|||
return { type, version }; |
|||
} |
|||
|
|||
const { type, version } = getTypeVersion(); |
|||
|
|||
export function getType() { |
|||
return type; |
|||
} |
|||
|
|||
export function getVersion() { |
|||
return version; |
|||
} |
|||
|
|||
export function isIeFn() { |
|||
return type === 'IE'; |
|||
} |
|||
|
|||
export function isChromeFn() { |
|||
return type === 'Chrome'; |
|||
} |
|||
|
|||
export function isEdgeFn() { |
|||
return type === 'Edge'; |
|||
} |
|||
|
|||
export function isSafariFn() { |
|||
return type === 'Safari'; |
|||
} |
|||
|
|||
export function isFirefoxFn() { |
|||
return type === 'Firefox'; |
|||
} |
|||
|
|||
export function isOperaFn() { |
|||
return type === 'Opera'; |
|||
} |
|||
|
|||
/** |
|||
* set page Title |
|||
* @param {*} title :page Title |
|||
*/ |
|||
function setDocumentTitle(title: string) { |
|||
document.title = title; |
|||
const ua = navigator.userAgent; |
|||
const regex = /\bMicroMessenger\/([\d.]+)/; |
|||
// 兼容
|
|||
if (regex.test(ua) && /ip(hone|od|ad)/i.test(ua)) { |
|||
const i = document.createElement('iframe'); |
|||
i.src = '/favicon.ico'; |
|||
i.style.display = 'none'; |
|||
i.onload = function () { |
|||
setTimeout(function () { |
|||
i.remove(); |
|||
}, 9); |
|||
}; |
|||
document.body.appendChild(i); |
|||
} |
|||
} |
|||
|
|||
export function setTitle(title: string, appTitle?: string) { |
|||
if (title) { |
|||
const _title = title ? ` ${title}-${appTitle} ` : `${appTitle}`; |
|||
setDocumentTitle(_title); |
|||
} |
|||
} |
|||
@ -1,137 +0,0 @@ |
|||
import './exception.less'; |
|||
|
|||
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 netWorkImg from '/@/assets/images/exception/net-work.png'; |
|||
import notDataImg from '/@/assets/images/no-data.png'; |
|||
|
|||
import { useRoute } from 'vue-router'; |
|||
|
|||
import { useGo, useRedo } from '/@/hooks/web/usePage'; |
|||
import { PageEnum } from '/@/enums/pageEnum'; |
|||
import { useI18n } from '/@/hooks/web/useI18n'; |
|||
|
|||
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 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: notDataImg, |
|||
}); |
|||
|
|||
unref(statusMapRef).set(ExceptionEnum.NET_WORK_ERROR, { |
|||
title: t('sys.exception.networkErrorTitle'), |
|||
subTitle: t('sys.exception.networkErrorSubTitle'), |
|||
btnText: 'Refresh', |
|||
handler: () => redo(), |
|||
icon: netWorkImg, |
|||
}); |
|||
|
|||
return () => { |
|||
const { title, subTitle, btnText, icon, handler, status } = unref(getMapValue) || {}; |
|||
return ( |
|||
<Result |
|||
class="exception " |
|||
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> |
|||
); |
|||
}; |
|||
}, |
|||
}); |
|||
@ -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> |
|||
@ -1,5 +0,0 @@ |
|||
.exception { |
|||
display: flex; |
|||
align-items: center; |
|||
flex-direction: column; |
|||
} |
|||
@ -1 +1 @@ |
|||
export { default as Exception } from './Exception'; |
|||
export { default as Exception } from './Exception.vue'; |
|||
|
|||
Loading…
Reference in new issue