♻️ 派单候选司机不再按承运商组织过滤

- 新增 fetchDriverCandidates:按租户与岗位取司机,不再解析承运商联系人组织
- driverOptionText 只做展示(姓名+手机尾号后四位),写回表单的仍是姓名
- 删除 fetchDriversByCarrierOrganizations 与无调用者的 clearCarrierOrganizationCache
- 运单管理、总单派车、运输计划、装卸管理四页同步;去掉「请先选择承运商」前置
This commit is contained in:
2026-10-23 20:03:49 +08:00
parent 372e8826a2
commit 0add4c5cdc
5 changed files with 119 additions and 175 deletions
@@ -210,7 +210,11 @@
@mousedown="() => handleDriverFocus(route)"
@focus="() => handleDriverFocus(route)"
@select="handleDriverSuggestionSelect"
/></el-form-item
>
<template #default="{ item }">
<span>{{ driverOptionText(item) }}</span>
</template>
</el-autocomplete></el-form-item
></el-col>
<el-col :span="6"
><el-form-item
@@ -239,7 +243,11 @@
@mousedown="() => handleDriverFocus(route)"
@focus="() => handleDriverFocus(route)"
@select="handleEscortSuggestionSelect"
/></el-form-item
>
<template #default="{ item }">
<span>{{ driverOptionText(item) }}</span>
</template>
</el-autocomplete></el-form-item
></el-col>
<el-col v-if="route.carrierType !== '承运商'" :span="6"
><el-form-item label="押运人手机号"
@@ -316,7 +324,7 @@
<script>
import * as api from '@/api/business/master-order';
import { fetchDriversByCarrierOrganizations } from '@/utils/carrier-org-resource';
import { fetchDriverCandidates, driverOptionText } from '@/utils/carrier-org-resource';
import { formatContractOptionLabel } from '@/utils/contract';
import {
currencyUnit,
@@ -403,6 +411,7 @@ export default {
this.applySelfOperatedCarrierDefaults();
},
methods: {
driverOptionText,
loadQuantityUnitOptions() {
if (this.quantityUnitLoading) return this.quantityUnitLoadPromise;
this.quantityUnitLoading = true;
@@ -944,12 +953,6 @@ export default {
route.escortPhone = '';
this.driverOptions = [];
},
getRouteCarrierFilter(route = {}) {
return {
carrierId: route.carrierId || '',
carrierName: route.carrierName || '',
};
},
carrierOptionValue(item = {}) {
return item.contractId || item.id || item.value || item.carrierName || '';
},
@@ -1026,36 +1029,22 @@ export default {
this.activeSuggestRoute = route;
},
async loadDriverOptions(route = {}, keyword = '') {
const carrier = this.getRouteCarrierFilter(route);
if (!carrier.carrierId && !carrier.carrierName) {
this.driverOptions = [];
return [];
}
this.driverLoading = true;
try {
this.driverOptions = await fetchDriversByCarrierOrganizations(
{ size: 20, ...(keyword ? { driverName: keyword } : {}), posts: '司机' },
carrier
);
this.driverOptions = await fetchDriverCandidates({
size: 20,
...(keyword ? { driverName: keyword } : {}),
posts: '司机',
});
return this.driverOptions;
} finally {
this.driverLoading = false;
}
},
fetchDriverSuggestions(queryString, callback) {
const route = this.activeSuggestRoute || {};
const carrier = this.getRouteCarrierFilter(route);
const keyword = String(queryString || '').trim();
if (!carrier.carrierId && !carrier.carrierName) {
callback([]);
if (!keyword) this.$message.warning('请先选择承运商');
return;
}
this.driverLoading = true;
fetchDriversByCarrierOrganizations(
{ size: 20, ...(keyword ? { driverName: keyword } : {}), posts: '司机' },
carrier
)
fetchDriverCandidates({ size: 20, ...(keyword ? { driverName: keyword } : {}), posts: '司机' })
.then(records => {
this.driverOptions = records;
callback(
@@ -1080,19 +1069,13 @@ export default {
if (drivingVehicle) route.vehicleNo = drivingVehicle;
},
fetchEscortSuggestions(queryString, callback) {
const route = this.activeSuggestRoute || {};
const keyword = String(queryString || '').trim();
const carrier = this.getRouteCarrierFilter(route);
if (!carrier.carrierId && !carrier.carrierName) {
callback([]);
if (!keyword) this.$message.warning('请先选择承运商');
return;
}
this.escortLoading = true;
fetchDriversByCarrierOrganizations(
{ size: 20, ...(keyword ? { driverName: keyword } : {}), posts: '押运员' },
carrier
)
fetchDriverCandidates({
size: 20,
...(keyword ? { driverName: keyword } : {}),
posts: '押运员',
})
.then(records => {
callback(
records.map(item => ({
@@ -1870,7 +1870,11 @@
:fetch-suggestions="fetchTaskDriverSuggestions"
:loading="taskDriverLoading"
@select="item => handleTaskDriverSelect('dispatch', item)"
/>
>
<template #default="{ item }">
<span>{{ driverOptionText(item) }}</span>
</template>
</el-autocomplete>
</el-form-item>
<el-form-item
:label="dispatchItemForm.carrierType === '承运商' ? '手机号' : '司机手机号'"
@@ -1893,7 +1897,11 @@
:fetch-suggestions="fetchTaskEscortSuggestions"
:loading="taskEscortLoading"
@select="handleTaskEscortSelect"
/>
>
<template #default="{ item }">
<span>{{ driverOptionText(item) }}</span>
</template>
</el-autocomplete>
</el-form-item>
<el-form-item v-if="dispatchItemForm.carrierType !== '承运商'" label="押运人手机号">
<el-input v-model="dispatchItemForm.escortPhone" placeholder="请输入" />
@@ -2768,7 +2776,7 @@ import {
getList as getProjectList,
} from '@/api/business/project-apply';
import { getList as getCommonRouteList } from '@/api/business/common-route';
import { fetchDriversByCarrierOrganizations } from '@/utils/carrier-org-resource';
import { fetchDriverCandidates, driverOptionText } from '@/utils/carrier-org-resource';
import { getDictionary } from '@/api/system/dictbiz';
import { getDictionary as getSystemDictionary } from '@/api/system/dict';
import { addressTypeOptions } from '@/option/base/common-address';
@@ -3815,6 +3823,7 @@ export default {
},
methods: {
formatContractOptionLabel,
driverOptionText,
initStandaloneFormPage() {
if (!this.isStandaloneFormPage) return;
const mode = this.$route.query.mode === 'edit' ? 'edit' : 'add';
@@ -4995,16 +5004,8 @@ export default {
},
fetchTaskDriverSuggestions(queryString, callback) {
const keyword = String(queryString || '').trim();
const carrier = this.getDispatchCarrierFilter();
if (!carrier.carrierId && !carrier.carrierName) {
callback([]);
return;
}
this.taskDriverLoading = true;
fetchDriversByCarrierOrganizations(
{ size: 20, ...(keyword ? { driverName: keyword } : {}), posts: '司机' },
carrier
)
fetchDriverCandidates({ size: 20, ...(keyword ? { driverName: keyword } : {}), posts: '司机' })
.then(records => {
this.taskDriverOptions = records;
callback(
@@ -5024,16 +5025,12 @@ export default {
},
fetchTaskEscortSuggestions(queryString, callback) {
const keyword = String(queryString || '').trim();
const carrier = this.getDispatchCarrierFilter();
if (!carrier.carrierId && !carrier.carrierName) {
callback([]);
return;
}
this.taskEscortLoading = true;
fetchDriversByCarrierOrganizations(
{ size: 20, ...(keyword ? { driverName: keyword } : {}), posts: '押运员' },
carrier
)
fetchDriverCandidates({
size: 20,
...(keyword ? { driverName: keyword } : {}),
posts: '押运员',
})
.then(records => {
this.taskEscortOptions = records;
callback(records.map(item => ({ ...item, value: item.driverName || item.name || '' })));
@@ -8048,12 +8045,6 @@ export default {
this.taskDriverOptions = [];
this.taskEscortOptions = [];
},
getDispatchCarrierFilter() {
return {
carrierId: this.dispatchItemForm.carrierId || '',
carrierName: this.dispatchItemForm.carrierName || '',
};
},
handleDispatchCargoQuantityInput(row, value) {
const text = String(value || '').replace(/[^\d.]/g, '');
const parts = text.split('.');
@@ -1200,7 +1200,11 @@
:loading="taskDriverLoading"
:disabled="dialogReadonly"
@select="handleTaskDriverSelect"
/>
>
<template #default="{ item }">
<span>{{ driverOptionText(item) }}</span>
</template>
</el-autocomplete>
</el-form-item>
<el-form-item
v-if="isRoadTransport"
@@ -1279,7 +1283,11 @@
:loading="taskEscortLoading"
:disabled="dialogReadonly"
@select="handleTaskEscortSelect"
/>
>
<template #default="{ item }">
<span>{{ driverOptionText(item) }}</span>
</template>
</el-autocomplete>
</el-form-item>
<el-form-item v-if="showRoadEscortFields" label="押运人手机号">
<el-input
@@ -1660,7 +1668,11 @@
style="width: 100%"
@select="handleReassignDriverSelect"
@change="handleReassignDriverChange"
/>
>
<template #default="{ item }">
<span>{{ driverOptionText(item) }}</span>
</template>
</el-autocomplete>
</el-form-item>
<el-form-item
label="手机号"
@@ -3700,9 +3712,7 @@ import VoucherExecutionDetail from './voucher-execution-detail.vue';
import PunchRecordPhotos from './punch-record-photos.vue';
import AddressMapPicker from '@/components/address-map-picker/main.vue';
import { getList as getDriverList } from '@/api/transportCapacity/driver';
import {
fetchDriversByCarrierOrganizations,
} from '@/utils/carrier-org-resource';
import { fetchDriverCandidates, driverOptionText } from '@/utils/carrier-org-resource';
import { getDictionary } from '@/api/system/dictbiz';
import { getDictionary as getSystemDictionary } from '@/api/system/dict';
import { addressTypeOptions } from '@/option/base/common-address';
@@ -4814,6 +4824,7 @@ export default {
},
methods: {
formatContractOptionLabel,
driverOptionText,
parseRouteChangeContent,
// 页面被 keep-alive 缓存/卸载时调用,关闭本页所有 append-to-body 的弹窗,
// 避免 Teleport 出去的 DOM 残留在 body 上盖住后续页面(详见 data 里的说明)。
@@ -7967,19 +7978,10 @@ export default {
this.taskDriverOptions = [];
this.taskEscortOptions = [];
},
getTaskCarrierFilter() {
return {
carrierId: this.form.carrierId || '',
carrierName: this.form.carrierName || '',
};
},
loadTaskDriverOptions() {
if (!this.taskInfoFormEnabled || this.taskDriverLoading) return Promise.resolve([]);
this.taskDriverLoading = true;
return fetchDriversByCarrierOrganizations(
{ size: 9999, posts: '司机' },
this.getTaskCarrierFilter()
)
return fetchDriverCandidates({ size: 9999, posts: '司机' })
.then(records => {
this.taskDriverOptions = records;
return this.taskDriverOptions;
@@ -7990,16 +7992,8 @@ export default {
},
fetchTaskDriverSuggestions(queryString, callback) {
const keyword = String(queryString || '').trim();
const carrier = this.getTaskCarrierFilter();
if (!carrier.carrierId && !carrier.carrierName) {
callback([]);
return;
}
this.taskDriverLoading = true;
fetchDriversByCarrierOrganizations(
{ size: 20, ...(keyword ? { driverName: keyword } : {}), posts: '司机' },
carrier
)
fetchDriverCandidates({ size: 20, ...(keyword ? { driverName: keyword } : {}), posts: '司机' })
.then(records => {
this.taskDriverOptions = records;
callback(
@@ -8019,16 +8013,12 @@ export default {
},
fetchTaskEscortSuggestions(queryString, callback) {
const keyword = String(queryString || '').trim();
const carrier = this.getTaskCarrierFilter();
if (!carrier.carrierId && !carrier.carrierName) {
callback([]);
return;
}
this.taskEscortLoading = true;
fetchDriversByCarrierOrganizations(
{ size: 20, ...(keyword ? { driverName: keyword } : {}), posts: '押运员' },
carrier
)
fetchDriverCandidates({
size: 20,
...(keyword ? { driverName: keyword } : {}),
posts: '押运员',
})
.then(records => {
this.taskEscortOptions = records;
callback(records.map(item => ({ ...item, value: item.driverName || item.name || '' })));
@@ -10235,20 +10225,8 @@ export default {
},
fetchReassignDriverSuggestions(queryString, callback) {
const keyword = String(queryString || '').trim();
const row = this.reassignDrawer.row || {};
const carrier = {
carrierId: row.carrierId || '',
carrierName: row.carrierName || '',
};
if (!carrier.carrierId && !carrier.carrierName) {
callback([]);
return;
}
this.reassignDrawer.driverLoading = true;
fetchDriversByCarrierOrganizations(
{ size: 20, ...(keyword ? { driverName: keyword } : {}), posts: '司机' },
carrier
)
fetchDriverCandidates({ size: 20, ...(keyword ? { driverName: keyword } : {}), posts: '司机' })
.then(records => {
this.reassignDriverOptions = records;
callback(
+23 -28
View File
@@ -1068,7 +1068,7 @@
<el-option
v-for="item in driverOptions"
:key="item.id || item.driverName || item.name"
:label="item.driverName || item.name"
:label="driverOptionText(item)"
:value="item.driverName || item.name"
/>
</el-select>
@@ -1465,7 +1465,11 @@
:loading="driverLoading"
placeholder="请输入"
@select="item => handleDriverSuggestionSelect('dialog', item)"
/>
>
<template #default="{ item }">
<span>{{ driverOptionText(item) }}</span>
</template>
</el-autocomplete>
</el-form-item>
<el-form-item
label="手机号"
@@ -1488,7 +1492,11 @@
:loading="escortLoading"
placeholder="请输入"
@select="item => handleEscortSuggestionSelect('dialog', item)"
/>
>
<template #default="{ item }">
<span>{{ driverOptionText(item) }}</span>
</template>
</el-autocomplete>
</el-form-item>
<el-form-item v-if="dialogForm.carrierType !== '承运商'" label="押运人手机号">
<el-input v-model="dialogForm.escortPhone" clearable placeholder="请输入" />
@@ -1804,7 +1812,7 @@ import { getList as getContractList } from '@/api/business/contract-manage';
import { getParentOptions as getCargoTypeOptions } from '@/api/base/cargo-type';
import { getList as getCustomerList } from '@/api/vehicle/customer-archive';
import { getList as getDriverList } from '@/api/transportCapacity/driver';
import { fetchDriversByCarrierOrganizations } from '@/utils/carrier-org-resource';
import { fetchDriverCandidates, driverOptionText } from '@/utils/carrier-org-resource';
import { formatContractOptionLabel } from '@/utils/contract';
import {
getList as getProcessConfigList,
@@ -2304,6 +2312,7 @@ export default {
},
methods: {
parseRouteChangeContent,
driverOptionText,
formatTaskCarrierContractLabel(item = {}) {
const carrierName = item.carrierName || item.partyB || '';
const contractLabel = formatContractOptionLabel(item);
@@ -4267,12 +4276,6 @@ export default {
this.dialogForm.escortPhone = '';
this.driverOptions = [];
},
getDialogCarrierFilter() {
return {
carrierId: this.dialogForm.carrierId || '',
carrierName: this.dialogForm.carrierName || '',
};
},
handleDriverChange(value) {
const driver = this.driverOptions.find(item => (item.driverName || item.name) === value);
if (driver && !this.dialogForm.driverPhone) {
@@ -4306,16 +4309,12 @@ export default {
},
fetchEscortSuggestions(queryString, callback) {
const keyword = String(queryString || '').trim();
const carrier = this.getDialogCarrierFilter();
if (!carrier.carrierId && !carrier.carrierName) {
callback([]);
return;
}
this.escortLoading = true;
fetchDriversByCarrierOrganizations(
{ size: 20, ...(keyword ? { driverName: keyword } : {}), posts: '押运员' },
carrier
)
fetchDriverCandidates({
size: 20,
...(keyword ? { driverName: keyword } : {}),
posts: '押运员',
})
.then(records => {
callback(
records.map(item => ({
@@ -4395,17 +4394,13 @@ export default {
}
},
async loadDialogDriverOptions(keyword = '') {
const carrier = this.getDialogCarrierFilter();
if (!carrier.carrierId && !carrier.carrierName) {
this.driverOptions = [];
return [];
}
this.driverLoading = true;
try {
this.driverOptions = await fetchDriversByCarrierOrganizations(
{ size: 20, ...(keyword ? { driverName: keyword } : {}), posts: '司机' },
carrier
);
this.driverOptions = await fetchDriverCandidates({
size: 20,
...(keyword ? { driverName: keyword } : {}),
posts: '司机',
});
return this.driverOptions;
} finally {
this.driverLoading = false;