Files
aiot-platform-ui/packages/effects/common-ui/src/ui/dashboard/analysis/analysis-overview.vue
lrl b480eb54c1 feat: 新增会员统计组件和优化数据展示
- 在会员统计页面中新增会员地域分布和性别分布组件
- 更新会员统计 API,支持获取会员汇总和地区统计数据
- 优化数据加载逻辑,提升用户体验
- 引入分析概览组件以展示关键统计信息
2025-07-16 16:14:01 +08:00

67 lines
1.6 KiB
Vue

<script setup lang="ts">
import type { AnalysisOverviewItem } from '../typing';
import { computed } from 'vue';
import {
Card,
CardContent,
CardFooter,
CardHeader,
CardTitle,
VbenCountToAnimator,
VbenIcon,
} from '@vben-core/shadcn-ui';
interface Props {
items?: AnalysisOverviewItem[];
modelValue?: AnalysisOverviewItem[];
}
defineOptions({
name: 'AnalysisOverview',
});
const props = withDefaults(defineProps<Props>(), {
items: () => [],
modelValue: () => [],
});
const emit = defineEmits(['update:modelValue']);
const itemsData = computed({
get: () => (props.modelValue?.length ? props.modelValue : props.items),
set: (value) => emit('update:modelValue', value),
});
</script>
<template>
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4">
<template v-for="item in itemsData" :key="item.title">
<Card :title="item.title" class="w-full">
<CardHeader>
<CardTitle class="text-xl">{{ item.title }}</CardTitle>
</CardHeader>
<CardContent class="flex items-center justify-between">
<VbenCountToAnimator
:end-val="item.value"
:start-val="1"
class="text-xl"
prefix=""
/>
<VbenIcon :icon="item.icon" class="size-8 flex-shrink-0" />
</CardContent>
<CardFooter v-if="item.totalTitle" class="justify-between">
<span>{{ item.totalTitle }}</span>
<VbenCountToAnimator
:end-val="item.totalValue"
:start-val="1"
prefix=""
/>
</CardFooter>
</Card>
</template>
</div>
</template>