<template>
|
<div class="kpi-card" :class="{ 'is-alert': alert, 'is-demo': demo }">
|
<div class="kpi-card__label">
|
<span>{{ label }}</span>
|
<el-tag v-if="demo" class="kpi-card__badge" type="info" effect="plain" size="small">演示</el-tag>
|
</div>
|
<div class="kpi-card__value">
|
<cl-number :value="numeric" :fixed="fixed" type="amount" :suffix="suffix" />
|
</div>
|
<div v-if="hint" class="kpi-card__hint">{{ hint }}</div>
|
</div>
|
</template>
|
|
<script lang="ts" setup>
|
import { computed } from 'vue';
|
|
const props = defineProps<{
|
label: string;
|
value: number | string;
|
suffix?: string;
|
fixed?: number;
|
hint?: string;
|
alert?: boolean;
|
demo?: boolean;
|
}>();
|
|
const numeric = computed(() => Number(props.value) || 0);
|
</script>
|
|
<style lang="scss" scoped>
|
.kpi-card {
|
padding: 14px 16px;
|
border-radius: 12px;
|
border: 1px solid var(--el-border-color-extra-light);
|
background: var(--el-bg-color);
|
color: var(--el-text-color-primary);
|
min-height: 96px;
|
|
&__label {
|
display: flex;
|
align-items: center;
|
gap: 6px;
|
font-size: 13px;
|
color: var(--el-text-color-secondary);
|
}
|
|
&__badge {
|
transform: scale(0.92);
|
}
|
|
&__value {
|
margin-top: 8px;
|
font-size: 26px;
|
font-weight: 700;
|
line-height: 1.2;
|
color: var(--el-text-color-primary);
|
|
:deep(.cl-number__suffix) {
|
margin-left: 4px;
|
font-size: 13px;
|
font-weight: 500;
|
color: var(--el-text-color-secondary);
|
}
|
}
|
|
&__hint {
|
margin-top: 8px;
|
font-size: 12px;
|
color: var(--el-text-color-secondary);
|
}
|
|
&.is-alert {
|
border-color: var(--el-color-danger-light-5);
|
background: var(--el-color-danger-light-9);
|
|
.kpi-card__value {
|
color: var(--el-color-danger);
|
}
|
}
|
|
&.is-demo:not(.is-alert) {
|
border-style: dashed;
|
}
|
}
|
</style>
|