调整预结算、正式结算
This commit is contained in:
@@ -303,6 +303,7 @@
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="!routeMapSelected.longitude"
|
||||
:loading="routeMapConfirmLoading"
|
||||
@click="confirmRouteMapPick"
|
||||
>
|
||||
确定
|
||||
@@ -315,6 +316,7 @@
|
||||
<script>
|
||||
import * as api from '@/api/business/common-route';
|
||||
import { getList as getCommonAddressList } from '@/api/base/common-address';
|
||||
import { getDetail as getRegionDetail } from '@/api/base/region';
|
||||
import { exportBlob } from '@/api/common';
|
||||
import { getDeptTree } from '@/api/system/dept';
|
||||
import { addressTypeOptions } from '@/option/base/common-address';
|
||||
@@ -356,6 +358,7 @@ export default {
|
||||
routeMapVisible: false,
|
||||
routeMapTarget: '',
|
||||
routeMapLoading: false,
|
||||
routeMapConfirmLoading: false,
|
||||
routeMapKeyword: '',
|
||||
routeMapStatus: '可搜索地址或点击地图选点',
|
||||
routeMapSelected: {},
|
||||
@@ -496,14 +499,22 @@ export default {
|
||||
this.addressLoading = false;
|
||||
});
|
||||
},
|
||||
selectAddressRow(row) {
|
||||
async selectAddressRow(row) {
|
||||
if (!row) return;
|
||||
this.applyAddress(this.addressTarget, row);
|
||||
const applied = await this.applyAddress(this.addressTarget, row);
|
||||
if (!applied) return;
|
||||
this.addressDialogVisible = false;
|
||||
},
|
||||
applyAddress(target, address) {
|
||||
async applyAddress(target, address) {
|
||||
if (!target || !address) return;
|
||||
const prefix = target === 'departure' ? 'departure' : 'arrival';
|
||||
const regionIds = await this.resolveRegionIds(address.regionCode);
|
||||
if (!this.hasCompleteRegionIds(regionIds)) {
|
||||
this.$message.warning('该常用地址缺少完整的省、市、区ID,请先维护行政区划');
|
||||
return false;
|
||||
}
|
||||
this.applyRegionIds(prefix, regionIds);
|
||||
this.form[`${prefix}AddressId`] = address.id || '';
|
||||
this.form[`${prefix}Name`] = address.addressName || '';
|
||||
this.form[`${prefix}Address`] = address.detailAddress || '';
|
||||
this.form[`${prefix}AddressCode`] = address.addressCode || '';
|
||||
@@ -515,6 +526,7 @@ export default {
|
||||
this.form[`${prefix}Latitude`] = address.latitude || '';
|
||||
this.form[`${prefix}Contact`] = address.contactName || this.form[`${prefix}Contact`] || '';
|
||||
this.form[`${prefix}Phone`] = address.contactPhone || this.form[`${prefix}Phone`] || '';
|
||||
return true;
|
||||
},
|
||||
openRouteMapDialog(target) {
|
||||
if (this.dialogReadonly) return;
|
||||
@@ -526,6 +538,10 @@ export default {
|
||||
lat: this.form[`${prefix}Latitude`],
|
||||
address: this.form[`${prefix}Address`],
|
||||
regionName: this.form[`${prefix}Name`],
|
||||
regionCode: this.form[`${prefix}DistrictId`],
|
||||
provinceId: this.form[`${prefix}ProvinceId`],
|
||||
cityId: this.form[`${prefix}CityId`],
|
||||
districtId: this.form[`${prefix}DistrictId`],
|
||||
});
|
||||
this.routeMapStatus = this.routeMapSelected.longitude
|
||||
? '已加载当前选点,可重新选点'
|
||||
@@ -638,6 +654,7 @@ export default {
|
||||
...this.routeMapSelected,
|
||||
detailAddress: address.detailAddress || this.routeMapSelected.detailAddress,
|
||||
regionName: address.regionName || this.routeMapSelected.regionName,
|
||||
regionCode: address.regionCode || '',
|
||||
};
|
||||
this.routeMapKeyword = this.routeMapSelected.detailAddress || this.routeMapKeyword;
|
||||
this.routeMapStatus = this.routeMapSelected.detailAddress || '已选点,可确认回填';
|
||||
@@ -656,28 +673,90 @@ export default {
|
||||
this.routeAmapMarker.setMap(this.routeAmap);
|
||||
this.routeAmap.setCenter(point);
|
||||
},
|
||||
confirmRouteMapPick() {
|
||||
async confirmRouteMapPick() {
|
||||
if (!this.routeMapSelected.longitude) {
|
||||
this.$message.warning('请先搜索或点击地图完成选点');
|
||||
return;
|
||||
}
|
||||
const prefix = this.routeMapTarget;
|
||||
this.form[`${prefix}Address`] =
|
||||
this.routeMapSelected.detailAddress || this.form[`${prefix}Address`];
|
||||
this.form[`${prefix}Name`] = this.routeMapSelected.regionName || this.form[`${prefix}Name`];
|
||||
this.form[`${prefix}Longitude`] = this.routeMapSelected.longitude;
|
||||
this.form[`${prefix}Latitude`] = this.routeMapSelected.latitude;
|
||||
this.routeMapVisible = false;
|
||||
this.$refs.crud?.validateField?.(`${prefix}Address`);
|
||||
this.routeMapConfirmLoading = true;
|
||||
try {
|
||||
const regionIds = await this.resolveRegionIds(this.routeMapSelected.regionCode);
|
||||
if (!this.hasCompleteRegionIds(regionIds)) {
|
||||
this.$message.warning('当前选点未解析到完整的省、市、区ID,请重新选择地址');
|
||||
return;
|
||||
}
|
||||
this.applyRegionIds(prefix, regionIds);
|
||||
this.form[`${prefix}AddressId`] = '';
|
||||
this.form[`${prefix}AddressCode`] = '';
|
||||
this.form[`${prefix}SiteCode`] = '';
|
||||
this.form[`${prefix}Address`] =
|
||||
this.routeMapSelected.detailAddress || this.form[`${prefix}Address`];
|
||||
this.form[`${prefix}Name`] = this.routeMapSelected.regionName || this.form[`${prefix}Name`];
|
||||
this.form[`${prefix}Longitude`] = this.routeMapSelected.longitude;
|
||||
this.form[`${prefix}Latitude`] = this.routeMapSelected.latitude;
|
||||
this.routeMapVisible = false;
|
||||
this.$refs.crud?.validateField?.(`${prefix}Address`);
|
||||
} finally {
|
||||
this.routeMapConfirmLoading = false;
|
||||
}
|
||||
},
|
||||
buildRouteMapSelection({ lng, lat, address, regionName }) {
|
||||
buildRouteMapSelection({
|
||||
lng,
|
||||
lat,
|
||||
address,
|
||||
regionName,
|
||||
regionCode,
|
||||
provinceId,
|
||||
cityId,
|
||||
districtId,
|
||||
}) {
|
||||
return {
|
||||
longitude: this.formatCoordinate(lng),
|
||||
latitude: this.formatCoordinate(lat),
|
||||
detailAddress: address || '',
|
||||
regionName: regionName || '',
|
||||
regionCode: regionCode || '',
|
||||
provinceId: provinceId || '',
|
||||
cityId: cityId || '',
|
||||
districtId: districtId || '',
|
||||
};
|
||||
},
|
||||
applyRegionIds(prefix, regionIds = {}) {
|
||||
this.form[`${prefix}ProvinceId`] = regionIds.provinceId || '';
|
||||
this.form[`${prefix}CityId`] = regionIds.cityId || '';
|
||||
this.form[`${prefix}DistrictId`] = regionIds.districtId || '';
|
||||
},
|
||||
hasCompleteRegionIds(regionIds = {}) {
|
||||
return Boolean(regionIds.provinceId && regionIds.cityId && regionIds.districtId);
|
||||
},
|
||||
fallbackRegionIds(regionCode) {
|
||||
const code = String(regionCode || '').trim();
|
||||
if (!/^\d{6}$/.test(code)) {
|
||||
return { provinceId: '', cityId: '', districtId: '' };
|
||||
}
|
||||
return {
|
||||
provinceId: `${code.slice(0, 2)}0000`,
|
||||
cityId: `${code.slice(0, 4)}00`,
|
||||
districtId: code,
|
||||
};
|
||||
},
|
||||
async resolveRegionIds(regionCode) {
|
||||
const fallback = this.fallbackRegionIds(regionCode);
|
||||
if (!regionCode) return fallback;
|
||||
try {
|
||||
const res = await getRegionDetail(regionCode);
|
||||
const region = res.data.data || {};
|
||||
return {
|
||||
provinceId: String(region.provinceCode || fallback.provinceId || ''),
|
||||
cityId: String(region.cityCode || fallback.cityId || ''),
|
||||
districtId: String(region.districtCode || region.code || fallback.districtId || ''),
|
||||
};
|
||||
} catch (error) {
|
||||
window.console.log(error);
|
||||
return fallback;
|
||||
}
|
||||
},
|
||||
formatCoordinate(value) {
|
||||
if (value === undefined || value === null || value === '') return '';
|
||||
const numberValue = Number(value);
|
||||
@@ -754,6 +833,7 @@ export default {
|
||||
return {
|
||||
detailAddress: regeocode.formattedAddress || '',
|
||||
regionName: [component.province, city, component.district].filter(Boolean).join(''),
|
||||
regionCode: component.adcode || '',
|
||||
};
|
||||
},
|
||||
normalizeRow(row) {
|
||||
|
||||
@@ -5158,6 +5158,7 @@ const standaloneBusinessFormPaths = [
|
||||
...Object.keys(standaloneBusinessFormRoutes),
|
||||
...Object.values(standaloneBusinessFormRoutes),
|
||||
];
|
||||
const loadingCreateWaybillsStorageKey = 'loading-manage-create-waybills';
|
||||
|
||||
const attachmentViewerPlugins = [
|
||||
imagePlugin(),
|
||||
@@ -12779,28 +12780,41 @@ export default {
|
||||
this.$message.warning('请选择至少一条数据');
|
||||
return;
|
||||
}
|
||||
const nonRoadWaybills = this.selectionList.filter(row => {
|
||||
const transportType = String(row.transportType || '').trim();
|
||||
return transportType !== '公路运输' && transportType.toLowerCase() !== 'road';
|
||||
});
|
||||
const nonRoadWaybills = this.selectionList.filter(row => !this.waybillIsRoadTransport(row));
|
||||
if (nonRoadWaybills.length) {
|
||||
this.$message.warning('公路配置仅支持运输方式为“公路运输”的运单');
|
||||
this.$message.warning('公路配载仅支持运输方式为“公路运输”的运单');
|
||||
return;
|
||||
}
|
||||
if (typeof this.api.roadLoading !== 'function') {
|
||||
this.$message.warning('公路配载功能暂未配置');
|
||||
const unavailableWaybills = this.selectionList.filter(
|
||||
row =>
|
||||
this.statusValue(row) !== 'pending' ||
|
||||
row.loadingId ||
|
||||
row.loadingManageId ||
|
||||
row.loadingNo
|
||||
);
|
||||
if (unavailableWaybills.length) {
|
||||
this.$message.warning('公路配载仅支持进行中且未配载的运单');
|
||||
return;
|
||||
}
|
||||
this.$confirm('确定对选中的运单进行公路配载?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => this.api.roadLoading(this.ids))
|
||||
.then(() => {
|
||||
this.$message.success('公路配载成功');
|
||||
this.onLoad(this.page, this.query);
|
||||
});
|
||||
try {
|
||||
sessionStorage.setItem(
|
||||
loadingCreateWaybillsStorageKey,
|
||||
JSON.stringify({
|
||||
source: 'waybill-manage',
|
||||
rows: this.selectionList,
|
||||
})
|
||||
);
|
||||
} catch (error) {
|
||||
this.$message.error('暂存待配载运单失败,请重试');
|
||||
return;
|
||||
}
|
||||
this.$router.push({
|
||||
path: '/business/loading-manage/form',
|
||||
query: {
|
||||
mode: 'add',
|
||||
name: '新增配载管理',
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -635,8 +635,11 @@ export default {
|
||||
editPending(item) {
|
||||
const route = this.routes.find(routeItem => routeItem.segmentNo === item.segmentNo);
|
||||
if (!route) return;
|
||||
const sourceIndex = (this.master.goods || []).findIndex(goods => goods.cargoName === item.cargoName && goods.cargoType === item.cargoType);
|
||||
let goods = route.goods.find(goodsItem => goodsItem.cargoName === item.cargoName && goodsItem.cargoType === item.cargoType);
|
||||
const itemSourceIndex = Number(item.sourceIndex);
|
||||
const sourceIndex = Number.isInteger(itemSourceIndex) && itemSourceIndex >= 0
|
||||
? itemSourceIndex
|
||||
: (this.master.goods || []).findIndex(goods => goods.cargoName === item.cargoName && goods.cargoType === item.cargoType);
|
||||
let goods = route.goods.find(goodsItem => String(goodsItem.sourceIndex) === String(sourceIndex));
|
||||
if (!goods && sourceIndex >= 0) {
|
||||
goods = this.createGoodsRow(this.master.goods[sourceIndex], sourceIndex);
|
||||
route.goods.push(goods);
|
||||
@@ -646,8 +649,9 @@ export default {
|
||||
this.syncFreightItems(route);
|
||||
const freightItem = this.freightItemsForGoods(route, goods);
|
||||
if (freightItem) { freightItem.unitPrice = item.unitPrice || ''; freightItem.priceUnit = item.priceUnit || freightItem.priceUnit; }
|
||||
this.editingId = item.id;
|
||||
this.removePending(item.id);
|
||||
this.editingId = item.id;
|
||||
route.selected = true;
|
||||
this.$nextTick(() => document.querySelector(`[data-segment="${item.segmentNo}"]`)?.scrollIntoView({ behavior: 'smooth', block: 'start' }));
|
||||
},
|
||||
freightItemsForGoods(route, goods) {
|
||||
|
||||
@@ -907,7 +907,8 @@ export default {
|
||||
async loadContracts(projectId, selectFirst = true) {
|
||||
const response = await api.getProjectContracts(projectId);
|
||||
this.contracts = this.responseRecords(response).filter(
|
||||
item => String(item.projectId) === String(projectId)
|
||||
item =>
|
||||
String(item.projectId) === String(projectId) && item.contractCategory === '客户合同'
|
||||
);
|
||||
if (selectFirst) {
|
||||
const first = this.contracts[0];
|
||||
|
||||
@@ -1002,6 +1002,7 @@ const defaultTransportType = '';
|
||||
const defaultCandidateTransportType = '';
|
||||
const AMAP_KEY = '653b7cf105ad7fb8ec9b2f5198ade315';
|
||||
const AMAP_SECURITY_CODE = '5aab65c632e48ebae0d0e28f5b28e21a';
|
||||
const loadingCreateWaybillsStorageKey = 'loading-manage-create-waybills';
|
||||
let detailAmapLoader;
|
||||
|
||||
const createSearchForm = () => ({
|
||||
@@ -1111,6 +1112,18 @@ const parseJsonArray = value => {
|
||||
}
|
||||
};
|
||||
|
||||
const parseIdJsonArray = value => {
|
||||
if (Array.isArray(value)) return value.map(id => String(id));
|
||||
if (typeof value !== 'string' || !value.trim()) return [];
|
||||
try {
|
||||
const normalizedValue = value.replace(/(^\s*\[\s*|,\s*)(-?\d{16,})(\s*(?=,|\]))/g, '$1"$2"$3');
|
||||
const result = JSON.parse(normalizedValue);
|
||||
return Array.isArray(result) ? result.map(id => String(id)) : [];
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
const uniqueText = (rows, prop) =>
|
||||
[
|
||||
...new Set(
|
||||
@@ -1361,7 +1374,7 @@ export default {
|
||||
if (linkedRows[index]?.id || linkedRows[index]?.waybillId) {
|
||||
return linkedRows[index].id || linkedRows[index].waybillId;
|
||||
}
|
||||
const ids = parseJsonArray(row.waybillIdsJson);
|
||||
const ids = parseIdJsonArray(row.waybillIdsJson);
|
||||
return ids[index] || '';
|
||||
},
|
||||
async openWaybillDetail(row = {}) {
|
||||
@@ -1545,11 +1558,25 @@ export default {
|
||||
};
|
||||
actionMap[type]?.();
|
||||
},
|
||||
initStandaloneFormPage() {
|
||||
async initStandaloneFormPage() {
|
||||
if (!this.isStandaloneFormPage) return;
|
||||
this.openLoadingDialog(this.$route.query.mode === 'edit' ? 'edit' : 'add', {
|
||||
const mode = this.$route.query.mode === 'edit' ? 'edit' : 'add';
|
||||
await this.openLoadingDialog(mode, {
|
||||
id: this.$route.query.id,
|
||||
});
|
||||
if (mode === 'add') await this.consumeLoadingCreateWaybills();
|
||||
},
|
||||
async consumeLoadingCreateWaybills() {
|
||||
const raw = sessionStorage.getItem(loadingCreateWaybillsStorageKey);
|
||||
if (!raw) return;
|
||||
sessionStorage.removeItem(loadingCreateWaybillsStorageKey);
|
||||
try {
|
||||
const payload = JSON.parse(raw);
|
||||
if (payload?.source !== 'waybill-manage' || !Array.isArray(payload.rows)) return;
|
||||
await this.addWaybillRows(payload.rows);
|
||||
} catch (error) {
|
||||
ElMessage.warning('待配载运单数据读取失败,请重新选择');
|
||||
}
|
||||
},
|
||||
async openLoadingDialog(mode, row) {
|
||||
if (['add', 'edit'].includes(mode) && !this.isStandaloneFormPage) {
|
||||
@@ -1863,7 +1890,7 @@ export default {
|
||||
}
|
||||
},
|
||||
async restoreWaybillRows(idsJson, loadingSubNos) {
|
||||
const ids = parseJsonArray(idsJson).filter(Boolean);
|
||||
const ids = parseIdJsonArray(idsJson).filter(Boolean);
|
||||
if (ids.length) {
|
||||
const rows = await Promise.all(
|
||||
ids.map(id =>
|
||||
@@ -1927,11 +1954,13 @@ export default {
|
||||
candidateSelectionChange(rows) {
|
||||
this.candidateSelection = rows || [];
|
||||
},
|
||||
async addSelectedWaybills() {
|
||||
async addWaybillRows(rows = []) {
|
||||
const waybillRows = Array.isArray(rows) ? rows.filter(Boolean) : [];
|
||||
if (!waybillRows.length) return;
|
||||
this.candidateAdding = true;
|
||||
try {
|
||||
const selectedRows = await Promise.all(
|
||||
this.candidateSelection.map(async row => {
|
||||
waybillRows.map(async row => {
|
||||
if (!row.id) return row;
|
||||
try {
|
||||
const res = await getWaybillDetail(row.id);
|
||||
@@ -1961,6 +1990,9 @@ export default {
|
||||
this.candidateAdding = false;
|
||||
}
|
||||
},
|
||||
async addSelectedWaybills() {
|
||||
await this.addWaybillRows(this.candidateSelection);
|
||||
},
|
||||
removeSelectedWaybill(index) {
|
||||
this.selectedWaybillRows.splice(index, 1);
|
||||
this.rebuildSummaryFromWaybills();
|
||||
@@ -1972,7 +2004,12 @@ export default {
|
||||
.map(row => row.waybillNo)
|
||||
.filter(Boolean)
|
||||
.join(',');
|
||||
this.dialogForm.waybillIdsJson = JSON.stringify(rows.map(row => row.id).filter(Boolean));
|
||||
this.dialogForm.waybillIdsJson = JSON.stringify(
|
||||
rows
|
||||
.map(row => row.id)
|
||||
.filter(Boolean)
|
||||
.map(id => String(id))
|
||||
);
|
||||
this.dialogForm.projectName = uniqueText(rows, 'projectName');
|
||||
this.dialogForm.customerName = uniqueText(rows, 'customerName');
|
||||
this.dialogForm.originalNo = uniqueText(rows, 'originalNo');
|
||||
|
||||
Reference in New Issue
Block a user