90 lines
1.9 KiB
Vue
90 lines
1.9 KiB
Vue
<template>
|
|
<div class="page-state" :class="[`page-state-${status}`]">
|
|
<a-spin v-if="status === 'loading'" :tip="loadingText" class="page-state-spin">
|
|
<slot />
|
|
</a-spin>
|
|
|
|
<a-result v-else-if="status === 'error'" status="500" :title="errorTitle" :subtitle="errorText">
|
|
<template #extra>
|
|
<a-button type="primary" @click="$emit('retry')">重试</a-button>
|
|
</template>
|
|
</a-result>
|
|
|
|
<a-result v-else-if="status === 'unauthorized'" status="403" :title="unauthorizedTitle" :subtitle="unauthorizedText" />
|
|
|
|
<template v-else>
|
|
<a-alert v-if="status === 'partial'" type="warning" show-icon class="page-state-alert">
|
|
{{ partialText }}
|
|
</a-alert>
|
|
<slot />
|
|
<a-empty v-if="status === 'empty'" :description="emptyText" class="page-state-empty" />
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
defineProps({
|
|
status: {
|
|
type: String,
|
|
default: 'success',
|
|
validator: (value: string) => ['loading', 'empty', 'error', 'success', 'partial', 'unauthorized'].includes(value),
|
|
},
|
|
loadingText: {
|
|
type: String,
|
|
default: '加载中',
|
|
},
|
|
emptyText: {
|
|
type: String,
|
|
default: '暂无数据',
|
|
},
|
|
errorTitle: {
|
|
type: String,
|
|
default: '加载失败',
|
|
},
|
|
errorText: {
|
|
type: String,
|
|
default: '数据暂时不可用,请稍后重试。',
|
|
},
|
|
partialText: {
|
|
type: String,
|
|
default: '部分数据加载失败,当前页面展示可用数据。',
|
|
},
|
|
unauthorizedTitle: {
|
|
type: String,
|
|
default: '无权限访问',
|
|
},
|
|
unauthorizedText: {
|
|
type: String,
|
|
default: '当前账号没有访问或操作该页面的权限。',
|
|
},
|
|
})
|
|
|
|
defineEmits<{
|
|
(e: 'retry'): void
|
|
}>()
|
|
</script>
|
|
|
|
<script lang="ts">
|
|
export default {
|
|
name: 'PageState',
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
.page-state {
|
|
min-width: 0;
|
|
}
|
|
|
|
.page-state-spin {
|
|
width: 100%;
|
|
}
|
|
|
|
.page-state-alert {
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.page-state-empty {
|
|
padding: 32px 0;
|
|
}
|
|
</style>
|