<template>
|
<view class="vehicle-selector">
|
<view class="form-label" v-if="label">{{ label }}</view>
|
<picker
|
mode="selector"
|
:range="vehicles"
|
:value="selectedIndex"
|
@change="onVehicleChange"
|
:disabled="disabled"
|
>
|
<view class="form-input picker-input" :class="{ disabled: disabled }">
|
{{ displayText }}
|
<uni-icons type="arrowright" size="16" color="#999"></uni-icons>
|
</view>
|
</picker>
|
</view>
|
</template>
|
|
<script>
|
import { listAvailableVehicles, getUserBoundVehicle } from "@/api/vehicle"
|
|
export default {
|
name: 'VehicleSelector',
|
props: {
|
// 标签文本
|
label: {
|
type: String,
|
default: '任务车辆'
|
},
|
// 当前选中的车辆ID
|
value: {
|
type: [Number, String],
|
default: null
|
},
|
// 车辆类型过滤(GENERAL/EMERGENCY/WELFARE)
|
vehicleType: {
|
type: String,
|
default: 'GENERAL'
|
},
|
// 部门ID
|
deptId: {
|
type: [Number, String],
|
default: null
|
},
|
// 占位符
|
placeholder: {
|
type: String,
|
default: '请选择任务车辆'
|
},
|
// 是否禁用
|
disabled: {
|
type: Boolean,
|
default: false
|
},
|
// 是否自动选择绑定车辆
|
autoSelectBound: {
|
type: Boolean,
|
default: true
|
}
|
},
|
data() {
|
return {
|
vehicles: [],
|
vehicleOptions: [],
|
selectedIndex: -1
|
}
|
},
|
computed: {
|
displayText() {
|
if (this.selectedIndex >= 0 && this.selectedIndex < this.vehicles.length) {
|
return this.vehicles[this.selectedIndex]
|
}
|
return this.placeholder
|
}
|
},
|
watch: {
|
value: {
|
immediate: true,
|
handler(newVal) {
|
if (newVal && this.vehicleOptions.length > 0) {
|
const index = this.vehicleOptions.findIndex(v => v.id === newVal)
|
this.selectedIndex = index
|
}
|
}
|
},
|
deptId: {
|
immediate: true,
|
handler(newVal) {
|
if (newVal) {
|
this.loadVehicles()
|
}
|
}
|
}
|
},
|
mounted() {
|
if (this.deptId) {
|
this.loadVehicles()
|
}
|
},
|
methods: {
|
// 加载车辆列表
|
loadVehicles() {
|
if (!this.deptId) {
|
console.warn('VehicleSelector: deptId is required')
|
return Promise.reject('deptId is required')
|
}
|
|
return listAvailableVehicles(this.deptId, this.vehicleType).then(response => {
|
const vehicleList = response.data || response.rows || []
|
this.vehicleOptions = vehicleList.map(vehicle => ({
|
id: vehicle.vehicleId,
|
name: vehicle.vehicleNo,
|
type: vehicle.vehicleType,
|
status: vehicle.status
|
}))
|
this.vehicles = this.vehicleOptions.map(v => v.name)
|
|
// 自动选择绑定车辆
|
if (this.autoSelectBound && !this.value) {
|
this.selectBoundVehicle()
|
} else if (this.value) {
|
// 如果有传入的value,设置选中索引
|
const index = this.vehicleOptions.findIndex(v => v.id === this.value)
|
this.selectedIndex = index
|
}
|
|
return vehicleList
|
}).catch(error => {
|
console.error('加载车辆列表失败:', error)
|
this.vehicles = []
|
this.vehicleOptions = []
|
return []
|
})
|
},
|
|
// 选择绑定的车辆
|
selectBoundVehicle() {
|
getUserBoundVehicle().then(response => {
|
const userInfo = response.data || response
|
if (userInfo.boundVehicle) {
|
const boundVehicleNo = userInfo.boundVehicle.vehicleNumber
|
const boundVehicleId = userInfo.boundVehicle.vehicleId
|
|
const vehicleIndex = this.vehicleOptions.findIndex(v =>
|
v.id === boundVehicleId || v.name === boundVehicleNo
|
)
|
|
if (vehicleIndex !== -1) {
|
this.selectedIndex = vehicleIndex
|
this.emitChange(this.vehicleOptions[vehicleIndex])
|
}
|
}
|
}).catch(error => {
|
console.error('获取用户绑定车辆失败:', error)
|
})
|
},
|
|
// 车辆选择变化
|
onVehicleChange(e) {
|
const index = e.detail.value
|
this.selectedIndex = index
|
const selectedVehicle = this.vehicleOptions[index]
|
this.emitChange(selectedVehicle)
|
},
|
|
// 触发事件
|
emitChange(vehicle) {
|
if (vehicle) {
|
this.$emit('input', vehicle.id)
|
this.$emit('change', {
|
vehicleId: vehicle.id,
|
vehicleName: vehicle.name,
|
vehicleType: vehicle.type,
|
vehicleStatus: vehicle.status
|
})
|
}
|
},
|
|
// 重新加载车辆列表(供外部调用)
|
reload() {
|
return this.loadVehicles()
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.vehicle-selector {
|
.form-label {
|
font-size: 28rpx;
|
margin-bottom: 15rpx;
|
color: #333;
|
}
|
|
.form-input {
|
height: 70rpx;
|
padding: 0 20rpx;
|
border: 1rpx solid #eee;
|
border-radius: 10rpx;
|
font-size: 28rpx;
|
|
&.picker-input {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
}
|
|
&.disabled {
|
background-color: #f5f5f5;
|
color: #999;
|
}
|
}
|
}
|
</style>
|