<script lang="ts" setup>
|
import type { EchartsUIType } from '@vben/plugins/echarts';
|
|
import type { ArchiveStatApi } from '#/api/archive/stat';
|
|
import { computed, onMounted, ref } from 'vue';
|
|
import { ContentWrap, Page } from '@vben/common-ui';
|
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
|
import { Spin } from 'ant-design-vue';
|
|
import { getArchiveStatOverview } from '#/api/archive/stat';
|
|
import { buildBarOption, buildPieOption, STAT_CARDS } from './data';
|
|
/** 档案统计 */
|
defineOptions({ name: 'ArchiveStat' });
|
|
const loading = ref(false);
|
const overview = ref<ArchiveStatApi.StatOverview>({});
|
|
const categoryChartRef = ref<EchartsUIType>();
|
const secretChartRef = ref<EchartsUIType>();
|
const carrierChartRef = ref<EchartsUIType>();
|
|
const { renderEcharts: renderCategory } = useEcharts(categoryChartRef);
|
const { renderEcharts: renderSecret } = useEcharts(secretChartRef);
|
const { renderEcharts: renderCarrier } = useEcharts(carrierChartRef);
|
|
/** 卡片取值 */
|
const cards = computed(() =>
|
STAT_CARDS.map((card) => ({
|
...card,
|
value: (overview.value[card.key] as number | undefined) ?? 0,
|
})),
|
);
|
|
async function loadData() {
|
loading.value = true;
|
try {
|
const data = await getArchiveStatOverview();
|
overview.value = data;
|
await Promise.all([
|
renderCategory(
|
buildPieOption(
|
'按分类分布',
|
(data.byCategory ?? []).map((item) => ({
|
name: item.name ?? '未命名',
|
value: item.total ?? 0,
|
})),
|
),
|
),
|
renderSecret(
|
buildBarOption(
|
'按密级分布',
|
(data.bySecretLevel ?? []).map((item) => ({
|
name: item.name ?? '未设置',
|
value: item.total ?? 0,
|
})),
|
),
|
),
|
renderCarrier(
|
buildPieOption(
|
'按载体分布',
|
(data.byCarrierType ?? []).map((item) => ({
|
name: item.name ?? '未设置',
|
value: item.total ?? 0,
|
})),
|
),
|
),
|
]);
|
} finally {
|
loading.value = false;
|
}
|
}
|
|
onMounted(loadData);
|
</script>
|
|
<template>
|
<Page auto-content-height>
|
<Spin :spinning="loading" tip="加载中...">
|
<div class="space-y-4">
|
<!-- 统计卡片 -->
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-4">
|
<ContentWrap
|
v-for="card in cards"
|
:key="card.key"
|
class="flex items-center justify-between"
|
>
|
<div>
|
<p class="text-sm text-gray-500">{{ card.label }}</p>
|
<p
|
class="mt-1 text-2xl font-semibold"
|
:style="{ color: card.color }"
|
>
|
{{ card.value }}
|
</p>
|
</div>
|
<span
|
class="inline-block h-10 w-1 rounded"
|
:style="{ backgroundColor: card.color }"
|
/>
|
</ContentWrap>
|
</div>
|
|
<!-- 分布图表 -->
|
<div class="grid grid-cols-1 gap-4 xl:grid-cols-2">
|
<ContentWrap>
|
<EchartsUI class="h-72 w-full" ref="categoryChartRef" />
|
</ContentWrap>
|
<ContentWrap>
|
<EchartsUI class="h-72 w-full" ref="secretChartRef" />
|
</ContentWrap>
|
</div>
|
<ContentWrap>
|
<EchartsUI class="h-72 w-full" ref="carrierChartRef" />
|
</ContentWrap>
|
</div>
|
</Spin>
|
</Page>
|
</template>
|