Files
TakeoutSaaS.TenantUI/apps/web-antd/src/views/finance/overview/components/OverviewKpiRow.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>