213 lines
5.6 KiB
Vue
213 lines
5.6 KiB
Vue
<template>
|
|
<div class="order-summary">
|
|
<div class="summary-container">
|
|
<!-- 总订单数 -->
|
|
<div class="summary-box total-orders">
|
|
<div class="content-left">
|
|
<div class="summary-title">总订单数</div>
|
|
<div class="summary-value">
|
|
<strong>{{ dataInfo.totalOrderCount.toLocaleString() }}</strong>
|
|
<span class="growth">
|
|
<svg class="arrow-up" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="#38c172" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
|
|
<polyline points="6 15 12 9 18 15"></polyline>
|
|
</svg>
|
|
{{ dataInfo.totalOrderCountGrowthRate }}%
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="icon-bg blue">
|
|
<svg viewBox="0 0 24 24" width="28" height="28" fill="#2f86f6">
|
|
<path d="M7 18c-1.1 0-2-.9-2-2s.9-2 2-2h10v-4H7V7H5v3c0 1.1.9 2 2 2v6z"></path>
|
|
<circle cx="18" cy="18" r="2"></circle>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 本月完成订单 -->
|
|
<div class="summary-box completed-orders">
|
|
<div class="content-left">
|
|
<div class="summary-title">本月完成订单</div>
|
|
<div class="summary-value">
|
|
<strong>{{ dataInfo.monthFinishedOrderCount.toLocaleString() }}</strong>
|
|
<span class="growth">
|
|
<svg class="arrow-up" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="#38c172" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
|
|
<polyline points="6 15 12 9 18 15"></polyline>
|
|
</svg>
|
|
{{ dataInfo.monthFinishedOrderCountGrowthRate }}%
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="icon-bg green">
|
|
<svg viewBox="0 0 24 24" width="28" height="28" fill="#38c172">
|
|
<polyline points="20 6 9 17 4 12" stroke="#38c172" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 订单完成度 -->
|
|
<div class="summary-box completion-rate">
|
|
<div class="content-left">
|
|
<div class="summary-title">订单完成度</div>
|
|
<div class="summary-value">
|
|
<strong>{{ dataInfo.finishedRate.toFixed(1) }}%</strong>
|
|
<span class="growth">
|
|
<svg class="arrow-up" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="#38c172" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
|
|
<polyline points="6 15 12 9 18 15"></polyline>
|
|
</svg>
|
|
{{ dataInfo.finishedRateGrowthRate }}%
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="icon-bg yellow">
|
|
<svg viewBox="0 0 24 24" width="28" height="28" fill="#f6bb42">
|
|
<path d="M4 12h16M4 12a8 8 0 0116 0M12 4v8l4 4" stroke="#f6bb42" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
export default {
|
|
name: 'OrderSummary',
|
|
props: {
|
|
dataInfo: {
|
|
type: Object,
|
|
required: true,
|
|
default: () => ({
|
|
totalOrderCount: 0,
|
|
monthFinishedOrderCount: 0,
|
|
finishedRate: 0,
|
|
totalOrderCountGrowthRate: 0,
|
|
monthFinishedOrderCountGrowthRate: 0,
|
|
finishedRateGrowthRate: 0,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.order-summary {
|
|
width: 100%;
|
|
padding: 10px 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.summary-container {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: 15px; /* 卡片之间间距 */
|
|
width: 100%;
|
|
}
|
|
|
|
.summary-box {
|
|
flex: 1 1 0;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 24px 30px;
|
|
border-radius: 16px;
|
|
box-shadow: 0 6px 20px rgba(31, 47, 70, 0.08);
|
|
cursor: default;
|
|
background: #fff;
|
|
user-select: none;
|
|
transition: box-shadow 0.3s ease;
|
|
min-width: 0; /* 防止子元素过大撑破flex */
|
|
}
|
|
|
|
.summary-box:hover {
|
|
box-shadow: 0 10px 32px rgba(31, 47, 70, 0.14);
|
|
}
|
|
|
|
.content-left {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
min-width: 0;
|
|
}
|
|
|
|
.summary-title {
|
|
font-size: 14px;
|
|
color: #5a5a5a;
|
|
margin-bottom: 6px;
|
|
user-select: text;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.summary-value {
|
|
display: flex;
|
|
align-items: center;
|
|
font-weight: 700;
|
|
font-size: 32px;
|
|
color: #222;
|
|
user-select: text;
|
|
min-width: 0;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.summary-value strong {
|
|
margin-right: 10px;
|
|
font-weight: 900;
|
|
}
|
|
|
|
.growth {
|
|
display: flex;
|
|
align-items: center;
|
|
font-size: 14px;
|
|
color: #38c172;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.arrow-up {
|
|
margin-right: 4px;
|
|
stroke: #38c172;
|
|
fill: none;
|
|
}
|
|
|
|
.icon-bg {
|
|
flex-shrink: 0;
|
|
width: 56px;
|
|
height: 56px;
|
|
border-radius: 50%;
|
|
background-color: rgba(0, 0, 0, 0.05);
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
user-select: none;
|
|
box-shadow: 0 4px 12px rgba(47, 134, 246, 0.25);
|
|
}
|
|
|
|
.total-orders {
|
|
background: linear-gradient(135deg, #d5e7ff 0%, #ffffff 100%);
|
|
color: #0d3b73;
|
|
}
|
|
|
|
.total-orders .icon-bg {
|
|
background-color: rgba(47, 134, 246, 0.15);
|
|
box-shadow: 0 4px 12px rgba(47, 134, 246, 0.25);
|
|
}
|
|
|
|
.completed-orders {
|
|
background: linear-gradient(135deg, #e7f5e8 0%, #ffffff 100%);
|
|
color: #1f6d28;
|
|
}
|
|
|
|
.completed-orders .icon-bg {
|
|
background-color: rgba(56, 193, 114, 0.15);
|
|
box-shadow: 0 4px 12px rgba(56, 193, 114, 0.25);
|
|
}
|
|
|
|
.completion-rate {
|
|
background: linear-gradient(135deg, #fff6e1 0%, #ffffff 100%);
|
|
color: #7a5a00;
|
|
}
|
|
|
|
.completion-rate .icon-bg {
|
|
background-color: rgba(246, 187, 66, 0.15);
|
|
box-shadow: 0 4px 12px rgba(246, 187, 66, 0.25);
|
|
}
|
|
</style>
|