Files
tms-erp-web/src/views/wel/components/section-kpi.vue
T

184 lines
4.2 KiB
Vue

<template>
<section class="wel-sec">
<div class="wel-sec__head">
<span class="wel-sec__title">核心经营指标</span>
<wel-filters />
</div>
<el-row :gutter="16">
<el-col v-for="card in cards" :key="card.label" :xs="24" :md="8">
<div class="kpi-card">
<div class="kpi-card__top">
<span class="kpi-card__label">{{ card.label }}</span>
<span
class="kpi-card__badge"
:class="card.trend >= 0 ? 'is-up' : 'is-down'"
>
环比 {{ card.trend >= 0 ? '+' : '' }}{{ card.trend }}%
</span>
</div>
<div class="kpi-card__value">
{{ card.value }}<span class="kpi-card__unit">{{ card.unit }}</span>
</div>
<ul class="kpi-card__subs">
<li v-for="s in card.subs" :key="s.name">
<span class="kpi-card__sub-name">{{ s.name }}</span>
<span class="kpi-card__sub-value">{{ s.value }}</span>
<span
v-if="typeof s.change === 'number'"
class="kpi-card__sub-change"
:class="s.change >= 0 ? 'is-up' : 'is-down'"
>
{{ s.change >= 0 ? '↑' : '↓' }} {{ Math.abs(s.change) }}%
</span>
</li>
</ul>
</div>
</el-col>
</el-row>
</section>
</template>
<script>
import WelFilters from './wel-filters.vue';
export default {
name: 'section-kpi',
components: { WelFilters },
data() {
return {
// Mock:营业额/运单量/利润等核心指标,对接统计接口后替换
cards: [
{
label: '营业额',
value: '58,814.0',
unit: '万元',
trend: 12.6,
subs: [
{ name: '毛利率', value: '23.5%', change: 1.2 },
{ name: '运输成本', value: '45,031 万元', change: -0.8 },
{ name: '回款金额', value: '39,640 万元', change: 3.4 },
{ name: '应收账款', value: '19,174 万元', change: -2.1 },
],
},
{
label: '运单量',
value: '1,497.1',
unit: '单',
trend: 8.4,
subs: [
{ name: '已完成', value: '1,205 单', change: 6.2 },
{ name: '在途', value: '135 单', change: 12.0 },
{ name: '待发运', value: '92 单', change: -4.5 },
{ name: '异常单', value: '65 单', change: 1.8 },
],
},
{
label: '运输利润',
value: '2,058.2',
unit: '万元',
trend: 15.7,
subs: [
{ name: '利润率', value: '13.7%', change: 1.5 },
{ name: '单均利润', value: '1.38 万元', change: 5.6 },
{ name: '燃油成本', value: '8,931 万元', change: -3.2 },
{ name: '过路费用', value: '4,208 万元', change: 0.9 },
],
},
],
};
},
};
</script>
<style lang="scss" scoped>
@use '../dashboard.scss';
.kpi-card {
background: #ffffff;
border-radius: 10px;
padding: 18px 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
margin-bottom: 16px;
}
.kpi-card__top {
display: flex;
align-items: center;
justify-content: space-between;
}
.kpi-card__label {
font-size: 13px;
color: #909399;
}
.kpi-card__badge {
font-size: 12px;
padding: 2px 8px;
border-radius: 10px;
&.is-up {
color: #f04747;
background: #fdecec;
}
&.is-down {
color: #2ba471;
background: #e8f7ef;
}
}
.kpi-card__value {
font-size: 30px;
font-weight: 700;
color: #303133;
margin: 8px 0 12px;
}
.kpi-card__unit {
font-size: 13px;
font-weight: 400;
color: #909399;
margin-left: 6px;
}
.kpi-card__subs {
list-style: none;
margin: 0;
padding: 10px 0 0;
border-top: 1px solid #f0f2f5;
li {
display: flex;
align-items: center;
padding: 5px 0;
font-size: 13px;
}
}
.kpi-card__sub-name {
color: #909399;
flex: 1;
}
.kpi-card__sub-value {
color: #303133;
font-weight: 600;
margin-right: 10px;
}
.kpi-card__sub-change {
width: 56px;
text-align: right;
&.is-up {
color: #f04747;
}
&.is-down {
color: #2ba471;
}
}
</style>