163 lines
4.7 KiB
Vue
163 lines
4.7 KiB
Vue
<template>
|
|
<div class="aksrt-deferred-page">
|
|
<div class="aksrt-deferred-page__icon">
|
|
<FaIcon :icon="resolvedIcon" :size="48" />
|
|
</div>
|
|
<h2 class="aksrt-deferred-page__title">{{ resolvedTitle }}</h2>
|
|
<p class="aksrt-deferred-page__desc">{{ resolvedDesc }}</p>
|
|
<div class="aksrt-deferred-page__meta">
|
|
<n-tag size="small" type="info">{{ resolvedStatus }}</n-tag>
|
|
<n-tag v-if="resolvedPhase" size="small" type="warning">Phase {{ resolvedPhase }}</n-tag>
|
|
</div>
|
|
<div v-if="resolvedDependsOn.length" class="aksrt-deferred-page__depends">
|
|
<span class="aksrt-deferred-page__label">依赖</span>
|
|
<div class="aksrt-deferred-page__depends-list">
|
|
<n-tag v-for="item in resolvedDependsOn" :key="item" size="small" type="default">{{ item }}</n-tag>
|
|
</div>
|
|
</div>
|
|
<div v-if="resolvedReason" class="aksrt-deferred-page__reason">
|
|
<span class="aksrt-deferred-page__label">原因</span>
|
|
<p>{{ resolvedReason }}</p>
|
|
</div>
|
|
<div v-if="resolvedFeatures && resolvedFeatures.length" class="aksrt-deferred-page__features">
|
|
<div
|
|
v-for="(feat, i) in resolvedFeatures"
|
|
:key="i"
|
|
class="aksrt-deferred-page__feature"
|
|
>
|
|
<FaIcon icon="fa fas fa-check-circle" :size="14" />
|
|
<span>{{ feat }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="aksrt-deferred-page__badge">
|
|
<n-tag type="info" size="small">即将推出</n-tag>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
/**
|
|
* DeferredPage — "Coming Soon" page component for deferred sections.
|
|
* Shows a friendly message instead of a blank page.
|
|
*
|
|
* When used as a route component, reads props from route.meta.deferredProps.
|
|
* When used directly, accepts props normally.
|
|
*/
|
|
import { computed } from 'vue'
|
|
import { useRoute } from 'vue-router'
|
|
import FaIcon from './form/FaIcon.vue'
|
|
|
|
const props = defineProps({
|
|
title: { type: String, default: '' },
|
|
description: { type: String, default: '' },
|
|
icon: { type: String, default: '' },
|
|
features: { type: Array, default: () => [] },
|
|
status: { type: String, default: '' },
|
|
phase: { type: String, default: '' },
|
|
dependsOn: { type: Array, default: () => [] },
|
|
reason: { type: String, default: '' },
|
|
})
|
|
|
|
const route = useRoute()
|
|
|
|
/** Merge direct props with route meta deferredProps */
|
|
const resolvedTitle = computed(() => props.title || route.meta?.deferredProps?.title || '功能开发中')
|
|
const resolvedDesc = computed(() => props.description || route.meta?.deferredProps?.description || '此功能正在规划开发中,将在后续版本上线。')
|
|
const resolvedIcon = computed(() => props.icon || route.meta?.deferredProps?.icon || 'fa fas fa-rocket')
|
|
const resolvedStatus = computed(() => props.status || route.meta?.deferredProps?.status || 'deferred')
|
|
const resolvedPhase = computed(() => props.phase || route.meta?.deferredProps?.phase || '')
|
|
const resolvedDependsOn = computed(() => {
|
|
if (props.dependsOn && props.dependsOn.length) return props.dependsOn
|
|
return route.meta?.deferredProps?.dependsOn || []
|
|
})
|
|
const resolvedReason = computed(() => props.reason || route.meta?.deferredProps?.reason || '')
|
|
const resolvedFeatures = computed(() => {
|
|
if (props.features && props.features.length) return props.features
|
|
return route.meta?.deferredProps?.features || []
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.aksrt-deferred-page {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-height: 400px;
|
|
text-align: center;
|
|
padding: 40px 20px;
|
|
}
|
|
|
|
.aksrt-deferred-page__icon {
|
|
color: var(--aksrt-color-border-strong);
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.aksrt-deferred-page__title {
|
|
margin: 0 0 10px;
|
|
font-size: 20px;
|
|
font-weight: 600;
|
|
color: var(--aksrt-color-text);
|
|
}
|
|
|
|
.aksrt-deferred-page__desc {
|
|
margin: 0 0 20px;
|
|
font-size: 14px;
|
|
color: var(--aksrt-color-muted);
|
|
max-width: 400px;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.aksrt-deferred-page__meta {
|
|
display: flex;
|
|
gap: 10px;
|
|
margin-bottom: 18px;
|
|
}
|
|
|
|
.aksrt-deferred-page__depends,
|
|
.aksrt-deferred-page__reason {
|
|
width: min(520px, 100%);
|
|
margin-bottom: 18px;
|
|
text-align: left;
|
|
}
|
|
|
|
.aksrt-deferred-page__label {
|
|
display: inline-block;
|
|
margin-bottom: 8px;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
color: var(--aksrt-color-text-secondary);
|
|
}
|
|
|
|
.aksrt-deferred-page__depends-list {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
}
|
|
|
|
.aksrt-deferred-page__reason p {
|
|
margin: 0;
|
|
color: var(--aksrt-color-muted);
|
|
line-height: 1.7;
|
|
}
|
|
|
|
.aksrt-deferred-page__features {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.aksrt-deferred-page__feature {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-size: 13px;
|
|
color: var(--aksrt-color-muted);
|
|
}
|
|
|
|
.aksrt-deferred-page__feature :deep(i) {
|
|
color: #52c41a;
|
|
}
|
|
</style>
|