Merge remote-tracking branch 'origin/master' into feature/hcs-api-p0-web

# Conflicts:
#	src/views/business/contract-manage-change.vue
This commit is contained in:
刘泉佳
2026-10-23 19:20:12 +08:00
27 changed files with 1924 additions and 572 deletions
@@ -13824,13 +13824,13 @@ export default {
}
const unavailableWaybills = this.selectionList.filter(
row =>
this.statusValue(row) !== 'pending' ||
!['pending', 'processing', 'running'].includes(this.statusValue(row)) ||
row.loadingId ||
row.loadingManageId ||
row.loadingNo
);
if (unavailableWaybills.length) {
this.$message.warning('公路配载仅支持进行中且未配载的运单');
this.$message.warning('公路配载仅支持待执行/进行中且未关联有效配载单的运单');
return;
}
try {
@@ -94,7 +94,7 @@
<div class="route-node-form">
<el-form-item label="途经地" required class="route-address-form-item"
><div class="route-address-inputs"
><el-input v-if="isNonRoadAddress(`route-${index}`)" v-model="route.departureName" class="route-address-name" readonly :disabled="isBasicRouteReadonly || !route.transportType" placeholder="请先选择运输方式" /><el-cascader v-else v-model="addressRegionPaths[`route-${index}`]" class="route-address-name" :options="regionOptions" :props="regionCascaderProps" :loading="regionLoading" :disabled="isBasicRouteReadonly || !route.transportType" placeholder="请选择省市区" clearable filterable @visible-change="visible => visible && loadRegionOptions()" @change="value => handleAddressRegionChange(`route-${index}`, value)" /><el-input v-model="route.departureAddress" class="route-address-detail" readonly :disabled="isBasicRouteReadonly || !route.transportType" placeholder="请先选择运输方式" @click="handleAddressDetailClick(`route-${index}`)" /><el-tooltip content="选择常用地址" placement="top"><el-button class="address-picker-button" type="primary" link :icon="OfficeBuilding" :disabled="isBasicRouteReadonly || !route.transportType" @click="openCommonAddress(`route-${index}`)" /></el-tooltip></div
><el-input v-if="isNonRoadAddress(`route-${index}`)" v-model="route.departureName" class="route-address-name" readonly :disabled="isBasicRouteReadonly" placeholder="请选择站点" /><el-cascader v-else v-model="addressRegionPaths[`route-${index}`]" class="route-address-name" :options="regionOptions" :props="regionCascaderProps" :loading="regionLoading" :disabled="isBasicRouteReadonly" placeholder="请选择省市区" clearable filterable @visible-change="visible => visible && loadRegionOptions()" @change="value => handleAddressRegionChange(`route-${index}`, value)" /><el-input v-model="route.departureAddress" class="route-address-detail" readonly :disabled="isBasicRouteReadonly" placeholder="请输入详细地址" @click="handleAddressDetailClick(`route-${index}`)" /><el-tooltip content="选择常用地址" placement="top"><el-button class="address-picker-button" type="primary" link :icon="OfficeBuilding" :disabled="isBasicRouteReadonly" @click="openCommonAddress(`route-${index}`)" /></el-tooltip></div
></el-form-item>
<el-form-item label="联系人" class="route-contact-form-item"><el-input v-model="route.departureContact" :disabled="isBasicRouteReadonly" placeholder="请输入" /></el-form-item>
<el-form-item label="联系方式" class="route-phone-form-item"><div class="route-contact-actions"><el-input v-model="route.departurePhone" :disabled="isBasicRouteReadonly" placeholder="请输入" /><template v-if="!isBasicRouteReadonly"><el-tooltip v-if="index === form.routes.length - 1" content="新增途经点" placement="top"><el-button class="route-action-button" type="primary" link @click="addRoute"><el-icon><CirclePlus /></el-icon></el-button></el-tooltip><el-tooltip content="删除途经点" placement="top"><el-button class="route-action-button" type="danger" link @click="removeRoute(index)"><el-icon><Remove /></el-icon></el-button></el-tooltip></template></div></el-form-item>
@@ -111,7 +111,7 @@
<div class="route-node-form">
<el-form-item label="收货地" required class="route-address-form-item"
><div class="route-address-inputs"
><el-input v-if="isNonRoadAddress('arrival')" v-model="form.arrivalName" class="route-address-name" readonly :disabled="isBasicRouteReadonly || !form.finalTransportType" placeholder="请先选择运输方式" /><el-cascader v-else v-model="addressRegionPaths.arrival" class="route-address-name" :options="regionOptions" :props="regionCascaderProps" :loading="regionLoading" :disabled="isBasicRouteReadonly || !form.finalTransportType" placeholder="请选择省市区" clearable filterable @visible-change="visible => visible && loadRegionOptions()" @change="value => handleAddressRegionChange('arrival', value)" /><el-input v-model="form.arrivalAddress" class="route-address-detail" readonly :disabled="isBasicRouteReadonly || !form.finalTransportType" placeholder="请先选择运输方式" @click="handleAddressDetailClick('arrival')" /><el-tooltip content="选择常用地址" placement="top"><el-button class="address-picker-button" type="primary" link :icon="OfficeBuilding" :disabled="isBasicRouteReadonly || !form.finalTransportType" @click="openCommonAddress('arrival')" /></el-tooltip></div
><el-input v-if="isNonRoadAddress('arrival')" v-model="form.arrivalName" class="route-address-name" readonly :disabled="isBasicRouteReadonly" placeholder="请选择站点" /><el-cascader v-else v-model="addressRegionPaths.arrival" class="route-address-name" :options="regionOptions" :props="regionCascaderProps" :loading="regionLoading" :disabled="isBasicRouteReadonly" placeholder="请选择省市区" clearable filterable @visible-change="visible => visible && loadRegionOptions()" @change="value => handleAddressRegionChange('arrival', value)" /><el-input v-model="form.arrivalAddress" class="route-address-detail" readonly :disabled="isBasicRouteReadonly" placeholder="请输入详细地址" @click="handleAddressDetailClick('arrival')" /><el-tooltip content="选择常用地址" placement="top"><el-button class="address-picker-button" type="primary" link :icon="OfficeBuilding" :disabled="isBasicRouteReadonly" @click="openCommonAddress('arrival')" /></el-tooltip></div
></el-form-item>
<el-form-item label="联系人" class="route-contact-form-item"
><el-input v-model="form.arrivalContact" :disabled="isBasicRouteReadonly" placeholder="请输入" /></el-form-item>
@@ -714,7 +714,7 @@ export default {
'msg',
'zip',
],
transports: ['公路运输', '铁路运输', '水路运输', '航空运输'],
transports: ['铁路运输', '水路运输', '航空运输', '公路运输'],
quantityUnitOptions: [],
quantityUnitLoading: false,
form: {
@@ -798,6 +798,7 @@ export default {
methods: {
formatContractOptionLabel,
defaultQuantityUnit() {
if (this.quantityUnitOptions.includes('吨')) return '吨';
return this.quantityUnitOptions[0] || '吨';
},
loadQuantityUnitOptions() {
@@ -1164,22 +1165,30 @@ export default {
const field = this.addressModel(target);
if (!field) return false;
const siteCode = String(field.model[field.siteCode] || '').trim();
// 地址展示模式由实际选择的数据决定:有站点编码表示非公路站点名称,
// 没有站点编码则保留省市区级联,避免切换运输方式时改写已有地址。
// 展示模式由已选数据决定:有站点编码则显示站点名,否则省市区;暂不按运输方式强制站点限制。
return Boolean(siteCode && siteCode !== '/');
},
hasAddressValue(target) {
const field = this.addressModel(target);
if (!field) return false;
return Boolean(
String(field.model[field.address] || '').trim() || String(field.model[field.name] || '').trim()
);
},
tipEmptyAddressDetail(target) {
// 替代原「请先选择运输方式」placeholder:空地址点击时 toast,已有值不再提示。
if (!this.hasAddressValue(target)) {
this.$message.warning('请输入详细地址');
}
},
resolveAddressRegionCode(row = {}) {
return row.regionCode || row.districtCode || row.areaCode || row.adcode || '';
},
openCommonAddress(target) {
if (this.isBasicRouteReadonly) return;
this.tipEmptyAddressDetail(target);
this.addressTarget = target;
if (this.addressTransportMode(target) !== 'road') {
this.stationQuery = {};
this.stationPage.current = 1;
this.stationDialogVisible = true;
return;
}
// 暂不按运输方式限制站点:统一走常用地址选择。
this.addressQuery = {};
this.addressPage.current = 1;
this.addressDialogVisible = true;
@@ -1279,18 +1288,11 @@ export default {
},
handleAddressDetailClick(target) {
if (this.isBasicRouteReadonly) return;
if (this.addressTransportMode(target) !== 'road') {
this.openCommonAddress(target);
return;
}
this.tipEmptyAddressDetail(target);
this.openAddressMap(target);
},
openAddressMap(target) {
if (this.isBasicRouteReadonly) return;
if (this.addressTransportMode(target) !== 'road') {
this.$message.info('非公路运输地址不能使用地图选择');
return;
}
const field = this.addressModel(target);
if (!field) return;
this.mapTarget = target;
@@ -1690,7 +1692,11 @@ export default {
'',
cargoTypePath,
quantity: row.quantity || '',
quantityUnit: row.quantityUnit || this.defaultQuantityUnit(),
// 常用货物单位若为空或「个」,新建总单统一默认「吨」
quantityUnit:
!row.quantityUnit || String(row.quantityUnit).trim() === '个'
? this.defaultQuantityUnit()
: row.quantityUnit,
packageType: row.packageType || row.package || '',
brand: row.brand || '',
specification: row.specification || row.spec || '',
@@ -1775,17 +1781,21 @@ export default {
return formatUpdateUserName(row);
},
selectRoute(route) {
// 先写入运输方式(会触发地点清空),再回填线路地址,避免被清空逻辑覆盖。
this.form.finalTransportType = '公路运输';
if (!this.form.routes.length) this.addRoute();
if (this.form.routes[0]) this.form.routes[0].transportType = '公路运输';
this.form.departureName = route.departureName || '';
this.form.departureAddress = route.departureAddress || '';
this.form.departureContact = route.departureContact || '';
this.form.departurePhone = route.departurePhone || '';
this.form.departureSiteCode = '';
this.form.arrivalName = route.arrivalName || '';
this.form.arrivalAddress = route.arrivalAddress || '';
this.form.arrivalContact = route.arrivalContact || '';
this.form.arrivalPhone = route.arrivalPhone || '';
this.form.arrivalSiteCode = '';
this.syncAddressRegionPaths();
this.form.finalTransportType = '公路运输';
if (!this.form.routes.length) this.addRoute();
this.routeDialogVisible = false;
},
createRoute(index = this.form.routes.length) {
@@ -1591,8 +1591,8 @@
<el-link type="primary" v-if="canCancel(row)" @click="handleAction('cancel', row)">
取消
</el-link>
<el-link type="primary" v-if="canComplete(row)" @click="handleAction('complete', row)">
{{ completeActionLabel }}
<el-link type="primary" v-if="canComplete(row)" @click="handleCompleteAction(row)">
{{ completeActionLabelFor(row) }}
</el-link>
<el-link type="primary" v-if="canMaintainMileage(row)" @click="openMileageDialog(row)">
维护里程
@@ -5111,7 +5111,29 @@ export default {
return false;
}
const status = this.statusValue(row);
return status === 'processing' || status === 'running';
return status === 'processing' || status === 'running' || status === 'pending_return';
},
completeActionLabelFor(row) {
return this.statusValue(row) === 'pending_return' ? '确认回单' : this.completeActionLabel;
},
handleCompleteAction(row) {
const isPendingReturn = this.statusValue(row) === 'pending_return';
const actionName = this.completeActionLabelFor(row);
this.$confirm(`确定${actionName}该${this.config.title}?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
if (isPendingReturn && typeof this.api.confirmReturn === 'function') {
return this.api.confirmReturn(row.id);
}
return this.api.complete(row.id);
})
.then(() => {
this.$message.success(`${actionName}成功`);
this.onLoad(this.page, this.query);
});
},
canMaintainMileage(row) {
return (
@@ -6543,6 +6565,9 @@ export default {
if (status === 'completed') {
return 'primary';
}
if (status === 'pending_return') {
return 'warning';
}
return 'warning';
},
normalizeRow(row, saveAsDraft = false) {
@@ -10356,7 +10381,14 @@ export default {
this.$message.warning('请选择至少一条数据');
return;
}
this.$confirm('确定完成选中的运单?', '提示', {
const pendingReturnCount = this.selectionList.filter(
row => this.statusValue(row) === 'pending_return'
).length;
const tip =
pendingReturnCount > 0
? `确定完成选中的运单?其中 ${pendingReturnCount} 条为待确认回单,确认后将转为已完成。`
: '确定完成选中的运单?';
this.$confirm(tip, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
@@ -10382,13 +10414,13 @@ export default {
}
const unavailableWaybills = this.selectionList.filter(
row =>
!['processing', 'running'].includes(this.statusValue(row)) ||
!['pending', 'processing', 'running'].includes(this.statusValue(row)) ||
row.loadingId ||
row.loadingManageId ||
row.loadingNo
);
if (unavailableWaybills.length) {
this.$message.warning('公路配载仅支持进行中且未配载的运单');
this.$message.warning('公路配载仅支持待执行/进行中且未关联有效配载单的运单');
return;
}
try {