diff --git a/contract-dialog-debug.html b/contract-dialog-debug.html deleted file mode 100644 index 3fab89c..0000000 --- a/contract-dialog-debug.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - 合同弹窗调试 - - -
- - - diff --git a/src/api/business/contract-manage.js b/src/api/business/contract-manage.js index 275800c..6010d39 100644 --- a/src/api/business/contract-manage.js +++ b/src/api/business/contract-manage.js @@ -59,14 +59,14 @@ export const withdraw = id => params: { id }, }); -export const startChange = (id, reason) => +export const startChange = (id, changeContent, changeReason = changeContent) => request({ url: `${baseUrl}/start-change`, method: 'post', params: { id, - changeContent: reason, - changeReason: reason, + changeContent: changeContent || '', + changeReason, }, }); diff --git a/src/components/pdf-preview/main.vue b/src/components/pdf-preview/main.vue index 934eefe..42b223f 100644 --- a/src/components/pdf-preview/main.vue +++ b/src/components/pdf-preview/main.vue @@ -15,10 +15,12 @@ diff --git a/src/views/business/contract-manage.vue b/src/views/business/contract-manage.vue index 5fcb0b7..750472b 100644 --- a/src/views/business/contract-manage.vue +++ b/src/views/business/contract-manage.vue @@ -769,7 +769,7 @@ 查看详情 @@ -780,6 +780,46 @@ > + +
+ 变更日期:{{ detailChangeRecord.changeDate || '-' }} + 经办人:{{ detailChangeRecord.handlerUserName || '-' }} + 变更类型:{{ detailChangeRecord.changeType || '-' }} + 状态:{{ detailChangeRecord.statusName || detailChangeRecord.status || '-' }} +
+ + + + + + + +
+ { const saved = res.data?.data || {}; const id = saved.id || this.form.id; - if (action === 'formal') { - if (!id) throw new Error('合同保存成功但未返回主键,无法提交正式合同'); - return this.api.submitFormal(id); + if (action === 'temporary' || action === 'formal') { + if (!id) throw new Error('合同保存成功但未返回主键,无法提交合同'); + return action === 'temporary' + ? this.api.toTemporary(id) + : this.api.submitFormal(id); } return null; }) @@ -2104,6 +2149,116 @@ export default { this.detailBillingPlanIndex = index; this.detailBillingPlanBox = true; }, + parseChangeRecordData(value) { + if (!value) return {}; + if (typeof value === 'object') return value; + try { + const data = JSON.parse(value); + return data && typeof data === 'object' && !Array.isArray(data) ? data : {}; + } catch (error) { + return {}; + } + }, + normalizeChangeRecordValue(value) { + if (typeof value !== 'string') return value; + const text = value.trim(); + if (!text || (!text.startsWith('[') && !text.startsWith('{') && text !== 'null')) { + return value; + } + try { + return JSON.parse(text); + } catch (error) { + return value; + } + }, + isEmptyChangeRecordValue(value) { + const normalized = this.normalizeChangeRecordValue(value); + if (normalized === undefined || normalized === null || normalized === '') return true; + if (Array.isArray(normalized)) return normalized.length === 0; + if (typeof normalized === 'object') return Object.keys(normalized).length === 0; + return false; + }, + getContractChangeFieldLabel(field) { + const labels = { + contractName: '合同名称', + partyB: '乙方', + startDate: '开始日期', + endDate: '结束日期', + contractFormat: '合同格式', + settlementMode: '结算方式', + legalSealFlag: '是否需要加盖法人章', + copyCount: '一式(份)', + settlementCurrency: '结算币种', + invoiceCycle: '开票周期', + paymentDays: '回款账期', + remark: '备注', + feeGenerationMode: '费用生成模式', + billingPlanJson: '计费方案', + settlementRuleJson: '结算单规则', + preSettlementConfigJson: '预结算配置', + formalSettlementConfigJson: '正式结算配置', + paymentRatioJson: '付款比例设置', + contractFileJson: '合同文件', + attachmentsJson: '其它附件', + changeAttachmentsJson: '变更材料', + }; + return labels[field] || field; + }, + formatChangeRecordAttachments(value) { + const attachments = Array.isArray(value) + ? value + : parseArray(typeof value === 'string' ? value : JSON.stringify(value || [])); + const names = attachments + .map(item => + typeof item === 'string' + ? item + : item?.originalName || item?.name || item?.fileName || item?.url || item?.link || '' + ) + .filter(Boolean); + return names.length ? names.join('、') : '空'; + }, + formatContractChangeValue(field, value) { + const normalized = this.normalizeChangeRecordValue(value); + if (this.isEmptyChangeRecordValue(normalized)) return '空'; + if (['contractFileJson', 'attachmentsJson', 'changeAttachmentsJson'].includes(field)) { + return this.formatChangeRecordAttachments(normalized); + } + if (field === 'legalSealFlag') return Number(normalized) === 1 ? '是' : '否'; + if (field === 'feeGenerationMode') return normalized === 'manual' ? '手动生成' : '系统生成'; + if (field === 'invoiceCycle' || field === 'paymentDays') return `${normalized}天`; + if (Array.isArray(normalized) || typeof normalized === 'object') { + return JSON.stringify(normalized); + } + return String(normalized); + }, + buildDetailChangeRecordRows(row = {}) { + const beforeData = this.parseChangeRecordData(row.beforeData); + const afterData = this.parseChangeRecordData(row.afterData); + const fields = [...new Set([...Object.keys(beforeData), ...Object.keys(afterData)])]; + const rows = fields + .filter( + field => + JSON.stringify(this.normalizeChangeRecordValue(beforeData[field])) !== + JSON.stringify(this.normalizeChangeRecordValue(afterData[field])) + ) + .map(field => ({ + field: this.getContractChangeFieldLabel(field), + before: this.formatContractChangeValue(field, beforeData[field]), + after: this.formatContractChangeValue(field, afterData[field]), + })); + if (row.changeContent) { + rows.unshift({ field: '变更内容', before: '空', after: row.changeContent }); + } + if (row.changeReason) { + rows.push({ field: '变更原因', before: '空', after: row.changeReason }); + } + return rows; + }, + openDetailChangeRecord(row) { + this.detailChangeRecord = row; + this.detailChangeRecordDetailRows = this.buildDetailChangeRecordRows(row); + this.detailChangeRecordVisible = true; + }, displayValue(value) { return value === undefined || value === null || value === '' ? '-' : value; }, @@ -2310,6 +2465,23 @@ export default { } } +.contract-change-record-detail-meta { + display: flex; + flex-wrap: wrap; + gap: 8px 32px; + margin-bottom: 16px; + color: #606266; +} + +:deep(.contract-change-record-detail-dialog .el-dialog__body) { + padding-top: 12px; +} + +:deep(.contract-change-record-detail-dialog .contract-change-record-detail-value .cell) { + white-space: pre-wrap; + word-break: break-all; +} + :global(.avue--collapse .contract-manage-page__footer) { left: 60px; } diff --git a/src/views/business/project-apply.vue b/src/views/business/project-apply.vue index 5f4165a..1fd5742 100644 --- a/src/views/business/project-apply.vue +++ b/src/views/business/project-apply.vue @@ -157,7 +157,7 @@ :disabled="isBasicInfoReadonly" /> - +
项目材料
+ + 未上传:{{ missingRequiredAttachmentTypes.join('、') }} + -