🔀 合并 websoft/dev,统一待回单确认与公路配载校验
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1079,31 +1079,12 @@
|
||||
<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>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="运输方式">
|
||||
<el-select
|
||||
v-model="candidateQuery.transportType"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="请选择"
|
||||
:disabled="dialogMode === 'add'"
|
||||
@visible-change="visible => visible && loadTransportTypeOptions()"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in transportTypeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
<el-col
|
||||
:span="candidateSearchVisible ? 24 : 6"
|
||||
@@ -1511,7 +1492,11 @@
|
||||
placeholder="请输入"
|
||||
:disabled="dialogReadonly || isRunningSelfDriverLocked"
|
||||
@select="item => handleDriverSuggestionSelect('dialog', item)"
|
||||
/>
|
||||
>
|
||||
<template #default="{ item }">
|
||||
<span>{{ driverOptionText(item) }}</span>
|
||||
</template>
|
||||
</el-autocomplete>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="手机号"
|
||||
@@ -1550,7 +1535,11 @@
|
||||
placeholder="请输入"
|
||||
:disabled="dialogReadonly"
|
||||
@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
|
||||
@@ -1880,7 +1869,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,
|
||||
@@ -1905,7 +1894,6 @@ import { normalizeMapSearchResults, searchAmapPlaceText } from '@/utils/map-sear
|
||||
import { parseRouteChangeContent } from '@/utils/route-change';
|
||||
|
||||
const defaultTransportType = '';
|
||||
const defaultCandidateTransportType = '';
|
||||
const AMAP_KEY = '653b7cf105ad7fb8ec9b2f5198ade315';
|
||||
const AMAP_SECURITY_CODE = '5aab65c632e48ebae0d0e28f5b28e21a';
|
||||
const loadingCreateWaybillsStorageKey = 'loading-manage-create-waybills';
|
||||
@@ -1946,7 +1934,6 @@ const createCandidateSearchForm = () => ({
|
||||
vehicleNo: '',
|
||||
carrierName: '',
|
||||
driverName: '',
|
||||
transportType: defaultCandidateTransportType,
|
||||
});
|
||||
|
||||
const createDialogForm = () => ({
|
||||
@@ -2401,6 +2388,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
parseRouteChangeContent,
|
||||
driverOptionText,
|
||||
formatTaskCarrierContractLabel(item = {}) {
|
||||
const carrierName = item.carrierName || item.partyB || '';
|
||||
const contractLabel = formatContractOptionLabel(item);
|
||||
@@ -3104,7 +3092,6 @@ export default {
|
||||
this.dialogMode = mode;
|
||||
this.dialogLoading = true;
|
||||
this.resetDialogData();
|
||||
if (mode === 'add') this.candidateQuery.transportType = 'road';
|
||||
try {
|
||||
if (row?.id) {
|
||||
const res = await loadingApi.getDetail(row.id);
|
||||
@@ -3131,7 +3118,6 @@ export default {
|
||||
} else {
|
||||
this.dialogForm = createDialogForm();
|
||||
this.candidateQuery = createCandidateSearchForm();
|
||||
this.candidateQuery.transportType = 'road';
|
||||
await this.loadCandidateWaybills();
|
||||
}
|
||||
} finally {
|
||||
@@ -3912,16 +3898,17 @@ export default {
|
||||
try {
|
||||
const query = {
|
||||
...this.buildQueryParams(this.candidateQuery),
|
||||
// 与后端 LoadableAdmissionSupport 一致:公路 + 待执行/进行中 + 未关联有效配载单
|
||||
// 公路、待执行、未配载的判定都在后端可配载开关内
|
||||
// 该开关已把候选限定为公路,再按精确运输方式取值筛会漏掉「公路运输」这类历史写法
|
||||
loadableOnly: 1,
|
||||
// 仅查当前账户所属组织及子组织下的运单
|
||||
// allDept=0 表示不指定组织:超管与「数据权限范围=全部组织」的账户后端不过滤组织,
|
||||
// 其余账户限定本组织(不展开下级)
|
||||
allDept: 0,
|
||||
};
|
||||
const transportType = this.getCandidateTransportTypeQuery(query.transportType);
|
||||
const res = await getWaybillList(
|
||||
this.candidatePage.currentPage,
|
||||
this.candidatePage.pageSize,
|
||||
{ ...query, transportType }
|
||||
query
|
||||
);
|
||||
const page = unwrapPage(res);
|
||||
this.candidateRows = page.records;
|
||||
@@ -3930,20 +3917,12 @@ export default {
|
||||
this.candidateLoading = false;
|
||||
}
|
||||
},
|
||||
getCandidateTransportTypeQuery(value) {
|
||||
const normalized = String(value || '')
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
if (['road', '公路运输'].includes(normalized)) return 'road,公路运输';
|
||||
return value || '';
|
||||
},
|
||||
handleCandidateSearch() {
|
||||
this.candidatePage.currentPage = 1;
|
||||
this.loadCandidateWaybills();
|
||||
},
|
||||
handleCandidateReset() {
|
||||
this.candidateQuery = createCandidateSearchForm();
|
||||
if (this.dialogMode === 'add') this.candidateQuery.transportType = 'road';
|
||||
this.candidatePage.currentPage = 1;
|
||||
this.loadCandidateWaybills();
|
||||
},
|
||||
@@ -4005,8 +3984,31 @@ export default {
|
||||
const exists = new Set(
|
||||
this.selectedWaybillRows.map(row => String(row.id || row.waybillNo))
|
||||
);
|
||||
// 一张配载单的全部子运单必须同项目:以已选运单(无已选时以本批首张)的项目为准
|
||||
const anchorRow = [...this.selectedWaybillRows, ...selectedRows].find(row =>
|
||||
this.waybillProjectKey(row)
|
||||
);
|
||||
const anchorKey = anchorRow ? this.waybillProjectKey(anchorRow) : '';
|
||||
const mismatchedRows = anchorKey
|
||||
? selectedRows.filter(
|
||||
row => this.waybillProjectKey(row) && this.waybillProjectKey(row) !== anchorKey
|
||||
)
|
||||
: [];
|
||||
if (mismatchedRows.length) {
|
||||
const anchorName = anchorRow.projectName || anchorRow.projectId;
|
||||
const mismatchedText = mismatchedRows
|
||||
.map(
|
||||
row =>
|
||||
`${row.waybillNo || row.id}(项目:${row.projectName || row.projectId || '未知'})`
|
||||
)
|
||||
.join('、');
|
||||
this.$message.warning(
|
||||
`运单 ${mismatchedText} 与已选运单项目「${anchorName}」不一致,不能加入同一配载单`
|
||||
);
|
||||
}
|
||||
const nextRows = [...this.selectedWaybillRows];
|
||||
selectedRows.forEach(row => {
|
||||
if (mismatchedRows.includes(row)) return;
|
||||
const key = String(row.id || row.waybillNo);
|
||||
if (!exists.has(key)) {
|
||||
nextRows.push(row);
|
||||
@@ -4029,6 +4031,9 @@ export default {
|
||||
async addSelectedWaybills() {
|
||||
await this.addWaybillRows(this.candidateSelection);
|
||||
},
|
||||
waybillProjectKey(row = {}) {
|
||||
return String(row.projectId || row.projectName || '').trim();
|
||||
},
|
||||
removeSelectedWaybill(index) {
|
||||
const row = this.selectedWaybillRows[index];
|
||||
if (this.isSelectedWaybillRemoveLocked(row)) {
|
||||
@@ -4551,12 +4556,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) {
|
||||
@@ -4590,16 +4589,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 => ({
|
||||
@@ -4679,17 +4674,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;
|
||||
@@ -4720,10 +4711,9 @@ export default {
|
||||
}
|
||||
this.taskCarrierLoading = true;
|
||||
try {
|
||||
const projectIds = [
|
||||
...new Set(this.selectedWaybillRows.map(row => row.projectId).filter(Boolean)),
|
||||
];
|
||||
const response = await loadingApi.getCarrierContracts(projectIds);
|
||||
// 配载单只有一个项目,承运商合同也必须属于该项目
|
||||
const projectId = this.selectedWaybillRows.map(row => row.projectId).find(Boolean);
|
||||
const response = await loadingApi.getCarrierContracts(projectId ? [projectId] : []);
|
||||
if (requestId !== this.taskCarrierRequestId) return [];
|
||||
const contracts = response.data?.data || response.data || [];
|
||||
if (this.dialogForm.carrierType !== '自运') {
|
||||
|
||||
Reference in New Issue
Block a user