60 lines
1.5 KiB
Vue
60 lines
1.5 KiB
Vue
<script setup lang="ts">
|
|
/**
|
|
* 文件职责:财务概览 KPI 指标卡。
|
|
*/
|
|
import type { FinanceOverviewKpiKey } from '../composables/overview-page/constants';
|
|
|
|
import type { FinanceOverviewDashboardDto } from '#/api/finance/overview';
|
|
|
|
import { computed } from 'vue';
|
|
|
|
import { IconifyIcon } from '@vben/icons';
|
|
|
|
import { OVERVIEW_KPI_CONFIG } from '../composables/overview-page/constants';
|
|
import {
|
|
formatChangeRate,
|
|
formatCurrency,
|
|
resolveKpiTrendClass,
|
|
resolveKpiTrendIcon,
|
|
} from '../composables/overview-page/helpers';
|
|
|
|
interface Props {
|
|
dashboard: FinanceOverviewDashboardDto;
|
|
}
|
|
|
|
const props = defineProps<Props>();
|
|
|
|
const kpiCards = computed(() =>
|
|
OVERVIEW_KPI_CONFIG.map((item) => ({
|
|
...item,
|
|
value: props.dashboard[item.key as FinanceOverviewKpiKey],
|
|
})),
|
|
);
|
|
</script>
|
|
|
|
<template>
|
|
<div class="fo-kpi-row">
|
|
<div
|
|
v-for="card in kpiCards"
|
|
:key="card.key"
|
|
class="fo-kpi-card"
|
|
:class="`is-${card.tone}`"
|
|
>
|
|
<div class="fo-kpi-top">
|
|
<span class="fo-kpi-label">{{ card.label }}</span>
|
|
<span class="fo-kpi-icon">
|
|
<IconifyIcon :icon="card.icon" />
|
|
</span>
|
|
</div>
|
|
|
|
<div class="fo-kpi-value">{{ formatCurrency(card.value.amount) }}</div>
|
|
|
|
<div class="fo-kpi-change" :class="resolveKpiTrendClass(card.value)">
|
|
<IconifyIcon :icon="resolveKpiTrendIcon(card.value)" />
|
|
<span>{{ formatChangeRate(card.value.changeRate) }}</span>
|
|
<span>{{ card.value.compareLabel }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|