<template>
|
<view class="info-section">
|
<!-- 头部:单号 + 状态 -->
|
<view class="header-row" v-if="hasHeader">
|
<view class="dispatch-info">
|
<u-icon name="order" color="#409eff" size="16" />
|
<text class="dispatch-no">{{ getValue('dispatchNo') }}</text>
|
</view>
|
<view v-if="statusItem" class="status-tag" :class="statusItem.statusClass">
|
{{ statusItem.value }}
|
</view>
|
</view>
|
|
<!-- 紧凑型信息网格 -->
|
<view class="info-grid">
|
<view
|
v-for="item in gridItems"
|
:key="item.key"
|
class="grid-item"
|
:class="item.span"
|
>
|
<view class="item-icon">
|
<u-icon :name="item.icon" :color="item.iconColor" size="16" />
|
</view>
|
<view class="item-content">
|
<text class="item-value">{{ item.value || '-' }}</text>
|
</view>
|
</view>
|
</view>
|
|
<!-- 时间信息(如果有) -->
|
<view v-if="timeItem" class="time-row">
|
<u-icon name="clock" color="#f0ae2d" size="14" />
|
<text class="time-label">最晚发车</text>
|
<text class="time-value">{{ timeItem.value }}</text>
|
</view>
|
</view>
|
</template>
|
|
<script>
|
// 状态颜色映射
|
const STATUS_MAP = {
|
'待甩挂': { class: 'status-pending', color: '#ff6b6b' },
|
'待接挂': { class: 'status-pending', color: '#ff6b6b' },
|
'运输中': { class: 'status-transporting', color: '#409eff' },
|
'已完成': { class: 'status-completed', color: '#67c23a' },
|
'已取消': { class: 'status-cancelled', color: '#909399' },
|
'待发车': { class: 'status-waiting', color: '#e6a23c' },
|
'待到达': { class: 'status-waiting', color: '#e6a23c' }
|
}
|
|
// 字段图标映射
|
const ICON_MAP = {
|
'licensePlate': { icon: 'car', color: '#67c23a' },
|
'transportLine': { icon: 'map', color: '#ff6b6b' },
|
'customerName': { icon: 'account', color: '#e6a23c' },
|
'latestDeparture': { icon: 'clock', color: '#909399' },
|
'shipperAddress': { icon: 'home', color: '#67c23a' },
|
'receiverAddress': { icon: 'home-fill', color: '#ff6b6b' }
|
}
|
|
export default {
|
name: 'InfoSection',
|
props: {
|
list: {
|
type: Array,
|
default: () => []
|
}
|
},
|
computed: {
|
// 头部数据
|
hasHeader() {
|
return this.getItem('dispatchNo') || this.statusItem
|
},
|
statusItem() {
|
const item = this.getItem('statusStr')
|
if (!item) return null
|
const config = STATUS_MAP[item.value]
|
return {
|
...item,
|
statusClass: config?.class || 'status-default'
|
}
|
},
|
timeItem() {
|
return this.getItem('latestDeparture')
|
},
|
// 网格项(排除头部和时间)
|
gridItems() {
|
const excludeKeys = ['dispatchNo', 'statusStr', 'latestDeparture']
|
return this.list
|
.filter(item => !excludeKeys.includes(item.key) && item.value)
|
.map(item => {
|
const config = ICON_MAP[item.key] || { icon: 'info-circle', color: '#909399' }
|
return {
|
...item,
|
icon: config.icon,
|
iconColor: config.color,
|
span: 'full'
|
}
|
})
|
}
|
},
|
methods: {
|
getItem(key) {
|
return this.list.find(item => item.key === key)
|
},
|
getValue(key) {
|
const item = this.getItem(key)
|
return item ? item.value : ''
|
},
|
copyValue(value) {
|
if (!value) return
|
uni.setClipboardData({
|
data: value,
|
success: () => uni.$u.toast('已复制')
|
})
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.info-section {
|
margin: 20rpx;
|
background: #fff;
|
border-radius: 16rpx;
|
padding: 20rpx;
|
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
|
}
|
|
// 头部行
|
.header-row {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding-bottom: 16rpx;
|
margin-bottom: 16rpx;
|
border-bottom: 1rpx solid #f0f0f0;
|
}
|
|
.dispatch-info {
|
display: flex;
|
align-items: center;
|
gap: 12rpx;
|
}
|
|
.dispatch-no {
|
font-size: 30rpx;
|
color: #409eff;
|
font-weight: 600;
|
font-family: 'Courier New', monospace;
|
}
|
|
.copy-icon {
|
padding: 8rpx;
|
border-radius: 8rpx;
|
|
&:active {
|
background-color: #f5f7fa;
|
}
|
}
|
|
// 状态标签
|
.status-tag {
|
padding: 6rpx 16rpx;
|
border-radius: 8rpx;
|
font-size: 24rpx;
|
font-weight: 500;
|
}
|
|
.status-pending {
|
background-color: rgba(255, 107, 107, 0.1);
|
color: #ff6b6b;
|
}
|
|
.status-transporting {
|
background-color: rgba(64, 158, 255, 0.1);
|
color: #409eff;
|
}
|
|
.status-completed {
|
background-color: rgba(103, 194, 58, 0.1);
|
color: #67c23a;
|
}
|
|
.status-cancelled {
|
background-color: rgba(144, 147, 153, 0.1);
|
color: #909399;
|
}
|
|
.status-waiting {
|
background-color: rgba(230, 162, 60, 0.1);
|
color: #e6a23c;
|
}
|
|
.status-default {
|
background-color: rgba(64, 158, 255, 0.1);
|
color: #409eff;
|
}
|
|
// 信息网格
|
.info-grid {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 16rpx;
|
}
|
|
.grid-item {
|
display: flex;
|
align-items: center;
|
gap: 12rpx;
|
background: #f8f9fa;
|
border-radius: 12rpx;
|
padding: 0 16rpx;
|
|
&.half {
|
width: calc(50% - 8rpx);
|
}
|
|
&.full {
|
width: 100%;
|
}
|
}
|
|
.item-icon {
|
width: 48rpx;
|
height: 48rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
background: #fff;
|
border-radius: 10rpx;
|
flex-shrink: 0;
|
}
|
|
.item-content {
|
flex: 1;
|
min-width: 0;
|
}
|
|
.item-value {
|
font-size: 28rpx;
|
color: #303133;
|
font-weight: 500;
|
}
|
|
// 时间行
|
.time-row {
|
display: flex;
|
align-items: center;
|
gap: 12rpx;
|
margin-top: 16rpx;
|
padding-top: 16rpx;
|
border-top: 1rpx dashed #e5e5e5;
|
}
|
|
.time-label {
|
font-size: 24rpx;
|
color: #909399;
|
}
|
|
.time-value {
|
font-size: 26rpx;
|
color: #f0ae2d;
|
font-weight: 500;
|
}
|
</style>
|