调整业务模块
This commit is contained in:
@@ -152,10 +152,7 @@
|
||||
@click="handleTransportSecondaryAddressInputClick('departure')"
|
||||
>
|
||||
<template #suffix>
|
||||
<el-icon
|
||||
v-if="!transportStationMode"
|
||||
@click.stop="openTransportMapDialog('departure')"
|
||||
>
|
||||
<el-icon @click.stop="openTransportMapDialog('departure')">
|
||||
<Location />
|
||||
</el-icon>
|
||||
</template>
|
||||
@@ -198,7 +195,7 @@
|
||||
@click="handleTransportSecondaryAddressInputClick('arrival')"
|
||||
>
|
||||
<template #suffix>
|
||||
<el-icon v-if="!transportStationMode" @click.stop="openTransportMapDialog('arrival')">
|
||||
<el-icon @click.stop="openTransportMapDialog('arrival')">
|
||||
<Location />
|
||||
</el-icon>
|
||||
</template>
|
||||
@@ -559,9 +556,15 @@
|
||||
label-width="auto"
|
||||
class="shipping-template-page__detail-form shipping-template-page__detail-grid"
|
||||
>
|
||||
<el-form-item label="模板编号"><span>{{ detailRow.templateCode || '-' }}</span></el-form-item>
|
||||
<el-form-item label="模板名称"><span>{{ detailRow.templateName || '-' }}</span></el-form-item>
|
||||
<el-form-item label="模板类型"><span>{{ detailRow.templateType || '-' }}</span></el-form-item>
|
||||
<el-form-item label="模板编号"
|
||||
><span>{{ detailRow.templateCode || '-' }}</span></el-form-item
|
||||
>
|
||||
<el-form-item label="模板名称"
|
||||
><span>{{ detailRow.templateName || '-' }}</span></el-form-item
|
||||
>
|
||||
<el-form-item label="模板类型"
|
||||
><span>{{ detailRow.templateType || '-' }}</span></el-form-item
|
||||
>
|
||||
<el-form-item label="备注" class="shipping-template-page__detail-form-wide">
|
||||
<span>{{ detailRow.remark || '-' }}</span>
|
||||
</el-form-item>
|
||||
@@ -575,10 +578,16 @@
|
||||
label-width="auto"
|
||||
class="shipping-template-page__detail-form shipping-template-page__detail-grid"
|
||||
>
|
||||
<el-form-item label="项目"><span>{{ detailRow.projectName || '-' }}</span></el-form-item>
|
||||
<el-form-item label="客户合同"><span>{{ detailRow.contractName || '-' }}</span></el-form-item>
|
||||
<el-form-item label="项目"
|
||||
><span>{{ detailRow.projectName || '-' }}</span></el-form-item
|
||||
>
|
||||
<el-form-item label="客户合同"
|
||||
><span>{{ detailRow.contractName || '-' }}</span></el-form-item
|
||||
>
|
||||
<el-form-item label="运输方式">
|
||||
<span>{{ getTransportTypeLabel(detailRow.transportType) || detailRow.transportType || '-' }}</span>
|
||||
<span>{{
|
||||
getTransportTypeLabel(detailRow.transportType) || detailRow.transportType || '-'
|
||||
}}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" class="shipping-template-page__detail-form-wide">
|
||||
<span>{{ detailRow.basicRemark || '-' }}</span>
|
||||
@@ -588,7 +597,11 @@
|
||||
|
||||
<section class="shipping-template-page__detail-section">
|
||||
<div class="dialog-section-title">收发货信息</div>
|
||||
<el-form label-position="right" label-width="auto" class="shipping-template-page__detail-form">
|
||||
<el-form
|
||||
label-position="right"
|
||||
label-width="auto"
|
||||
class="shipping-template-page__detail-form"
|
||||
>
|
||||
<el-form-item label="发货地址">
|
||||
<div class="shipping-template-page__detail-route-values">
|
||||
<span>{{ detailRow.departureName || '-' }}</span>
|
||||
@@ -617,11 +630,21 @@
|
||||
<el-table-column prop="cargoName" label="货物名称" min-width="220" align="center" />
|
||||
<el-table-column prop="packageType" label="包装" min-width="120" align="center" />
|
||||
<el-table-column prop="quantity" label="数量" min-width="120" align="center" />
|
||||
<el-table-column prop="quantityUnit" label="数量单位" min-width="120" align="center" />
|
||||
<el-table-column
|
||||
prop="quantityUnit"
|
||||
label="数量单位"
|
||||
min-width="120"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column prop="brand" label="品牌" min-width="120" align="center" />
|
||||
<el-table-column prop="specification" label="规格" min-width="120" align="center" />
|
||||
<el-table-column prop="model" label="型号" min-width="120" align="center" />
|
||||
<el-table-column prop="materialCode" label="物料编码" min-width="140" align="center" />
|
||||
<el-table-column
|
||||
prop="materialCode"
|
||||
label="物料编码"
|
||||
min-width="140"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column prop="deviceCode" label="设备编码" min-width="140" align="center" />
|
||||
<el-table-column prop="remark" label="备注" min-width="160" align="center" />
|
||||
</el-table>
|
||||
@@ -638,11 +661,16 @@
|
||||
label-width="auto"
|
||||
:class="[
|
||||
'shipping-template-page__freight-form',
|
||||
`shipping-template-page__freight-form--${detailTransportMode === 'road' ? 'road' : 'non-road'}`,
|
||||
`shipping-template-page__freight-form--${
|
||||
detailTransportMode === 'road' ? 'road' : 'non-road'
|
||||
}`,
|
||||
]"
|
||||
>
|
||||
<template v-if="detailTransportMode === 'road'">
|
||||
<template v-for="(item, index) in detailFreightItems" :key="item.quantityUnit || index">
|
||||
<template
|
||||
v-for="(item, index) in detailFreightItems"
|
||||
:key="item.quantityUnit || index"
|
||||
>
|
||||
<el-form-item label="单价">
|
||||
<el-input :model-value="item.unitPrice || '-'" disabled>
|
||||
<template #append>{{ item.priceUnit || '-' }}</template>
|
||||
@@ -690,7 +718,9 @@
|
||||
<el-table-column type="index" label="序号" width="70" />
|
||||
<el-table-column label="文件名" min-width="220">
|
||||
<template #default="{ row }">
|
||||
<el-link type="primary" @click="previewAttachment(row)">{{ attachmentName(row) }}</el-link>
|
||||
<el-link type="primary" @click="previewAttachment(row)">{{
|
||||
attachmentName(row)
|
||||
}}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="附件描述" min-width="220">
|
||||
@@ -901,7 +931,8 @@
|
||||
><el-button @click="transportMapBox = false">取消</el-button
|
||||
><el-button
|
||||
type="primary"
|
||||
:disabled="!transportMapSelected.longitude"
|
||||
:loading="transportMapLoading"
|
||||
:disabled="!transportMapSelected.detailAddress || !transportMapSelected.regionName"
|
||||
@click="confirmTransportMapPick"
|
||||
>确定</el-button
|
||||
></template
|
||||
@@ -1410,10 +1441,7 @@ export default {
|
||||
return this.parseJsonArray(this.detailRow.goodsJson);
|
||||
},
|
||||
detailCargoQuantityTotal() {
|
||||
const total = this.detailGoodsRows.reduce(
|
||||
(sum, row) => sum + (Number(row.quantity) || 0),
|
||||
0
|
||||
);
|
||||
const total = this.detailGoodsRows.reduce((sum, row) => sum + (Number(row.quantity) || 0), 0);
|
||||
return total ? String(Number(total.toFixed(3))) : '系统自动计算';
|
||||
},
|
||||
detailAttachmentRows() {
|
||||
@@ -1433,9 +1461,7 @@ export default {
|
||||
return this.resolveTransportMode(this.detailRow.transportType);
|
||||
},
|
||||
detailFreightItems() {
|
||||
return Array.isArray(this.detailFreight.freightItems)
|
||||
? this.detailFreight.freightItems
|
||||
: [];
|
||||
return Array.isArray(this.detailFreight.freightItems) ? this.detailFreight.freightItems : [];
|
||||
},
|
||||
detailFreightTotal() {
|
||||
const storedTotal = Number(this.detailFreight.totalFreightAmount);
|
||||
@@ -1970,6 +1996,7 @@ export default {
|
||||
this.contractLoading = true;
|
||||
getContractList(1, 9999, {
|
||||
projectId: this.form.projectId,
|
||||
projectName: this.form.projectName,
|
||||
...(this.config.contractQueryParams || {}),
|
||||
})
|
||||
.then(res => {
|
||||
@@ -2239,6 +2266,9 @@ 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`] || '';
|
||||
this.$nextTick(() => {
|
||||
this.$refs.crud?.clearValidate?.([`${prefix}Address`]);
|
||||
});
|
||||
},
|
||||
openTransportStationDialog(target) {
|
||||
if (!this.form.transportType) return this.$message.warning('请先选择运输方式');
|
||||
@@ -2299,8 +2329,19 @@ export default {
|
||||
},
|
||||
openTransportMapDialog(target) {
|
||||
if (this.dialogReadonly || !this.form.transportType) return;
|
||||
this.transportMapTarget = target;
|
||||
this.transportMapKeyword = this.form[`${target}Address`] || '';
|
||||
const prefix = target === 'departure' ? 'departure' : 'arrival';
|
||||
this.transportMapTarget = prefix;
|
||||
this.transportMapKeyword = this.form[`${prefix}Address`] || this.form[`${prefix}Name`] || '';
|
||||
this.transportMapSelected = this.buildTransportMapSelection({
|
||||
longitude: this.form[`${prefix}Longitude`],
|
||||
latitude: this.form[`${prefix}Latitude`],
|
||||
detailAddress: this.form[`${prefix}Address`],
|
||||
regionName: this.form[`${prefix}Name`],
|
||||
addressCode: this.form[`${prefix}AddressCode`],
|
||||
});
|
||||
this.transportMapStatus = this.transportMapSelected.longitude
|
||||
? '已加载当前选点,可重新选点'
|
||||
: '可搜索地址或点击地图选点';
|
||||
this.transportMapBox = true;
|
||||
},
|
||||
loadAmap() {
|
||||
@@ -2310,8 +2351,9 @@ export default {
|
||||
window._AMapSecurityConfig = { securityJsCode: AMAP_SECURITY_CODE };
|
||||
const script = document.createElement('script');
|
||||
script.src = `https://webapi.amap.com/maps?v=2.0&key=${AMAP_KEY}`;
|
||||
script.async = true;
|
||||
script.onload = resolve;
|
||||
script.onerror = reject;
|
||||
script.onerror = () => reject(new Error('高德地图组件加载失败'));
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
return amapLoader;
|
||||
@@ -2321,56 +2363,185 @@ export default {
|
||||
.then(() => {
|
||||
this.$nextTick(() => {
|
||||
if (!this.transportMapInstance) {
|
||||
const center = this.transportMapSelected.longitude
|
||||
? this.toLngLat(
|
||||
this.transportMapSelected.longitude,
|
||||
this.transportMapSelected.latitude
|
||||
)
|
||||
: [116.40769, 39.89945];
|
||||
this.transportMapInstance = new window.AMap.Map(this.$refs.transportMap, {
|
||||
center: [116.40769, 39.89945],
|
||||
zoom: 11,
|
||||
center,
|
||||
zoom: this.transportMapSelected.longitude ? 14 : 11,
|
||||
});
|
||||
this.transportMapInstance.on('click', event => this.pickMapPoint(event.lnglat));
|
||||
} else this.transportMapInstance.resize();
|
||||
} else {
|
||||
this.transportMapInstance.resize();
|
||||
}
|
||||
if (this.transportMapSelected.longitude) {
|
||||
this.renderTransportMapMarker(
|
||||
this.toLngLat(
|
||||
this.transportMapSelected.longitude,
|
||||
this.transportMapSelected.latitude
|
||||
)
|
||||
);
|
||||
} else {
|
||||
this.transportMapMarker?.setMap(null);
|
||||
this.transportMapMarker = null;
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
this.$message.error('高德地图组件加载失败');
|
||||
this.$message.error('高德地图组件加载失败,请稍后重试或重新打开弹窗');
|
||||
this.transportMapBox = false;
|
||||
});
|
||||
},
|
||||
searchTransportMapKeyword() {
|
||||
if (!this.transportMapKeyword) return this.$message.warning('请输入地址关键词');
|
||||
this.loadAmap().then(() => {
|
||||
this.transportMapLoading = true;
|
||||
window.AMap.plugin('AMap.Geocoder', () => {
|
||||
this.transportMapGeocoder = this.transportMapGeocoder || new window.AMap.Geocoder();
|
||||
this.transportMapGeocoder.getLocation(this.transportMapKeyword, (status, result) => {
|
||||
this.transportMapLoading = false;
|
||||
const location = status === 'complete' && result.geocodes?.[0]?.location;
|
||||
if (location) this.pickMapPoint(location, this.transportMapKeyword);
|
||||
else this.$message.warning('地图搜索无匹配地址');
|
||||
});
|
||||
const keyword = String(this.transportMapKeyword || '').trim();
|
||||
if (!keyword) return this.$message.warning('请输入地址关键词');
|
||||
this.transportMapLoading = true;
|
||||
this.loadAmap()
|
||||
.then(() => this.ensureTransportMapGeocoder())
|
||||
.then(() => this.runTransportMapGeocode('location', keyword))
|
||||
.then(result => {
|
||||
const point = this.resolveTransportMapPoint(result);
|
||||
if (!point) throw new Error('未找到匹配地址');
|
||||
return this.pickMapPoint(point, keyword);
|
||||
})
|
||||
.catch(() => {
|
||||
this.transportMapStatus = '地图搜索失败';
|
||||
this.$message.warning('地图搜索无匹配地址');
|
||||
})
|
||||
.finally(() => {
|
||||
this.transportMapLoading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
pickMapPoint(point, keyword = '') {
|
||||
const longitude = point.getLng ? point.getLng() : point.lng;
|
||||
const latitude = point.getLat ? point.getLat() : point.lat;
|
||||
if (longitude === undefined || latitude === undefined) return;
|
||||
this.transportMapSelected = {
|
||||
longitude: Number(longitude).toFixed(6),
|
||||
latitude: Number(latitude).toFixed(6),
|
||||
detailAddress: keyword || this.transportMapKeyword,
|
||||
};
|
||||
this.transportMapStatus = '已选点,可确认回填';
|
||||
if (this.transportMapInstance) {
|
||||
this.transportMapMarker?.setMap(null);
|
||||
this.transportMapMarker = new window.AMap.Marker({ position: [longitude, latitude] });
|
||||
this.transportMapMarker.setMap(this.transportMapInstance);
|
||||
this.transportMapInstance.setCenter([longitude, latitude]);
|
||||
const longitude = this.getTransportMapPointLng(point);
|
||||
const latitude = this.getTransportMapPointLat(point);
|
||||
if (!Number.isFinite(Number(longitude)) || !Number.isFinite(Number(latitude))) {
|
||||
this.$message.warning('选点坐标无效');
|
||||
return Promise.resolve();
|
||||
}
|
||||
const lnglat = this.toLngLat(longitude, latitude);
|
||||
this.renderTransportMapMarker(lnglat);
|
||||
this.transportMapSelected = this.buildTransportMapSelection({ longitude, latitude });
|
||||
this.transportMapStatus = '正在反查地址...';
|
||||
this.transportMapLoading = true;
|
||||
return this.ensureTransportMapGeocoder()
|
||||
.then(() => this.runTransportMapGeocode('address', lnglat))
|
||||
.then(result => {
|
||||
const address = this.resolveTransportMapAddress(result);
|
||||
this.transportMapSelected = {
|
||||
...this.transportMapSelected,
|
||||
detailAddress: address.detailAddress || keyword,
|
||||
regionName: address.regionName,
|
||||
addressCode: address.addressCode,
|
||||
};
|
||||
this.transportMapKeyword =
|
||||
this.transportMapSelected.detailAddress || this.transportMapKeyword;
|
||||
this.transportMapStatus = this.transportMapSelected.detailAddress || '已选点,可确认回填';
|
||||
})
|
||||
.catch(() => {
|
||||
this.transportMapSelected = {};
|
||||
this.transportMapStatus = '反查地址失败';
|
||||
this.$message.error('反查地址失败,请重新选点');
|
||||
})
|
||||
.finally(() => {
|
||||
this.transportMapLoading = false;
|
||||
});
|
||||
},
|
||||
renderTransportMapMarker(point) {
|
||||
if (!this.transportMapInstance || !window.AMap) return;
|
||||
this.transportMapMarker?.setMap(null);
|
||||
this.transportMapMarker = new window.AMap.Marker({ position: point });
|
||||
this.transportMapMarker.setMap(this.transportMapInstance);
|
||||
this.transportMapInstance.setCenter(point);
|
||||
},
|
||||
confirmTransportMapPick() {
|
||||
if (!this.transportMapSelected.detailAddress || !this.transportMapSelected.regionName) {
|
||||
this.$message.warning('请等待地址解析完成后再确认');
|
||||
return;
|
||||
}
|
||||
const prefix = this.transportMapTarget;
|
||||
this.applyAddress(prefix, this.transportMapSelected);
|
||||
this.transportMapBox = false;
|
||||
},
|
||||
buildTransportMapSelection({ longitude, latitude, detailAddress, regionName, addressCode }) {
|
||||
return {
|
||||
longitude: this.formatTransportMapCoordinate(longitude),
|
||||
latitude: this.formatTransportMapCoordinate(latitude),
|
||||
detailAddress: detailAddress || '',
|
||||
regionName: regionName || '',
|
||||
addressCode: addressCode || '',
|
||||
};
|
||||
},
|
||||
formatTransportMapCoordinate(value) {
|
||||
if (value === undefined || value === null || value === '') return '';
|
||||
const numberValue = Number(value);
|
||||
return Number.isFinite(numberValue) ? numberValue.toFixed(6) : '';
|
||||
},
|
||||
toLngLat(longitude, latitude) {
|
||||
return new window.AMap.LngLat(Number(longitude), Number(latitude));
|
||||
},
|
||||
getTransportMapPointLng(point) {
|
||||
if (!point) return undefined;
|
||||
return typeof point.getLng === 'function' ? point.getLng() : point.lng ?? point.lon;
|
||||
},
|
||||
getTransportMapPointLat(point) {
|
||||
if (!point) return undefined;
|
||||
return typeof point.getLat === 'function' ? point.getLat() : point.lat;
|
||||
},
|
||||
ensureTransportMapGeocoder() {
|
||||
if (this.transportMapGeocoder) return Promise.resolve(this.transportMapGeocoder);
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!window.AMap?.plugin) {
|
||||
reject(new Error('高德地图组件未就绪'));
|
||||
return;
|
||||
}
|
||||
window.AMap.plugin(['AMap.Geocoder'], () => {
|
||||
try {
|
||||
this.transportMapGeocoder = new window.AMap.Geocoder();
|
||||
resolve(this.transportMapGeocoder);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
runTransportMapGeocode(action, input) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const timer = window.setTimeout(() => reject(new Error('高德地图请求超时')), 10000);
|
||||
const done = (status, result) => {
|
||||
window.clearTimeout(timer);
|
||||
if (status === 'complete' && result) {
|
||||
resolve(result);
|
||||
return;
|
||||
}
|
||||
reject(new Error('高德地图请求失败'));
|
||||
};
|
||||
try {
|
||||
if (action === 'location') this.transportMapGeocoder.getLocation(input, done);
|
||||
else this.transportMapGeocoder.getAddress(input, done);
|
||||
} catch (error) {
|
||||
window.clearTimeout(timer);
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
},
|
||||
resolveTransportMapPoint(result) {
|
||||
const geocode = Array.isArray(result?.geocodes) ? result.geocodes[0] : null;
|
||||
return geocode?.location || result?.location || result?.lnglat || null;
|
||||
},
|
||||
resolveTransportMapAddress(result = {}) {
|
||||
const regeocode = result.regeocode || {};
|
||||
const component = regeocode.addressComponent || {};
|
||||
const city = Array.isArray(component.city) ? '' : component.city;
|
||||
return {
|
||||
detailAddress: regeocode.formattedAddress || '',
|
||||
regionName: [component.province, city, component.district].filter(Boolean).join(''),
|
||||
addressCode: component.adcode || '',
|
||||
};
|
||||
},
|
||||
ensureCargoTypeOptions() {
|
||||
if (this.cargoTypeRequest) return this.cargoTypeRequest;
|
||||
if (this.cargoTypeOptions.length) return Promise.resolve(this.cargoTypeOptions);
|
||||
@@ -2538,9 +2709,7 @@ export default {
|
||||
quantityUnits() {
|
||||
return [
|
||||
...new Set(
|
||||
this.transportCargoRows
|
||||
.map(row => String(row.quantityUnit || '').trim())
|
||||
.filter(Boolean)
|
||||
this.transportCargoRows.map(row => String(row.quantityUnit || '').trim()).filter(Boolean)
|
||||
),
|
||||
];
|
||||
},
|
||||
@@ -2990,10 +3159,7 @@ export default {
|
||||
}
|
||||
.shipping-template-page__detail-route-values {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(160px, 1fr) minmax(220px, 2fr) minmax(140px, 1fr) minmax(
|
||||
160px,
|
||||
1fr
|
||||
);
|
||||
grid-template-columns: minmax(160px, 1fr) minmax(220px, 2fr) minmax(140px, 1fr) minmax(160px, 1fr);
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user