223 lines
4.9 KiB
Vue
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>
|