✨ 正式结算保存草稿与同步入口,项目申请平台公司多选等业务优化
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -887,11 +887,14 @@ const syncCarrierOptions = () => {
|
||||
carrierOptions.value = [];
|
||||
return;
|
||||
}
|
||||
const carrierId =
|
||||
const carrierId = resolveCarrierArchiveId(
|
||||
customerContract?.partyBId ||
|
||||
customerContract?.partyBUserId ||
|
||||
customerContract?.customerId ||
|
||||
'';
|
||||
customerContract?.partyBUserId ||
|
||||
customerContract?.contractPartyBId ||
|
||||
customerContract?.customerId ||
|
||||
'',
|
||||
carrierName
|
||||
);
|
||||
carrierOptions.value = [{ id: carrierId, carrierName, label: carrierName, value: carrierName }];
|
||||
form.carrierId = carrierId;
|
||||
form.carrierIds = carrierId ? [carrierId] : [];
|
||||
@@ -1317,12 +1320,20 @@ const contractChange = id => {
|
||||
const carrierTypeChange = () => {
|
||||
syncCarrierOptions();
|
||||
};
|
||||
const resolveCarrierArchiveId = (carrierId, carrierName) => {
|
||||
if (carrierId) return carrierId;
|
||||
const name = String(carrierName || '').trim();
|
||||
if (!name) return '';
|
||||
const matched = queryCarriers.value.find(item => String(item.name || '').trim() === name);
|
||||
return matched?.id || '';
|
||||
};
|
||||
const carrierChange = value => {
|
||||
const item = carrierOptions.value.find(option => String(option.value) === String(value || ''));
|
||||
clearCarrier();
|
||||
if (!item) return;
|
||||
form.carrierId = item.id || '';
|
||||
form.carrierIds = item.id ? [item.id] : [];
|
||||
const carrierId = resolveCarrierArchiveId(item.id, item.carrierName);
|
||||
form.carrierId = carrierId;
|
||||
form.carrierIds = carrierId ? [carrierId] : [];
|
||||
form.carrierName = item.carrierName || '';
|
||||
if (!isSelfOperated.value) form.carrierContractId = item.carrierContractId || '';
|
||||
};
|
||||
@@ -1738,11 +1749,23 @@ const normalizeOptionalPlanId = value => {
|
||||
const buildImportPayload = (status = form.status, rowList = rows.value, extra = {}) => {
|
||||
const { file, ...batch } = form;
|
||||
const planId = normalizeOptionalPlanId(batch.planId);
|
||||
const carrierId = resolveCarrierArchiveId(
|
||||
batch.carrierId || batch.carrierIds?.[0] || '',
|
||||
batch.carrierName
|
||||
);
|
||||
const carrierIds =
|
||||
Array.isArray(batch.carrierIds) && batch.carrierIds.length
|
||||
? batch.carrierIds
|
||||
: carrierId
|
||||
? [carrierId]
|
||||
: [];
|
||||
return {
|
||||
...batch,
|
||||
planId,
|
||||
// 未选计划时不带占位名称,避免落库/回显 -1
|
||||
planName: planId ? batch.planName || undefined : null,
|
||||
carrierId: carrierId || undefined,
|
||||
carrierIds,
|
||||
status,
|
||||
rows: rowList.map(normalizeImportRow).map(stripInternalRowFields),
|
||||
...extra,
|
||||
|
||||
@@ -6508,17 +6508,10 @@ export default {
|
||||
if (isAddMode) {
|
||||
delete submitRow.id;
|
||||
delete submitRow.waybillNo;
|
||||
// 复制提交:状态列未进表单,Avue 可能不带回;显式保留原运单业务状态(含已完成)
|
||||
// 复制新建:业务状态固定为草稿,不沿用原运单状态
|
||||
const copyId = this.$route.query.copyId || '';
|
||||
if (copyId && !saveAsDraft) {
|
||||
const copiedStatus =
|
||||
this.form?.businessStatus ||
|
||||
this.copySourceBusinessStatus ||
|
||||
submitRow.businessStatus ||
|
||||
'';
|
||||
if (copiedStatus) {
|
||||
submitRow.businessStatus = copiedStatus;
|
||||
}
|
||||
if (copyId) {
|
||||
submitRow.businessStatus = this.config.draftStatus || 'draft';
|
||||
}
|
||||
}
|
||||
const skipValidation = saveAsDraft && this.config.skipDraftValidation === true;
|
||||
@@ -6541,14 +6534,16 @@ export default {
|
||||
if (this.config.enableAttachmentTable) {
|
||||
submitRow.attachmentsJson = JSON.stringify(this.attachmentRows);
|
||||
}
|
||||
const isCopyAdd = Boolean(this.$route.query.copyId) && isAddMode;
|
||||
if (this.config.saveAsDraft && saveAsDraft) {
|
||||
submitRow[this.config.draftStatusProp || 'approvalStatus'] =
|
||||
this.config.draftStatus || 'draft';
|
||||
} else if (
|
||||
!isCopyAdd &&
|
||||
this.config.draftStatusProp === 'businessStatus' &&
|
||||
submitRow.businessStatus === (this.config.draftStatus || 'draft')
|
||||
) {
|
||||
// 正式提交:清空草稿态,由后端按过程配置校正为待执行/进行中
|
||||
// 正式提交:清空草稿态,由后端按过程配置校正为待执行/进行中(复制新建除外,保持草稿)
|
||||
submitRow.businessStatus = '';
|
||||
}
|
||||
delete submitRow.basicInfoTitle;
|
||||
@@ -6811,12 +6806,18 @@ export default {
|
||||
}
|
||||
},
|
||||
rowSave(row, done, loading) {
|
||||
const submitRow = this.normalizeRow(row);
|
||||
// 复制页提交走草稿保存,避免 submit 接口把 draft 校正为待执行/进行中
|
||||
const isCopySubmit = Boolean(this.$route.query.copyId);
|
||||
const submitRow = this.normalizeRow(row, isCopySubmit);
|
||||
if (!submitRow) {
|
||||
this.stopSubmitLoading(loading);
|
||||
return;
|
||||
}
|
||||
this.getSaveRequest()(submitRow).then(
|
||||
const request =
|
||||
isCopySubmit && typeof this.api.saveDraft === 'function'
|
||||
? this.api.saveDraft
|
||||
: this.getSaveRequest();
|
||||
request(submitRow).then(
|
||||
res => {
|
||||
this.markWaybillListNeedRefresh();
|
||||
this.onLoad(this.page);
|
||||
@@ -6945,13 +6946,14 @@ export default {
|
||||
if (type === 'add' && copyId) {
|
||||
this.api.getDetail(copyId).then(res => {
|
||||
const sourceData = res.data.data || {};
|
||||
// 原运单业务状态(如 completed)提交时需原样带回并生成应收应付
|
||||
this.copySourceBusinessStatus = sourceData.businessStatus || '';
|
||||
// 清除不应该复制的字段(业务状态与原运单保持一致)
|
||||
this.copySourceBusinessStatus = '';
|
||||
// 清除不应该复制的字段;复制新建固定为草稿
|
||||
delete sourceData.id;
|
||||
delete sourceData.code;
|
||||
delete sourceData.waybillNo;
|
||||
delete sourceData.waybillStatus;
|
||||
delete sourceData.businessStatus;
|
||||
delete sourceData.businessStatusName;
|
||||
delete sourceData.driverAcceptStatus;
|
||||
delete sourceData.driverAcceptTime;
|
||||
delete sourceData.driverAcceptDriverId;
|
||||
@@ -6968,11 +6970,8 @@ export default {
|
||||
delete sourceData.updateUserName;
|
||||
|
||||
this.applyFormDetail(sourceData);
|
||||
// 标记为手工创建;业务状态沿用原运单(含已完成)
|
||||
this.form.dataSource = '手工创建';
|
||||
if (this.copySourceBusinessStatus) {
|
||||
this.form.businessStatus = this.copySourceBusinessStatus;
|
||||
}
|
||||
this.form.businessStatus = this.config.draftStatus || 'draft';
|
||||
done();
|
||||
});
|
||||
return;
|
||||
|
||||
@@ -231,6 +231,9 @@
|
||||
<el-select
|
||||
v-model="form.undertakeDeptId"
|
||||
placeholder="请选择"
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
clearable
|
||||
filterable
|
||||
:disabled="isBasicInfoReadonly"
|
||||
@@ -956,7 +959,7 @@ const emptyForm = () => ({
|
||||
projectShortName: '',
|
||||
businessDeptId: '',
|
||||
businessDeptName: '',
|
||||
undertakeDeptId: '',
|
||||
undertakeDeptId: [],
|
||||
undertakeDeptName: '',
|
||||
projectSource: '',
|
||||
sourceRemark: '',
|
||||
@@ -1146,7 +1149,15 @@ export default {
|
||||
{ max: 20, message: '项目简称不能超过20个字符', trigger: 'blur' },
|
||||
],
|
||||
businessDeptId: [{ required: true, message: '请选择业务部门', trigger: 'change' }],
|
||||
undertakeDeptId: [{ required: true, message: '请选择平台公司', trigger: 'change' }],
|
||||
undertakeDeptId: [
|
||||
{
|
||||
type: 'array',
|
||||
required: true,
|
||||
min: 1,
|
||||
message: '请选择平台公司',
|
||||
trigger: 'change',
|
||||
},
|
||||
],
|
||||
businessMode: [{ required: true, message: '请选择业务模式', trigger: 'change' }],
|
||||
customerNames: [{ required: true, message: '请选择客户名称', trigger: 'change' }],
|
||||
carrierNames: [{ required: true, message: '请选择下游承运商', trigger: 'change' }],
|
||||
@@ -1508,13 +1519,13 @@ export default {
|
||||
this.businessDeptTreeOptions = [{ label, value: detail.businessDeptId }];
|
||||
this.deptOptions = [{ label, rawLabel: label, value: detail.businessDeptId }];
|
||||
}
|
||||
if (detail.undertakeDeptId) {
|
||||
this.platformCompanyOptions = [
|
||||
{
|
||||
label: detail.undertakeDeptName || String(detail.undertakeDeptId),
|
||||
value: detail.undertakeDeptId,
|
||||
},
|
||||
];
|
||||
const undertakeDeptIds = this.parseUndertakeDeptIds(detail.undertakeDeptId);
|
||||
const undertakeDeptNames = this.parseUndertakeDeptNames(detail.undertakeDeptName);
|
||||
if (undertakeDeptIds.length) {
|
||||
this.platformCompanyOptions = undertakeDeptIds.map((id, index) => ({
|
||||
label: undertakeDeptNames[index] || String(id),
|
||||
value: id,
|
||||
}));
|
||||
}
|
||||
},
|
||||
resolvePublicDictOptions(options, currentValue) {
|
||||
@@ -1860,6 +1871,8 @@ export default {
|
||||
this.form = {
|
||||
...form,
|
||||
...situation,
|
||||
undertakeDeptId: this.parseUndertakeDeptIds(form.undertakeDeptId),
|
||||
undertakeDeptName: form.undertakeDeptName || '',
|
||||
customerNames: this.getCustomerRowNames(customerRows, 'customer') || form.customerNames,
|
||||
carrierNames: this.getCustomerRowNames(carrierRows, 'carrier') || form.carrierNames,
|
||||
};
|
||||
@@ -2026,8 +2039,13 @@ export default {
|
||||
});
|
||||
},
|
||||
normalizeSubmitForm(options = {}) {
|
||||
const undertakeDeptIds = this.parseUndertakeDeptIds(this.form.undertakeDeptId);
|
||||
const undertakeDeptName =
|
||||
this.resolveUndertakeDeptNames(undertakeDeptIds) || this.form.undertakeDeptName || '';
|
||||
const submitRow = {
|
||||
...this.form,
|
||||
undertakeDeptId: undertakeDeptIds.join(','),
|
||||
undertakeDeptName,
|
||||
fundLimit: this.formatAmount(this.form.fundLimit),
|
||||
receivableLimit: this.formatAmount(this.form.receivableLimit),
|
||||
...Object.fromEntries(
|
||||
@@ -2419,11 +2437,40 @@ export default {
|
||||
this.$refs.projectForm?.validateField('businessDeptId');
|
||||
},
|
||||
handleUndertakeDeptChange(value) {
|
||||
const id = Array.isArray(value) ? value.at(-1) : value;
|
||||
const dept = this.platformCompanyOptions.find(item => String(item.value) === String(id));
|
||||
this.form.undertakeDeptName = dept ? dept.label : '';
|
||||
const ids = this.parseUndertakeDeptIds(value);
|
||||
this.form.undertakeDeptId = ids;
|
||||
this.form.undertakeDeptName = this.resolveUndertakeDeptNames(ids);
|
||||
this.$refs.projectForm?.validateField('undertakeDeptId');
|
||||
},
|
||||
parseUndertakeDeptIds(value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value
|
||||
.map(item => String(item ?? '').trim())
|
||||
.filter(item => item && item !== '-1');
|
||||
}
|
||||
return String(value ?? '')
|
||||
.split(/[,,]/)
|
||||
.map(item => item.trim())
|
||||
.filter(item => item && item !== '-1');
|
||||
},
|
||||
parseUndertakeDeptNames(value) {
|
||||
return String(value ?? '')
|
||||
.split(/[,,、]/)
|
||||
.map(item => item.trim())
|
||||
.filter(Boolean);
|
||||
},
|
||||
resolveUndertakeDeptNames(ids = []) {
|
||||
return ids
|
||||
.map(id => {
|
||||
const dept = this.platformCompanyOptions.find(item => String(item.value) === String(id));
|
||||
return dept?.label || '';
|
||||
})
|
||||
.filter(Boolean)
|
||||
.join('、');
|
||||
},
|
||||
firstUndertakeDeptId(value) {
|
||||
return this.parseUndertakeDeptIds(value)[0] || '';
|
||||
},
|
||||
// 由部门 id 反查「根 → 该节点」的 id 路径,供级联回显(找不到返回 null)
|
||||
findDeptPath(id, tree = [], parents = []) {
|
||||
const target = Array.isArray(id) ? id.at(-1) : id;
|
||||
@@ -2462,15 +2509,23 @@ export default {
|
||||
});
|
||||
},
|
||||
ensureCurrentPlatformOption() {
|
||||
const id = this.form.undertakeDeptId;
|
||||
if (!id) return;
|
||||
const exists = this.platformCompanyOptions.some(item => String(item.value) === String(id));
|
||||
if (!exists) {
|
||||
this.platformCompanyOptions.unshift({
|
||||
label: this.form.undertakeDeptName || String(id),
|
||||
value: id,
|
||||
});
|
||||
}
|
||||
const ids = this.parseUndertakeDeptIds(this.form.undertakeDeptId);
|
||||
if (!ids.length) return;
|
||||
const names = this.parseUndertakeDeptNames(this.form.undertakeDeptName);
|
||||
ids.forEach((id, index) => {
|
||||
const exists = this.platformCompanyOptions.some(item => String(item.value) === String(id));
|
||||
if (!exists) {
|
||||
this.platformCompanyOptions.unshift({
|
||||
label: names[index] || String(id),
|
||||
value: id,
|
||||
});
|
||||
}
|
||||
});
|
||||
// 选项 value 与已选 ID 类型对齐,避免回显失败
|
||||
this.form.undertakeDeptId = ids.map(id => {
|
||||
const matched = this.platformCompanyOptions.find(item => String(item.value) === String(id));
|
||||
return matched ? matched.value : id;
|
||||
});
|
||||
},
|
||||
excludeExternalOrganization(list = []) {
|
||||
return list.reduce((result, item) => {
|
||||
|
||||
Reference in New Issue
Block a user