feat(pl): optional escort selection on transport arrange

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
wuzilongandCursor committed 2026-09-13 10:48:23 +08:00
1 parent 3dc71788d4
commit ca3062b0e2
10 files changed
+339 -10

No files matched your search

@@ -80,7 +80,7 @@
label-width="100px"
class="pl-dialog-form"
>
<div class="pl-plan-transport-row pl-plan-transport-row--three">
<div class="pl-plan-transport-row pl-plan-transport-row--four">
<el-form-item label="车牌号" class="pl-plan-transport-row__vehicle">
<div class="pl-plan-vehicle-with-library">
<el-select
@@ -136,6 +136,26 @@
/>
</el-select>
</el-form-item>
<el-form-item label="选择押运员" class="pl-plan-transport-row__escort">
<el-select
v-model="selectedEscortId"
placeholder="请选择押运员(可选)"
filterable
remote
clearable
:remote-method="searchEscorts"
:loading="escortSelectLoading"
:disabled="!formData.vehicleId"
@focus="onEscortSelectFocus"
>
<el-option
v-for="d in escortList"
:key="d.id"
:label="formatDriverOptionLabel(d)"
:value="d.id"
/>
</el-select>
</el-form-item>
<el-form-item label="运输公司" class="pl-plan-transport-row__carrier">
<div class="pl-plan-carrier-with-library">
<el-select
@@ -509,6 +529,7 @@
const deliveryForms = ref<PlanDeliveryForm[]>([createEmptyDeliveryForm(1)])
const loadedPlanSnapshot = ref<Plan | null>(null)
const selectedDriverId = ref('')
const selectedEscortId = ref('')
/** 已安排:禁止仅「保存」,须走保存并安排/调整运输,避免计划与地磅等联动字段脱节 */
const showSaveButton = computed(() => {
@@ -664,6 +685,16 @@
getSelectedId: () => selectedDriverId.value,
listParams: { status: '1', personnelType: 'driver' }
})
const {
list: escortList,
loading: escortSelectLoading,
search: searchEscorts,
onFocus: onEscortSelectFocus,
ensureById: ensureSelectedEscortOption
} = usePlRemotePersonnelOptions({
getSelectedId: () => selectedEscortId.value,
listParams: { status: '1', personnelTypeIn: 'escort,both' }
})
const vehicleBundle = ref<VehicleViewBundle | null>(null)
const formData = reactive({
@@ -1509,6 +1540,7 @@
return {
vehicleId: formData.vehicleId,
driverId: selectedDriverId.value || undefined,
escortId: selectedEscortId.value || undefined,
carrierId: formData.carrierId || undefined,
distanceKm: formData.distanceKm ?? undefined,
freightType: formData.freightType,
@@ -1580,6 +1612,7 @@
freightAmount?: number
carrierId?: string
driverId?: string
escortId?: string
}
formData.distanceKm = transport.distanceKm != null ? Number(transport.distanceKm) : null
formData.freightType = transport.freightType || 'by_weight'
@@ -1589,6 +1622,9 @@
if (transport.driverId) {
selectedDriverId.value = transport.driverId
}
if (transport.escortId) {
selectedEscortId.value = transport.escortId
}
freightCalc.freightPrice.value =
transport.freightPrice != null ? Number(transport.freightPrice) : null
freightCalc.freightAmount.value =
@@ -1660,6 +1696,7 @@
plan,
vehicleId: formData.vehicleId,
driverId: selectedDriverId.value,
escortId: selectedEscortId.value,
carrierId: formData.carrierId,
loadForm: loadForm.value,
deliveryForms: deliveryForms.value,
@@ -1689,6 +1726,7 @@
loadedPlanSnapshot.value = null
vehicleBundle.value = null
selectedDriverId.value = ''
selectedEscortId.value = ''
const d = todayYmd()
Object.assign(formData, {
createDate: d,
@@ -1794,11 +1832,17 @@
if (data.driverId) {
selectedDriverId.value = data.driverId
}
if (data.escortId) {
selectedEscortId.value = data.escortId
}
freightCalc.resetFreightCalc()
await restoreFreightFromTransport(data)
if (selectedDriverId.value) {
await ensureSelectedDriverOption(selectedDriverId.value)
}
if (selectedEscortId.value) {
await ensureSelectedEscortOption(selectedEscortId.value)
}
if (formData.carrierId) {
await ensureSelectedCarrierOption(formData.carrierId)
}
@@ -1865,6 +1909,7 @@
formData.vehicleId = ''
formData.carrierId = ''
selectedDriverId.value = ''
selectedEscortId.value = ''
vehicleBundle.value = null
reapplyStopDibangByVehiclePlate('')
freightCalc.resetFreightCalc()
@@ -1886,7 +1931,13 @@
}
async function loadMasterData() {
await Promise.all([searchVehicles(''), searchCarriers(''), searchDrivers(''), loadDefaultCustomerOptions()])
await Promise.all([
searchVehicles(''),
searchCarriers(''),
searchDrivers(''),
searchEscorts(''),
loadDefaultCustomerOptions()
])
}
function resolveDefaultDriver(personnelList: VehiclePersonnelRow[]) {
@@ -1895,6 +1946,12 @@
selectedDriverId.value = defaultDriver?.personnelId || ''
}
function resolveDefaultEscort(personnelList: VehiclePersonnelRow[]) {
const escorts = personnelList.filter((item) => item.role === 'escort' && item.personnelId)
const defaultEscort = escorts.find((item) => item.isDefault === 1) || escorts[0]
selectedEscortId.value = defaultEscort?.personnelId || ''
}
async function handleVehicleChange(
vehicleId: string,
opts?: { syncStopDibang?: boolean }
@@ -1902,6 +1959,7 @@
const syncStopDibang = opts?.syncStopDibang !== false
vehicleBundle.value = null
selectedDriverId.value = ''
selectedEscortId.value = ''
if (!vehicleId) {
formData.carrierId = ''
if (syncStopDibang) reapplyStopDibangByVehiclePlate('')
@@ -1922,9 +1980,13 @@
formData.carrierId = vehicleBundle.value.detail.carrierId
}
resolveDefaultDriver(vehicleBundle.value.personnelList || [])
resolveDefaultEscort(vehicleBundle.value.personnelList || [])
if (selectedDriverId.value) {
await ensureSelectedDriverOption(selectedDriverId.value)
}
if (selectedEscortId.value) {
await ensureSelectedEscortOption(selectedEscortId.value)
}
} finally {
vehicleLoading.value = false
}
@@ -2306,14 +2368,21 @@
gap: 12px 16px;
}
.pl-plan-transport-row--four {
display: grid;
grid-template-columns: max-content minmax(180px, 240px) minmax(180px, 240px) minmax(240px, 1fr);
gap: 12px 16px;
}
.pl-plan-transport-row__vehicle {
width: max-content;
max-width: 100%;
}
.pl-plan-transport-row__driver {
.pl-plan-transport-row__driver,
.pl-plan-transport-row__escort {
min-width: 0;
max-width: 340px;
max-width: 280px;
}
.pl-plan-transport-row__carrier {