@ithinkdt/naive
Version:
iThinkDT Naive UI
139 lines (121 loc) • 4.8 kB
JSX
import { defineComponent, watchEffect } from 'vue'
import { NFlex, NResult, NButton } from 'ithinkdt-ui'
import { useI18n, usePageTab, useTheme, useAuth, useLogin } from '@ithinkdt/core'
import { cB, cE, CSS_MOUNT_ANCHOR_META_NAME, CSS_STYLE_PREFIX as p, fullWH, flexCenter } from '@ithinkdt/core/cssr'
export const DtError = defineComponent({
name: 'DtError',
props: {
type: { type: String, default: '404' },
path: { type: String, default: '' },
},
setup(props) {
const cls = `${p}-error`
createStyle(cls)
const theme = useTheme()
const { t } = useI18n()
const { title, close } = usePageTab()
const auth = useAuth()
const refreshAuth = () => {
auth.token = undefined
setTimeout(refresh, 100)
}
const { logout: relogin } = useLogin()
watchEffect(() => {
if (props.type === '404') {
title.value ??= props.type
}
const fullscreen = props.type === 'forbidden' || props.type === 'timeout'
theme.hasTopbar = !fullscreen
theme.hasSidebar = !fullscreen
theme.hasBreadcrumb = !fullscreen
theme.hasFooter = !fullscreen
})
function back() {
close()
}
const refresh = () => {
location.reload()
}
const mapStatus = {
403: '403',
404: '404',
500: '500',
forbidden: '403',
timeout: '500',
}
return () => (
<div class={cls}>
<div class={`${cls}__wrapper`}>
<NResult status={mapStatus[props.type]} title={t(`sys.error.${props.type}`)}>
{{
default: () => (
<span class={`${cls}__content`} v-html={t(`sys.error.${props.type}-desc`)}></span>
),
footer: () => (
<NFlex class={`${cls}__footer`} vertical align="center" size={40}>
{props.type === 'forbidden' ? (
<>
<NButton
class={`${cls}__action`}
size="large"
type="primary"
onClick={refreshAuth}
>
{t('sys.error.refreshAuth')}
</NButton>
<NButton
class={`${cls}__action`}
size="large"
type="error"
onClick={relogin}
>
{t('sys.error.exitAccount')}
</NButton>
</>
) : props.type === 'timeout' ? (
<NButton class={`${cls}__action`} type="primary" size="large" onClick={refresh}>
{t('sys.error.refreshPage')}
</NButton>
) : (
<NButton class={`${cls}__action`} type="primary" size="large" onClick={back}>
{t('sys.error.back')}
</NButton>
)}
</NFlex>
),
}}
</NResult>
</div>
</div>
)
},
})
let style
function createStyle(cls) {
if (!style) {
style = cB(
'error',
{
...fullWH,
...flexCenter,
},
[
cE('wrapper', {
display: 'inline-block',
textAlign: 'center',
paddingBottom: '10vh',
}),
cE('footer', {
margin: '100px 0 0',
}),
cE('action', {
width: '240px',
}),
],
)
style.mount({
id: cls,
anchorMetaName: CSS_MOUNT_ANCHOR_META_NAME,
})
}
}