提交
This commit is contained in:
1 parent
42ad896456
commit
6b2147aa46
66 files changed
+617071
-28046
No files matched your search
@@ -312,7 +312,7 @@ async function getList() {
|
||||
|
||||
function syncTableSelection() {
|
||||
const table = tableRef.value
|
||||
if (!table) return
|
||||
if (!table?.setCurrentRow) return
|
||||
if (!selectedId.value) {
|
||||
table.setCurrentRow(undefined)
|
||||
return
|
||||
@@ -426,7 +426,7 @@ function handleOpen() {
|
||||
queryParams.keyword = ''
|
||||
queryParams.customerId = props.customerId || undefined
|
||||
nextTick(() => {
|
||||
tableRef.value?.setCurrentRow(undefined)
|
||||
tableRef.value?.setCurrentRow?.(undefined)
|
||||
})
|
||||
getList()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,418 @@
|
||||
<!--
|
||||
列表可配置列统计行:点选单元格向上弹出无/求和/平均/最大/最小;
|
||||
仅统计当前页 data;偏好按 storageKey 存 localStorage。
|
||||
父级须用同一容器包裹 ListTable/el-table 与本组件,并传入 table-wrap-el。
|
||||
-->
|
||||
<template>
|
||||
<div
|
||||
ref="statsScrollRef"
|
||||
class="list-column-stats-row"
|
||||
aria-label="列表列统计"
|
||||
@scroll="onStatsRowScroll"
|
||||
>
|
||||
<div class="list-column-stats-row__inner">
|
||||
<div
|
||||
v-for="col in columns"
|
||||
:key="col.key"
|
||||
class="list-column-stats-row__cell"
|
||||
:class="{ 'is-stat': col.interactive, 'is-spacer': !col.interactive }"
|
||||
>
|
||||
<el-popover
|
||||
v-if="col.interactive && col.prop"
|
||||
:visible="menuOpenProp === col.prop"
|
||||
placement="top-start"
|
||||
:width="132"
|
||||
:teleported="true"
|
||||
trigger="click"
|
||||
:hide-after="0"
|
||||
popper-class="list-column-stats-dropdown"
|
||||
@update:visible="(v: boolean) => setMenuOpen(col.prop!, v)"
|
||||
>
|
||||
<template #reference>
|
||||
<button
|
||||
type="button"
|
||||
class="list-column-stats-row__trigger"
|
||||
:class="{ 'is-empty': !cellText(col) }"
|
||||
>
|
||||
{{ cellText(col) || '\u00a0' }}
|
||||
</button>
|
||||
</template>
|
||||
<div class="list-column-stats-menu">
|
||||
<button
|
||||
v-for="opt in COLUMN_STAT_METHOD_OPTIONS"
|
||||
:key="opt.label"
|
||||
type="button"
|
||||
class="list-column-stats-menu__item"
|
||||
:class="{ 'is-active': (config[col.prop!] || '') === opt.value }"
|
||||
@click="pick(col.prop!, opt.value)"
|
||||
>
|
||||
{{ opt.label }}
|
||||
</button>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
import {
|
||||
COLUMN_STAT_METHOD_OPTIONS,
|
||||
applyStatsCellAlignStyles,
|
||||
formatColumnStatDisplay,
|
||||
getTableColumnTextAligns,
|
||||
loadColumnStatConfig,
|
||||
resolveStatsCellAlign,
|
||||
saveColumnStatConfig,
|
||||
setColumnStatMethod,
|
||||
type ColumnStatConfigMap,
|
||||
type ColumnStatMethod,
|
||||
type StatsRowColumn
|
||||
} from '@/utils/list-column-stats'
|
||||
|
||||
defineOptions({ name: 'ListColumnStatsRow' })
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
storageKey: string
|
||||
columns: StatsRowColumn[]
|
||||
data: Record<string, unknown>[] | any[]
|
||||
/** 外层包裹表 + 统计行的元素 */
|
||||
tableWrapEl?: HTMLElement | null
|
||||
/** 自定义取值;默认 row[prop] */
|
||||
getCellValue?: (row: any, prop: string) => unknown
|
||||
}>(),
|
||||
{
|
||||
tableWrapEl: null,
|
||||
getCellValue: undefined
|
||||
}
|
||||
)
|
||||
|
||||
const statsScrollRef = ref<HTMLElement | null>(null)
|
||||
const config = ref<ColumnStatConfigMap>({})
|
||||
const menuOpenProp = ref<string | null>(null)
|
||||
|
||||
let scrollSyncing = false
|
||||
let headerResizeObserver: ResizeObserver | null = null
|
||||
let tableScrollElBound: HTMLElement | null = null
|
||||
|
||||
watch(
|
||||
() => props.storageKey,
|
||||
(key) => {
|
||||
config.value = loadColumnStatConfig(key)
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
const columnsRef = computed(() => props.columns || [])
|
||||
|
||||
function resolveCellValue(row: any, prop: string): unknown {
|
||||
if (props.getCellValue) return props.getCellValue(row, prop)
|
||||
return row?.[prop]
|
||||
}
|
||||
|
||||
function cellValues(prop: string): unknown[] {
|
||||
return (props.data || []).map((row) => resolveCellValue(row, prop))
|
||||
}
|
||||
|
||||
function cellText(col: StatsRowColumn): string {
|
||||
if (!col.prop) return ''
|
||||
const method = config.value[col.prop]
|
||||
return formatColumnStatDisplay(method, cellValues(col.prop), { money: !!col.money })
|
||||
}
|
||||
|
||||
function setMenuOpen(prop: string, visible: boolean) {
|
||||
menuOpenProp.value = visible ? prop : menuOpenProp.value === prop ? null : menuOpenProp.value
|
||||
}
|
||||
|
||||
function pick(prop: string, method: ColumnStatMethod | '') {
|
||||
config.value = setColumnStatMethod(config.value, prop, method)
|
||||
saveColumnStatConfig(config.value, props.storageKey)
|
||||
menuOpenProp.value = null
|
||||
}
|
||||
|
||||
function getMainTableEl(): HTMLElement | null {
|
||||
const wrap = props.tableWrapEl
|
||||
if (!wrap) return null
|
||||
return (
|
||||
(wrap.querySelector(':scope > .el-table') as HTMLElement | null) ||
|
||||
(wrap.querySelector('.el-table') as HTMLElement | null)
|
||||
)
|
||||
}
|
||||
|
||||
function getTableScrollEl(): HTMLElement | null {
|
||||
const table = getMainTableEl()
|
||||
if (!table) return null
|
||||
return (
|
||||
(table.querySelector('.el-table__body-wrapper .el-scrollbar__wrap') as HTMLElement | null) ||
|
||||
(table.querySelector('.el-table__body-wrapper') as HTMLElement | null)
|
||||
)
|
||||
}
|
||||
|
||||
function getHeaderWidths(): number[] {
|
||||
const table = getMainTableEl()
|
||||
if (!table) return []
|
||||
const cols = table.querySelectorAll('.el-table__header colgroup col')
|
||||
const fromCols: number[] = []
|
||||
cols.forEach((col) => {
|
||||
const el = col as HTMLElement
|
||||
if (el.getAttribute('name') === 'gutter') return
|
||||
const w =
|
||||
el.getBoundingClientRect().width || Number.parseFloat(el.getAttribute('width') || '') || 0
|
||||
if (w > 0) fromCols.push(w)
|
||||
})
|
||||
if (fromCols.length >= columnsRef.value.length) return fromCols
|
||||
|
||||
const ths = table.querySelectorAll('.el-table__header-wrapper th.el-table__cell')
|
||||
const fromThs: number[] = []
|
||||
ths.forEach((th) => {
|
||||
const el = th as HTMLElement
|
||||
if (el.classList.contains('gutter')) return
|
||||
const w = el.getBoundingClientRect().width
|
||||
if (w > 0) fromThs.push(w)
|
||||
})
|
||||
return fromThs
|
||||
}
|
||||
|
||||
function syncWidths() {
|
||||
const widths = getHeaderWidths()
|
||||
const aligns = getTableColumnTextAligns(getMainTableEl())
|
||||
const inner = statsScrollRef.value?.querySelector(
|
||||
'.list-column-stats-row__inner'
|
||||
) as HTMLElement | null
|
||||
const cells = statsScrollRef.value?.querySelectorAll('.list-column-stats-row__cell')
|
||||
if (!inner || !cells?.length || !widths.length) return
|
||||
|
||||
const cols = columnsRef.value
|
||||
const count = Math.min(cells.length, widths.length, cols.length)
|
||||
let total = 0
|
||||
for (let i = 0; i < count; i++) {
|
||||
const w = Math.round(widths[i])
|
||||
total += w
|
||||
const el = cells[i] as HTMLElement
|
||||
el.style.flex = 'none'
|
||||
el.style.width = `${w}px`
|
||||
el.style.minWidth = `${w}px`
|
||||
el.style.maxWidth = `${w}px`
|
||||
applyStatsCellAlignStyles(
|
||||
el,
|
||||
resolveStatsCellAlign(cols[i], aligns[i]),
|
||||
'.list-column-stats-row__trigger'
|
||||
)
|
||||
}
|
||||
inner.style.width = `${total}px`
|
||||
inner.style.minWidth = `${total}px`
|
||||
|
||||
bindTableScrollListener()
|
||||
const tableScroll = getTableScrollEl()
|
||||
const statsScroll = statsScrollRef.value
|
||||
if (tableScroll && statsScroll) {
|
||||
statsScroll.scrollLeft = tableScroll.scrollLeft
|
||||
}
|
||||
}
|
||||
|
||||
function scheduleSync() {
|
||||
nextTick(() => {
|
||||
syncWidths()
|
||||
ensureHeaderObserver()
|
||||
})
|
||||
}
|
||||
|
||||
function ensureHeaderObserver() {
|
||||
const table = getMainTableEl()
|
||||
const header = table?.querySelector('.el-table__header-wrapper') as HTMLElement | null
|
||||
if (!header) return
|
||||
if (headerResizeObserver) headerResizeObserver.disconnect()
|
||||
headerResizeObserver = new ResizeObserver(() => syncWidths())
|
||||
headerResizeObserver.observe(header)
|
||||
header.querySelectorAll('th.el-table__cell').forEach((th) => {
|
||||
if ((th as HTMLElement).classList.contains('gutter')) return
|
||||
headerResizeObserver?.observe(th)
|
||||
})
|
||||
}
|
||||
|
||||
function bindTableScrollListener() {
|
||||
const el = getTableScrollEl()
|
||||
if (!el || el === tableScrollElBound) return
|
||||
if (tableScrollElBound) {
|
||||
tableScrollElBound.removeEventListener('scroll', onTableScroll)
|
||||
}
|
||||
tableScrollElBound = el
|
||||
el.addEventListener('scroll', onTableScroll, { passive: true })
|
||||
}
|
||||
|
||||
function onTableScroll() {
|
||||
if (scrollSyncing) return
|
||||
const tableScroll = getTableScrollEl()
|
||||
const statsScroll = statsScrollRef.value
|
||||
if (!tableScroll || !statsScroll) return
|
||||
if (statsScroll.scrollLeft === tableScroll.scrollLeft) return
|
||||
scrollSyncing = true
|
||||
statsScroll.scrollLeft = tableScroll.scrollLeft
|
||||
requestAnimationFrame(() => {
|
||||
scrollSyncing = false
|
||||
})
|
||||
}
|
||||
|
||||
function onStatsRowScroll() {
|
||||
if (scrollSyncing) return
|
||||
const tableScroll = getTableScrollEl()
|
||||
const statsScroll = statsScrollRef.value
|
||||
if (!tableScroll || !statsScroll) return
|
||||
if (tableScroll.scrollLeft === statsScroll.scrollLeft) return
|
||||
scrollSyncing = true
|
||||
tableScroll.scrollLeft = statsScroll.scrollLeft
|
||||
requestAnimationFrame(() => {
|
||||
scrollSyncing = false
|
||||
})
|
||||
}
|
||||
|
||||
/** 供父级在 header-dragend 后调用 */
|
||||
function resync() {
|
||||
scheduleSync()
|
||||
}
|
||||
|
||||
defineExpose({ resync })
|
||||
|
||||
watch(
|
||||
() => [props.columns, props.data, props.tableWrapEl] as const,
|
||||
() => scheduleSync(),
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
scheduleSync()
|
||||
setTimeout(() => scheduleSync(), 150)
|
||||
setTimeout(() => scheduleSync(), 400)
|
||||
window.addEventListener('resize', scheduleSync)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', scheduleSync)
|
||||
headerResizeObserver?.disconnect()
|
||||
headerResizeObserver = null
|
||||
if (tableScrollElBound) {
|
||||
tableScrollElBound.removeEventListener('scroll', onTableScroll)
|
||||
tableScrollElBound = null
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.list-column-stats-row {
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
border-top: 2px solid var(--el-color-primary, #10b981);
|
||||
background: var(--mint-primary-bg, #ecfdf5);
|
||||
font-weight: 600;
|
||||
color: var(--mint-text, #1e293b);
|
||||
min-height: 44px;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.list-column-stats-row::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.list-column-stats-row__inner {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
min-height: 44px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.list-column-stats-row__cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 0 8px;
|
||||
box-sizing: border-box;
|
||||
border-right: 1px solid var(--mint-border, #e2e8f0);
|
||||
flex: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.list-column-stats-row__cell.is-align-left {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.list-column-stats-row__cell.is-align-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.list-column-stats-row__cell.is-align-right {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.list-column-stats-row__cell.is-spacer {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.list-column-stats-row__trigger {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
min-height: 28px;
|
||||
margin: 0;
|
||||
padding: 4px 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
line-height: 1.4;
|
||||
font-size: 13px;
|
||||
font-weight: inherit;
|
||||
color: inherit;
|
||||
outline: none;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.list-column-stats-row__trigger.is-empty {
|
||||
color: var(--mint-text-muted, #64748b);
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.list-column-stats-dropdown {
|
||||
z-index: 4000 !important;
|
||||
padding: 6px !important;
|
||||
}
|
||||
|
||||
.list-column-stats-menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.list-column-stats-menu__item {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 8px 10px;
|
||||
border: 0;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
color: #1e293b;
|
||||
font-size: 13px;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.list-column-stats-menu__item:hover {
|
||||
background: #ecfdf5;
|
||||
color: #059669;
|
||||
}
|
||||
|
||||
.list-column-stats-menu__item.is-active {
|
||||
background: #d1fae5;
|
||||
color: #059669;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -129,7 +129,9 @@
|
||||
)
|
||||
|
||||
/**
|
||||
* 代理底层 el-table,保证父组件 ref 上的 clearSelection / doLayout 等仍可用
|
||||
* 代理底层 el-table,保证父组件 ref 上的 clearSelection / setCurrentRow / doLayout 等仍可用。
|
||||
* 必须实现 has:Vue exposeProxy 用 `key in target` 决定是否转发,空对象 Proxy 若不声明 has
|
||||
* 则 `in` 恒为 false,父组件拿到的方法永远是 undefined。
|
||||
*/
|
||||
const exposed = new Proxy(
|
||||
{},
|
||||
@@ -148,6 +150,17 @@
|
||||
if (!table) return undefined
|
||||
const value = table[prop as keyof typeof table]
|
||||
return typeof value === 'function' ? value.bind(table) : value
|
||||
},
|
||||
has(_target, prop) {
|
||||
if (
|
||||
prop === 'elTableRef' ||
|
||||
prop === 'applyColumnWidths' ||
|
||||
prop === 'resetColumnWidths'
|
||||
) {
|
||||
return true
|
||||
}
|
||||
const table = tableRef.value
|
||||
return !!table && prop in table
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -73,16 +73,20 @@
|
||||
<el-form-item label="选择司机" prop="driverId">
|
||||
<el-select
|
||||
v-model="formData.driverId"
|
||||
placeholder="请先选择车辆(可选)"
|
||||
placeholder="请选择司机(可选)"
|
||||
filterable
|
||||
remote
|
||||
clearable
|
||||
:disabled="!formData.vehicleId || vehicleDriverList.length === 0"
|
||||
:remote-method="searchDrivers"
|
||||
:loading="driverSelectLoading"
|
||||
:disabled="!formData.vehicleId"
|
||||
@focus="onDriverSelectFocus"
|
||||
>
|
||||
<el-option
|
||||
v-for="d in vehicleDriverList"
|
||||
:key="d.personnelId"
|
||||
:label="formatDriverLabel(d)"
|
||||
:value="d.personnelId!"
|
||||
v-for="d in driverList"
|
||||
:key="d.id"
|
||||
:label="formatDriverOptionLabel(d)"
|
||||
:value="d.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@@ -345,6 +349,7 @@ import {
|
||||
transportApi,
|
||||
type Plan,
|
||||
type PlanProduct,
|
||||
type Personnel,
|
||||
type Transport,
|
||||
type TransportArrangeResult,
|
||||
type VehiclePersonnelRow
|
||||
@@ -360,6 +365,7 @@ import type { PlanFormProductRow } from '@/composables/usePlContractToPlan'
|
||||
import { usePlFreightCalc } from '@/composables/usePlFreightCalc'
|
||||
import {
|
||||
usePlRemoteCarrierOptions,
|
||||
usePlRemotePersonnelOptions,
|
||||
usePlRemoteVehicleOptions
|
||||
} from '@/composables/usePlRemoteOptions'
|
||||
import { loadVehicleViewBundle, type VehicleViewBundle } from '@/composables/usePlVehicleViewDetail'
|
||||
@@ -370,6 +376,7 @@ import { isTonProductUnit } from '@/utils/crm-product-display'
|
||||
import { formatDate } from '@/utils/format'
|
||||
import { pickBxData } from '@/utils/http/bx'
|
||||
import { canPrintSlipCommand, formatPlVehiclePlateDisplay, type PlPrintSlipCommand } from '@/utils/pl-display'
|
||||
import { getPersonnelAffiliationLabel } from '@/utils/pl-personnel-cert'
|
||||
|
||||
const dictStore = useDictStore()
|
||||
|
||||
@@ -440,7 +447,18 @@ const {
|
||||
getSelectedId: () => formData.carrierId,
|
||||
listParams: { status: '1' }
|
||||
})
|
||||
const vehicleDriverList = ref<VehiclePersonnelRow[]>([])
|
||||
/** 司机下拉:全部启用中的驾驶员(山峡自有 + 三方),不限车辆绑定 */
|
||||
const {
|
||||
list: driverList,
|
||||
loading: driverSelectLoading,
|
||||
search: searchDrivers,
|
||||
onFocus: onDriverSelectFocus,
|
||||
reset: resetDriverOptions,
|
||||
ensureById: ensureSelectedDriverOption
|
||||
} = usePlRemotePersonnelOptions({
|
||||
getSelectedId: () => formData.driverId,
|
||||
listParams: { status: '1', personnelType: 'driver' }
|
||||
})
|
||||
const prefilledDriverId = ref('')
|
||||
const vehicleBundle = ref<VehicleViewBundle | null>(null)
|
||||
const vehicleViewVisible = ref(false)
|
||||
@@ -471,8 +489,7 @@ const formData = reactive({
|
||||
})
|
||||
|
||||
const formRules = {
|
||||
vehicleId: [{ required: true, message: '请选择车辆', trigger: 'change' }],
|
||||
driverId: [{ required: true, message: '请选择司机', trigger: 'change' }]
|
||||
vehicleId: [{ required: true, message: '请选择车辆', trigger: 'change' }]
|
||||
}
|
||||
|
||||
const dialogTitle = computed(() => {
|
||||
@@ -560,22 +577,25 @@ watch(canGenerateDibangPlan, allowed => {
|
||||
}
|
||||
})
|
||||
|
||||
function formatDriverLabel(d: VehiclePersonnelRow) {
|
||||
function formatDriverOptionLabel(d: Personnel) {
|
||||
const phone = d.phoneNo ? ` (${d.phoneNo})` : ''
|
||||
return `${d.personnelName}${phone}`
|
||||
const affiliation = getPersonnelAffiliationLabel(d.personnelAffiliation)
|
||||
const suffix = affiliation ? ` · ${affiliation}` : ''
|
||||
return `${d.personnelName}${phone}${suffix}`
|
||||
}
|
||||
|
||||
/** 默认司机仍按车辆绑定人员规则预填;下拉选项已改为全量驾驶员 */
|
||||
function applyVehiclePersonnel(personnelList: VehiclePersonnelRow[], preferredDriverId?: string) {
|
||||
vehicleDriverList.value = personnelList.filter(p => p.role === 'driver' && p.personnelId)
|
||||
if (preferredDriverId && vehicleDriverList.value.some(d => d.personnelId === preferredDriverId)) {
|
||||
const vehicleDrivers = personnelList.filter(p => p.role === 'driver' && p.personnelId)
|
||||
if (preferredDriverId && vehicleDrivers.some(d => d.personnelId === preferredDriverId)) {
|
||||
formData.driverId = preferredDriverId
|
||||
return
|
||||
}
|
||||
const defaultDriver = personnelList.find(p => p.role === 'driver' && p.isDefault === 1 && p.personnelId)
|
||||
if (defaultDriver?.personnelId) {
|
||||
formData.driverId = defaultDriver.personnelId
|
||||
} else if (vehicleDriverList.value.length === 1 && vehicleDriverList.value[0].personnelId) {
|
||||
formData.driverId = vehicleDriverList.value[0].personnelId
|
||||
} else if (vehicleDrivers.length === 1 && vehicleDrivers[0].personnelId) {
|
||||
formData.driverId = vehicleDrivers[0].personnelId
|
||||
} else {
|
||||
formData.driverId = ''
|
||||
}
|
||||
@@ -652,9 +672,9 @@ function resetState() {
|
||||
resetArrangeActions()
|
||||
plan.value = {}
|
||||
products.value = []
|
||||
vehicleDriverList.value = []
|
||||
resetVehicleOptions()
|
||||
resetCarrierOptions()
|
||||
resetDriverOptions()
|
||||
prefilledDriverId.value = ''
|
||||
vehicleBundle.value = null
|
||||
vehicleViewVisible.value = false
|
||||
@@ -687,14 +707,13 @@ function resetState() {
|
||||
}
|
||||
|
||||
async function loadMasterData() {
|
||||
await Promise.all([searchVehicles(''), searchCarriers('')])
|
||||
await Promise.all([searchVehicles(''), searchCarriers(''), searchDrivers('')])
|
||||
}
|
||||
|
||||
async function handleVehicleChange(vehicleId: string, preferredDriverId?: string) {
|
||||
if (!vehicleId) {
|
||||
formData.driverId = ''
|
||||
formData.carrierId = ''
|
||||
vehicleDriverList.value = []
|
||||
vehicleBundle.value = null
|
||||
return
|
||||
}
|
||||
@@ -718,6 +737,9 @@ async function handleVehicleChange(vehicleId: string, preferredDriverId?: string
|
||||
await ensureSelectedCarrierOption(formData.carrierId)
|
||||
}
|
||||
applyVehiclePersonnel(vehicleBundle.value.personnelList || [], preferredDriverId)
|
||||
if (formData.driverId) {
|
||||
await ensureSelectedDriverOption(formData.driverId)
|
||||
}
|
||||
} finally {
|
||||
vehicleLoading.value = false
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user