Files
my-spring/web-vue/packages/biz/views/biz/myBizScreen/components/ChartTop.vue
2026-04-19 21:21:17 +08:00

223 lines
4.9 KiB
Vue

<template>
<div class="chart-top">
<div v-for="item in cardList" :key="item.key" class="chart-top__card">
<div class="chart-top__left">
<div class="chart-top__icon" :style="{ background: item.iconBg, color: item.iconColor }">
<Icon :icon="item.icon" size="18" />
</div>
<div class="chart-top__label">{{ item.label }}</div>
</div>
<div class="chart-top__right">
<span class="chart-top__value">{{ item.value }}</span>
<span class="chart-top__unit">{{ item.unit }}</span>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import { Icon } from '@jeesite/core/components/Icon';
interface TopCardItem {
key: string;
label: string;
value: string | number;
unit: string;
icon: string;
iconBg: string;
iconColor: string;
}
const cardList = computed<TopCardItem[]>(() => [
{
key: 'customer',
label: '客户总数',
value: 1280,
unit: '户',
icon: 'ant-design:team-outlined',
iconBg: 'rgba(59, 130, 246, 0.14)',
iconColor: '#2563eb',
},
{
key: 'contract',
label: '合同金额',
value: 986,
unit: '万',
icon: 'ant-design:file-text-outlined',
iconBg: 'rgba(16, 185, 129, 0.14)',
iconColor: '#059669',
},
{
key: 'project',
label: '项目数量',
value: 246,
unit: '个',
icon: 'ant-design:appstore-outlined',
iconBg: 'rgba(249, 115, 22, 0.14)',
iconColor: '#ea580c',
},
{
key: 'payment',
label: '本月回款',
value: 368,
unit: '万',
icon: 'ant-design:wallet-outlined',
iconBg: 'rgba(168, 85, 247, 0.14)',
iconColor: '#7e22ce',
},
{
key: 'warning',
label: '风险预警',
value: 19,
unit: '条',
icon: 'ant-design:alert-outlined',
iconBg: 'rgba(236, 72, 153, 0.14)',
iconColor: '#db2777',
},
{
key: 'rate',
label: '完成率',
value: 92.6,
unit: '%',
icon: 'ant-design:line-chart-outlined',
iconBg: 'rgba(6, 182, 212, 0.14)',
iconColor: '#0891b2',
},
]);
</script>
<style lang="less" scoped>
@dark-bg: #141414;
.chart-top {
width: 100%;
height: 100%;
display: grid;
grid-template-columns: repeat(6, minmax(0, 1fr));
gap: 12px;
}
.chart-top__card {
min-width: 0;
height: 100%;
padding: 12px 14px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
border-radius: 10px;
border: 1px solid rgb(226 232 240);
background: rgb(255, 255, 255);
box-shadow: 0 8px 24px rgb(148 163 184 / 14%);
cursor: pointer;
transition:
transform 0.2s ease,
box-shadow 0.2s ease,
border-color 0.2s ease,
background-color 0.2s ease;
}
.chart-top__card:hover {
transform: translateY(-2px);
border-color: rgb(147 197 253);
box-shadow: 0 12px 28px rgb(96 165 250 / 20%);
}
.chart-top__left {
min-width: 0;
display: flex;
align-items: center;
gap: 10px;
}
.chart-top__icon {
flex-shrink: 0;
width: 36px;
height: 36px;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 10px;
}
.chart-top__label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: rgb(71 85 105);
font-size: 14px;
line-height: 20px;
}
.chart-top__right {
flex-shrink: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
gap: 2px;
color: rgb(15 23 42);
text-align: center;
}
.chart-top__value {
font-size: 24px;
font-weight: 700;
line-height: 1;
}
.chart-top__unit {
color: rgb(100 116 139);
font-size: 13px;
line-height: 18px;
}
html[data-theme='dark'] .chart-top__card {
border-color: rgb(51 65 85);
background: @dark-bg !important;
box-shadow: none !important;
}
html[data-theme='dark'] .chart-top__card:hover {
transform: translateY(-2px);
border-color: rgb(96 165 250);
background: @dark-bg !important;
box-shadow: 0 14px 32px rgb(37 99 235 / 22%) !important;
}
html[data-theme='dark'] .chart-top__label {
color: rgb(148 163 184);
}
html[data-theme='dark'] .chart-top__right {
color: rgb(241 245 249);
}
html[data-theme='dark'] .chart-top__unit {
color: rgb(148 163 184);
}
@media (max-width: 1400px) {
.chart-top {
grid-template-columns: repeat(3, minmax(0, 1fr));
grid-template-rows: repeat(2, minmax(0, 1fr));
}
}
@media (max-width: 768px) {
.chart-top {
grid-template-columns: repeat(2, minmax(0, 1fr));
grid-template-rows: repeat(3, minmax(0, 1fr));
}
.chart-top__card {
padding: 10px 12px;
}
.chart-top__value {
font-size: 20px;
}
}
</style>