🐛 修复总单地址回填、结算费用英文项与项目部门提示
常用地址级联回填不再误清空;预结算/正式结算过滤 freightJson 杂项;项目查看态业务部门/平台公司支持悬停完整信息。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -280,6 +280,23 @@ export default {
|
|||||||
.filter(Boolean)[0] || '';
|
.filter(Boolean)[0] || '';
|
||||||
},
|
},
|
||||||
applyDefaultDeptSearch() {
|
applyDefaultDeptSearch() {
|
||||||
|
// 超管默认不限组织,避免预填当前组织后看不到其他组织/无组织数据。
|
||||||
|
if (this.isAdmin) {
|
||||||
|
const deptColumn = this.findColumn(this.option.column, 'searchDeptId');
|
||||||
|
if (deptColumn) {
|
||||||
|
deptColumn.searchValue = undefined;
|
||||||
|
}
|
||||||
|
const nextQuery = { ...this.query };
|
||||||
|
delete nextQuery.deptId;
|
||||||
|
delete nextQuery.searchDeptId;
|
||||||
|
this.query = nextQuery;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.crud?.searchForm) {
|
||||||
|
this.$refs.crud.searchForm.searchDeptId = undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
const deptId = this.defaultDeptId();
|
const deptId = this.defaultDeptId();
|
||||||
const deptColumn = this.findColumn(this.option.column, 'searchDeptId');
|
const deptColumn = this.findColumn(this.option.column, 'searchDeptId');
|
||||||
if (!deptId || !deptColumn) return;
|
if (!deptId || !deptColumn) return;
|
||||||
@@ -298,7 +315,8 @@ export default {
|
|||||||
if (deptColumn) {
|
if (deptColumn) {
|
||||||
deptColumn.dicData = this.deptOptions;
|
deptColumn.dicData = this.deptOptions;
|
||||||
}
|
}
|
||||||
// dicData 异步到位后再回填,避免下拉选项为空时清空已选组织,导致请求丢失 deptId。
|
// 超管不回填默认组织;普通用户在 dicData 到位后再回填,避免下拉清空已选组织。
|
||||||
|
if (this.isAdmin) return;
|
||||||
const deptId = String(this.query.deptId || this.defaultDeptId() || '');
|
const deptId = String(this.query.deptId || this.defaultDeptId() || '');
|
||||||
if (!deptId) return;
|
if (!deptId) return;
|
||||||
if (deptColumn) {
|
if (deptColumn) {
|
||||||
|
|||||||
@@ -652,6 +652,8 @@ export default {
|
|||||||
addressQuery: {},
|
addressQuery: {},
|
||||||
addressPage: { current: 1, size: 10, total: 0 },
|
addressPage: { current: 1, size: 10, total: 0 },
|
||||||
addressRegionPaths: { departure: [], arrival: [] },
|
addressRegionPaths: { departure: [], arrival: [] },
|
||||||
|
// 程序回填省市区时抑制 cascader @change,避免空值回调把已填地址清空
|
||||||
|
suppressAddressRegionChange: false,
|
||||||
regionOptions: [],
|
regionOptions: [],
|
||||||
regionLoading: false,
|
regionLoading: false,
|
||||||
regionRequest: null,
|
regionRequest: null,
|
||||||
@@ -889,26 +891,63 @@ export default {
|
|||||||
findRegionPathByName(options = [], regionName = '', parents = []) {
|
findRegionPathByName(options = [], regionName = '', parents = []) {
|
||||||
const target = String(regionName || '').replace(/\s+/g, '');
|
const target = String(regionName || '').replace(/\s+/g, '');
|
||||||
if (!target) return [];
|
if (!target) return [];
|
||||||
|
let suffixMatch = [];
|
||||||
for (const item of options) {
|
for (const item of options) {
|
||||||
const nextParents = [...parents, item];
|
const nextParents = [...parents, item];
|
||||||
const name = nextParents.map(region => region.title || region.name || '').join('');
|
const name = nextParents.map(region => region.title || region.name || '').join('');
|
||||||
if (name === target) return nextParents.map(region => region.id);
|
if (name === target) return nextParents.map(region => region.id);
|
||||||
|
// 常用地址可能缺省名,允许「市+区」后缀命中完整省市区路径
|
||||||
|
if (!suffixMatch.length && name.endsWith(target) && target.length >= 2) {
|
||||||
|
suffixMatch = nextParents.map(region => region.id);
|
||||||
|
}
|
||||||
const path = this.findRegionPathByName(item.children, target, nextParents);
|
const path = this.findRegionPathByName(item.children, target, nextParents);
|
||||||
if (path.length) return path;
|
if (path.length) return path;
|
||||||
}
|
}
|
||||||
return [];
|
return suffixMatch;
|
||||||
},
|
},
|
||||||
findRegionPathByCode(options = [], regionCode = '', parents = []) {
|
findRegionPathByCode(options = [], regionCode = '', parents = []) {
|
||||||
const target = String(regionCode || '').trim();
|
const target = String(regionCode || '').trim();
|
||||||
if (!target) return [];
|
if (!target) return [];
|
||||||
for (const item of options) {
|
for (const item of options) {
|
||||||
const nextParents = [...parents, item];
|
const nextParents = [...parents, item];
|
||||||
if (String(item.id) === target) return nextParents.map(region => region.id);
|
if (String(item.id) === target || String(item.value || '') === target) {
|
||||||
|
return nextParents.map(region => region.id);
|
||||||
|
}
|
||||||
const path = this.findRegionPathByCode(item.children, target, nextParents);
|
const path = this.findRegionPathByCode(item.children, target, nextParents);
|
||||||
if (path.length) return path;
|
if (path.length) return path;
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
},
|
},
|
||||||
|
resolveRegionPath(field) {
|
||||||
|
if (!field) return [];
|
||||||
|
const codePath = this.findRegionPathByCode(
|
||||||
|
this.regionOptions,
|
||||||
|
field.model[field.regionCode]
|
||||||
|
);
|
||||||
|
if (codePath.length) return codePath;
|
||||||
|
const namePath = this.findRegionPathByName(this.regionOptions, field.model[field.name]);
|
||||||
|
if (namePath.length) return namePath;
|
||||||
|
const composed = [field.model[field.provinceName], field.model[field.cityName], field.model[field.districtName]]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join('');
|
||||||
|
return this.findRegionPathByName(this.regionOptions, composed);
|
||||||
|
},
|
||||||
|
setAddressRegionPath(target, path = []) {
|
||||||
|
const nextPath = Array.isArray(path) ? path.map(item => String(item)) : [];
|
||||||
|
const current = this.addressRegionPaths[target] || [];
|
||||||
|
if (
|
||||||
|
current.length === nextPath.length &&
|
||||||
|
current.every((item, index) => String(item) === String(nextPath[index]))
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.suppressAddressRegionChange = true;
|
||||||
|
// Vue3 直接写动态 key,避免整体替换对象导致其它 cascader 重建并触发空 @change
|
||||||
|
this.addressRegionPaths[target] = nextPath;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.suppressAddressRegionChange = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
regionLabels(path = []) {
|
regionLabels(path = []) {
|
||||||
let options = this.regionOptions;
|
let options = this.regionOptions;
|
||||||
const labels = [];
|
const labels = [];
|
||||||
@@ -947,10 +986,22 @@ export default {
|
|||||||
this.setAddressRegionNames(field, [provinceMatch?.[0], cityMatch?.[0], districtMatch?.[0]]);
|
this.setAddressRegionNames(field, [provinceMatch?.[0], cityMatch?.[0], districtMatch?.[0]]);
|
||||||
},
|
},
|
||||||
handleAddressRegionChange(target, value) {
|
handleAddressRegionChange(target, value) {
|
||||||
|
if (this.suppressAddressRegionChange) return;
|
||||||
const field = this.addressModel(target);
|
const field = this.addressModel(target);
|
||||||
const path = Array.isArray(value) ? value.map(item => String(item)) : [];
|
const path = Array.isArray(value) ? value.map(item => String(item)) : [];
|
||||||
this.addressRegionPaths = { ...this.addressRegionPaths, [target]: path };
|
this.setAddressRegionPath(target, path);
|
||||||
if (!field) return;
|
if (!field) return;
|
||||||
|
// 程序回填/重建过程中 cascader 可能短暂抛出空值,不能据此清空已选常用地址
|
||||||
|
if (!path.length) {
|
||||||
|
const hasExisting =
|
||||||
|
String(field.model[field.name] || '').trim() ||
|
||||||
|
String(field.model[field.address] || '').trim() ||
|
||||||
|
String(field.model[field.regionCode] || '').trim();
|
||||||
|
if (hasExisting) {
|
||||||
|
this.$nextTick(() => this.syncAddressRegionPath(target));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
const labels = this.regionLabels(path);
|
const labels = this.regionLabels(path);
|
||||||
field.model[field.name] = labels.join('');
|
field.model[field.name] = labels.join('');
|
||||||
field.model[field.regionCode] = path.at(-1) || '';
|
field.model[field.regionCode] = path.at(-1) || '';
|
||||||
@@ -959,19 +1010,29 @@ export default {
|
|||||||
},
|
},
|
||||||
syncAddressRegionPath(target) {
|
syncAddressRegionPath(target) {
|
||||||
const field = this.addressModel(target);
|
const field = this.addressModel(target);
|
||||||
if (!field) return;
|
if (!field || !this.regionOptions.length) return;
|
||||||
const codePath = this.findRegionPathByCode(this.regionOptions, field.model[field.regionCode]);
|
const path = this.resolveRegionPath(field);
|
||||||
const path = codePath.length
|
this.setAddressRegionPath(target, path);
|
||||||
? codePath
|
|
||||||
: this.findRegionPathByName(this.regionOptions, field.model[field.name]);
|
|
||||||
this.addressRegionPaths = { ...this.addressRegionPaths, [target]: path };
|
|
||||||
if (path.length) this.setAddressRegionNames(field, this.regionLabels(path));
|
if (path.length) this.setAddressRegionNames(field, this.regionLabels(path));
|
||||||
},
|
},
|
||||||
syncAddressRegionPaths() {
|
syncAddressRegionPaths() {
|
||||||
if (!this.regionOptions.length) return;
|
if (!this.regionOptions.length) return;
|
||||||
['departure', 'arrival', ...this.form.routes.map((route, index) => `route-${index}`)].forEach(target => {
|
this.suppressAddressRegionChange = true;
|
||||||
this.syncAddressRegionPath(target);
|
try {
|
||||||
});
|
['departure', 'arrival', ...this.form.routes.map((route, index) => `route-${index}`)].forEach(
|
||||||
|
target => {
|
||||||
|
const field = this.addressModel(target);
|
||||||
|
if (!field) return;
|
||||||
|
const path = this.resolveRegionPath(field);
|
||||||
|
this.addressRegionPaths[target] = path;
|
||||||
|
if (path.length) this.setAddressRegionNames(field, this.regionLabels(path));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.suppressAddressRegionChange = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async loadDetail(id) {
|
async loadDetail(id) {
|
||||||
const res = await api.getDetail(id);
|
const res = await api.getDetail(id);
|
||||||
@@ -1233,8 +1294,9 @@ export default {
|
|||||||
this.stationPage.current = 1;
|
this.stationPage.current = 1;
|
||||||
this.loadStationList();
|
this.loadStationList();
|
||||||
},
|
},
|
||||||
selectStation(row) {
|
async selectStation(row) {
|
||||||
const target = this.addressModel(this.addressTarget);
|
const targetKey = this.addressTarget;
|
||||||
|
const target = this.addressModel(targetKey);
|
||||||
if (!target) return;
|
if (!target) return;
|
||||||
const station = this.normalizeStation(row);
|
const station = this.normalizeStation(row);
|
||||||
target.model[target.name] = station.stationName || station.regionName;
|
target.model[target.name] = station.stationName || station.regionName;
|
||||||
@@ -1245,7 +1307,9 @@ export default {
|
|||||||
target.model[target.siteCode] = station.stationCode;
|
target.model[target.siteCode] = station.stationCode;
|
||||||
this.setAddressRegionNamesFromRow(target, station);
|
this.setAddressRegionNamesFromRow(target, station);
|
||||||
this.stationDialogVisible = false;
|
this.stationDialogVisible = false;
|
||||||
this.loadRegionOptions().then(() => this.syncAddressRegionPath(this.addressTarget));
|
await this.loadRegionOptions();
|
||||||
|
await this.$nextTick();
|
||||||
|
this.syncAddressRegionPath(targetKey);
|
||||||
},
|
},
|
||||||
async loadAddressList() {
|
async loadAddressList() {
|
||||||
this.addressLoading = true;
|
this.addressLoading = true;
|
||||||
@@ -1271,8 +1335,9 @@ export default {
|
|||||||
this.addressPage.current = 1;
|
this.addressPage.current = 1;
|
||||||
this.loadAddressList();
|
this.loadAddressList();
|
||||||
},
|
},
|
||||||
selectAddress(row) {
|
async selectAddress(row) {
|
||||||
const target = this.addressModel(this.addressTarget);
|
const targetKey = this.addressTarget;
|
||||||
|
const target = this.addressModel(targetKey);
|
||||||
if (!target) return;
|
if (!target) return;
|
||||||
target.model[target.name] = row.regionName || row.addressName || '';
|
target.model[target.name] = row.regionName || row.addressName || '';
|
||||||
target.model[target.address] = row.detailAddress || row.address || '';
|
target.model[target.address] = row.detailAddress || row.address || '';
|
||||||
@@ -1284,7 +1349,10 @@ export default {
|
|||||||
target.model[target.siteCode] = '';
|
target.model[target.siteCode] = '';
|
||||||
this.setAddressRegionNamesFromRow(target, row);
|
this.setAddressRegionNamesFromRow(target, row);
|
||||||
this.addressDialogVisible = false;
|
this.addressDialogVisible = false;
|
||||||
this.loadRegionOptions().then(() => this.syncAddressRegionPath(this.addressTarget));
|
await this.loadRegionOptions();
|
||||||
|
// nextTick 确保途经点动态 key 已挂载 cascader 后再回填路径
|
||||||
|
await this.$nextTick();
|
||||||
|
this.syncAddressRegionPath(targetKey);
|
||||||
},
|
},
|
||||||
handleAddressDetailClick(target) {
|
handleAddressDetailClick(target) {
|
||||||
if (this.isBasicRouteReadonly) return;
|
if (this.isBasicRouteReadonly) return;
|
||||||
@@ -1803,12 +1871,23 @@ export default {
|
|||||||
},
|
},
|
||||||
addRoute() {
|
addRoute() {
|
||||||
if (this.isBasicRouteReadonly) return;
|
if (this.isBasicRouteReadonly) return;
|
||||||
this.form.routes.push(this.createRoute());
|
const index = this.form.routes.length;
|
||||||
|
this.form.routes.push(this.createRoute(index));
|
||||||
|
this.addressRegionPaths[`route-${index}`] = [];
|
||||||
},
|
},
|
||||||
removeRoute(index) {
|
removeRoute(index) {
|
||||||
if (this.isBasicRouteReadonly) return;
|
if (this.isBasicRouteReadonly) return;
|
||||||
this.form.routes.splice(index, 1);
|
this.form.routes.splice(index, 1);
|
||||||
this.syncAddressRegionPaths();
|
const nextPaths = { departure: this.addressRegionPaths.departure || [], arrival: this.addressRegionPaths.arrival || [] };
|
||||||
|
this.form.routes.forEach((route, routeIndex) => {
|
||||||
|
nextPaths[`route-${routeIndex}`] = this.addressRegionPaths[`route-${routeIndex >= index ? routeIndex + 1 : routeIndex}`] || [];
|
||||||
|
});
|
||||||
|
this.suppressAddressRegionChange = true;
|
||||||
|
this.addressRegionPaths = nextPaths;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.suppressAddressRegionChange = false;
|
||||||
|
this.syncAddressRegionPaths();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
goodsKey(row = {}) {
|
goodsKey(row = {}) {
|
||||||
return `${row.cargoName || ''}\u0000${row.cargoType || ''}`;
|
return `${row.cargoName || ''}\u0000${row.cargoType || ''}`;
|
||||||
|
|||||||
@@ -4023,7 +4023,7 @@ export default {
|
|||||||
exists.add(key);
|
exists.add(key);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// 承运商类型:新增后须仍存在共同的承运商合同乙方(按客户合同甲方匹配后取交集)
|
// 承运商类型:新增后须仍存在共同的承运商合同乙方(按客户合同乙方=承运商合同甲方匹配后取交集)
|
||||||
if (
|
if (
|
||||||
String(this.dialogForm.carrierType || '').trim() === '承运商' &&
|
String(this.dialogForm.carrierType || '').trim() === '承运商' &&
|
||||||
nextRows.length > this.selectedWaybillRows.length
|
nextRows.length > this.selectedWaybillRows.length
|
||||||
@@ -4744,7 +4744,7 @@ export default {
|
|||||||
}
|
}
|
||||||
this.taskCarrierLoading = true;
|
this.taskCarrierLoading = true;
|
||||||
try {
|
try {
|
||||||
// 配载单只有一个项目;传入子运单后按客户合同甲方匹配并取承运商合同乙方交集
|
// 配载单只有一个项目;传入子运单后按客户合同乙方=承运商合同甲方匹配并取承运商合同乙方交集
|
||||||
const projectId = this.selectedWaybillRows.map(row => row.projectId).find(Boolean);
|
const projectId = this.selectedWaybillRows.map(row => row.projectId).find(Boolean);
|
||||||
const waybillIds = this.selectedWaybillRows.map(row => row.id).filter(Boolean);
|
const waybillIds = this.selectedWaybillRows.map(row => row.id).filter(Boolean);
|
||||||
const response = await loadingApi.getCarrierContracts(
|
const response = await loadingApi.getCarrierContracts(
|
||||||
|
|||||||
@@ -249,35 +249,57 @@
|
|||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="业务部门" prop="businessDeptId">
|
<el-form-item label="业务部门" prop="businessDeptId">
|
||||||
<el-cascader
|
<el-tooltip
|
||||||
v-model="businessDeptCascaderValue"
|
placement="top"
|
||||||
:options="businessDeptTreeOptions"
|
:disabled="!shouldShowBusinessDeptTooltip"
|
||||||
:props="deptCascaderProps"
|
:show-after="200"
|
||||||
placeholder="请选择"
|
>
|
||||||
filterable
|
<template #content>
|
||||||
clearable
|
<div class="project-apply-form__field-tooltip">{{ businessDeptTooltipText }}</div>
|
||||||
:disabled="dialogReadonly"
|
</template>
|
||||||
/>
|
<span class="project-apply-form__field-tooltip-trigger">
|
||||||
|
<el-cascader
|
||||||
|
v-model="businessDeptCascaderValue"
|
||||||
|
:options="businessDeptTreeOptions"
|
||||||
|
:props="deptCascaderProps"
|
||||||
|
placeholder="请选择"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
:disabled="dialogReadonly"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="平台公司" prop="undertakeDeptId">
|
<el-form-item label="平台公司" prop="undertakeDeptId">
|
||||||
<el-select
|
<el-tooltip
|
||||||
v-model="form.undertakeDeptId"
|
placement="top"
|
||||||
placeholder="请选择"
|
:disabled="!shouldShowUndertakeDeptTooltip"
|
||||||
multiple
|
:show-after="200"
|
||||||
collapse-tags
|
|
||||||
collapse-tags-tooltip
|
|
||||||
clearable
|
|
||||||
filterable
|
|
||||||
:disabled="dialogReadonly"
|
|
||||||
@change="handleUndertakeDeptChange"
|
|
||||||
>
|
>
|
||||||
<el-option
|
<template #content>
|
||||||
v-for="item in platformCompanyOptions"
|
<div class="project-apply-form__field-tooltip">{{ undertakeDeptTooltipText }}</div>
|
||||||
:key="item.value"
|
</template>
|
||||||
:label="item.label"
|
<span class="project-apply-form__field-tooltip-trigger">
|
||||||
:value="item.value"
|
<el-select
|
||||||
/>
|
v-model="form.undertakeDeptId"
|
||||||
</el-select>
|
placeholder="请选择"
|
||||||
|
multiple
|
||||||
|
collapse-tags
|
||||||
|
collapse-tags-tooltip
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
:disabled="dialogReadonly"
|
||||||
|
@change="handleUndertakeDeptChange"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in platformCompanyOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</span>
|
||||||
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="项目由来" prop="projectSource">
|
<el-form-item label="项目由来" prop="projectSource">
|
||||||
<el-select
|
<el-select
|
||||||
@@ -1402,6 +1424,33 @@ export default {
|
|||||||
this.handleBusinessDeptChange(this.form.businessDeptId);
|
this.handleBusinessDeptChange(this.form.businessDeptId);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// 查看态禁用控件无 hover,用完整路径/名称做 tooltip
|
||||||
|
businessDeptTooltipText() {
|
||||||
|
const pathIds = this.businessDeptCascaderValue || [];
|
||||||
|
if (pathIds.length && this.businessDeptTreeOptions?.length) {
|
||||||
|
const labels = [];
|
||||||
|
let nodes = this.businessDeptTreeOptions;
|
||||||
|
for (const id of pathIds) {
|
||||||
|
const node = (nodes || []).find(item => String(item.value) === String(id));
|
||||||
|
if (!node) break;
|
||||||
|
labels.push(node.label);
|
||||||
|
nodes = node.children;
|
||||||
|
}
|
||||||
|
if (labels.length) return labels.join(' / ');
|
||||||
|
}
|
||||||
|
return String(this.form.businessDeptName || '').trim();
|
||||||
|
},
|
||||||
|
undertakeDeptTooltipText() {
|
||||||
|
const name = String(this.form.undertakeDeptName || '').trim();
|
||||||
|
if (name) return name;
|
||||||
|
return this.resolveUndertakeDeptNames(this.parseUndertakeDeptIds(this.form.undertakeDeptId));
|
||||||
|
},
|
||||||
|
shouldShowBusinessDeptTooltip() {
|
||||||
|
return this.dialogReadonly && !!this.businessDeptTooltipText;
|
||||||
|
},
|
||||||
|
shouldShowUndertakeDeptTooltip() {
|
||||||
|
return this.dialogReadonly && !!this.undertakeDeptTooltipText;
|
||||||
|
},
|
||||||
permissionList() {
|
permissionList() {
|
||||||
return {
|
return {
|
||||||
addBtn: this.canCreate,
|
addBtn: this.canCreate,
|
||||||
@@ -3272,6 +3321,20 @@ export default {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__field-tooltip-trigger {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__field-tooltip {
|
||||||
|
max-width: 480px;
|
||||||
|
max-height: 240px;
|
||||||
|
overflow: auto;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-word;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.el-form-item) {
|
:deep(.el-form-item) {
|
||||||
//margin-bottom: 24px;
|
//margin-bottom: 24px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3222,10 +3222,47 @@ export default {
|
|||||||
return files.length ? JSON.stringify(files) : '';
|
return files.length ? JSON.stringify(files) : '';
|
||||||
},
|
},
|
||||||
parseFeeItems(value) {
|
parseFeeItems(value) {
|
||||||
|
const raw = this.parseRawFeeItems(value);
|
||||||
|
const metaKeys = new Set([
|
||||||
|
'currency',
|
||||||
|
'totalFreightAmount',
|
||||||
|
'otherFreightAmount',
|
||||||
|
'freightItems',
|
||||||
|
'freightTotal',
|
||||||
|
'totalFreight',
|
||||||
|
'totalAmount',
|
||||||
|
'freight',
|
||||||
|
'freightAmount',
|
||||||
|
'transportFee',
|
||||||
|
'otherFeeTotal',
|
||||||
|
'otherAmount',
|
||||||
|
]);
|
||||||
|
const result = {};
|
||||||
|
let otherFeeAmount = 0;
|
||||||
|
Object.entries(raw).forEach(([key, amount]) => {
|
||||||
|
if (!key) return;
|
||||||
|
if (key === 'otherFreightAmount' || key === 'otherFeeTotal' || key === 'otherAmount') {
|
||||||
|
otherFeeAmount += Number(amount || 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (metaKeys.has(key)) return;
|
||||||
|
if (amount && typeof amount === 'object') return;
|
||||||
|
result[key] = amount;
|
||||||
|
});
|
||||||
|
const hasOtherFee = Object.keys(result).some(
|
||||||
|
name => String(name).includes('其它费') || String(name).includes('其他费')
|
||||||
|
);
|
||||||
|
if (otherFeeAmount && !hasOtherFee) {
|
||||||
|
result['其它费用'] = otherFeeAmount;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
parseRawFeeItems(value) {
|
||||||
if (!value) return {};
|
if (!value) return {};
|
||||||
if (typeof value === 'object') return value;
|
if (typeof value === 'object') return { ...value };
|
||||||
try {
|
try {
|
||||||
return JSON.parse(value);
|
const parsed = JSON.parse(value);
|
||||||
|
return parsed && typeof parsed === 'object' ? parsed : {};
|
||||||
} catch {
|
} catch {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3061,6 +3061,42 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
parseFeeItems(value) {
|
parseFeeItems(value) {
|
||||||
|
const raw = this.parseRawFeeItems(value);
|
||||||
|
const metaKeys = new Set([
|
||||||
|
'currency',
|
||||||
|
'totalFreightAmount',
|
||||||
|
'otherFreightAmount',
|
||||||
|
'freightItems',
|
||||||
|
'freightTotal',
|
||||||
|
'totalFreight',
|
||||||
|
'totalAmount',
|
||||||
|
'freight',
|
||||||
|
'freightAmount',
|
||||||
|
'transportFee',
|
||||||
|
'otherFeeTotal',
|
||||||
|
'otherAmount',
|
||||||
|
]);
|
||||||
|
const result = {};
|
||||||
|
let otherFeeAmount = 0;
|
||||||
|
Object.entries(raw).forEach(([key, amount]) => {
|
||||||
|
if (!key) return;
|
||||||
|
if (key === 'otherFreightAmount' || key === 'otherFeeTotal' || key === 'otherAmount') {
|
||||||
|
otherFeeAmount += Number(amount || 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (metaKeys.has(key)) return;
|
||||||
|
if (amount && typeof amount === 'object') return;
|
||||||
|
result[key] = amount;
|
||||||
|
});
|
||||||
|
const hasOtherFee = Object.keys(result).some(
|
||||||
|
name => String(name).includes('其它费') || String(name).includes('其他费')
|
||||||
|
);
|
||||||
|
if (otherFeeAmount && !hasOtherFee) {
|
||||||
|
result['其它费用'] = otherFeeAmount;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
parseRawFeeItems(value) {
|
||||||
if (!value) return {};
|
if (!value) return {};
|
||||||
if (typeof value === 'object') return { ...value };
|
if (typeof value === 'object') return { ...value };
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user