Files
xgy-oa/klp-ui/src/views/wms/order/components/OrderSummary.vue
2025-07-22 16:28:43 +08:00

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>