From 0b578df215da5869e2825237bbfb8fa94d22492e Mon Sep 17 00:00:00 2001 From: zhouxiaofeng <2946471396@qq.com> Date: Tue, 30 Jun 2026 09:54:17 +0800 Subject: [PATCH] 11 --- src/api/launch.js | 8 + .../components/ContractCollectModal.vue | 348 ++++++++++++++++++ .../ContractPartyPlaceholderModal.vue | 182 ++++----- src/views/contract/launch/index.vue | 69 +++- 4 files changed, 508 insertions(+), 99 deletions(-) create mode 100644 src/views/contract/launch/components/ContractCollectModal.vue diff --git a/src/api/launch.js b/src/api/launch.js index f3fb418..75ab817 100644 --- a/src/api/launch.js +++ b/src/api/launch.js @@ -121,6 +121,14 @@ export function mockCollectLaunch(id) { }); } +export function saveContractCollectInfo(id, data) { + return request({ + url: `/contract/launch/${id}/collect/save`, + method: "post", + data, + }); +} + export function archiveLaunch(id, data = {}) { return request({ url: `/contract/launch/${id}/archive`, diff --git a/src/views/contract/launch/components/ContractCollectModal.vue b/src/views/contract/launch/components/ContractCollectModal.vue new file mode 100644 index 0000000..a1f9967 --- /dev/null +++ b/src/views/contract/launch/components/ContractCollectModal.vue @@ -0,0 +1,348 @@ + + + + + diff --git a/src/views/contract/launch/components/ContractPartyPlaceholderModal.vue b/src/views/contract/launch/components/ContractPartyPlaceholderModal.vue index 7386a28..708562f 100644 --- a/src/views/contract/launch/components/ContractPartyPlaceholderModal.vue +++ b/src/views/contract/launch/components/ContractPartyPlaceholderModal.vue @@ -691,39 +691,7 @@ placeholder="选填,用于应收账款提醒" /> - - - - - - - - - - - - +
@@ -794,20 +762,7 @@
-
- 是否用印 - - - - -
-
- 审批是否一致 - - - - -
+
@@ -866,7 +821,7 @@ :data-source="detailState.performancePlans" :pagination="false" size="small" - :scroll="{ x: 820 }" + :scroll="{ x: 780 }" row-key="id" class="plan-table" > @@ -926,27 +881,20 @@ /> - - - @@ -1471,12 +1419,6 @@ function createContractFormData() { yfkAmount: 0, bzjAmount: 0, performancePlans: [], - signDate: "", - sealDate: "", - activeDate: "", - sealQuantity: 1, - sealIsSeal: "1", - sealApproveSame: "1", }; } @@ -1534,11 +1476,8 @@ function copyContractFormData(data = {}) { : null : null; } else if ( - key === "signDate" || - key === "sealDate" || key === "invoiceDate" || - key === "receiveDate" || - key === "activeDate" + key === "receiveDate" ) { form[key] = source[key] ? String(source[key]).slice(0, 10) : form[key]; } else if (key === "assistDept") { @@ -2026,7 +1965,7 @@ function handleBodyConfigSave(payload = {}) { syncUploadLists(); if (modalMode.value === "edit" && detailState.value.id) { - const errorMessage = validateState(); + const errorMessage = validateDraft(); if (errorMessage) { message.success( "合同正文配置已保存到当前页面,请继续完善主信息后再保存合同草稿。", @@ -2064,7 +2003,85 @@ function removePerformancePlan(id) { detailState.value.performancePlans.filter((item) => item.id !== id); } -function validateState() { +/** 草稿保存校验(宽松):仅校验必填核心字段 */ +function validateDraft() { + if ( + !ourParties.value.length || + ourParties.value.some((party) => !party.companyName?.trim()) + ) + return "请确认我方信息"; + if ( + currentSelfSubjectCode.value && + !ourParties.value.some( + (party) => + String(party.subjectCode || "").trim() === currentSelfSubjectCode.value, + ) + ) { + return "当前登录主体必须包含在我方主体中"; + } + if ( + isSingleAgreementChecked.value && + currentSelfSubjectCode.value && + ourParties.value.some( + (party) => + String(party.subjectCode || "").trim() !== currentSelfSubjectCode.value, + ) + ) { + return "单方协议仅允许使用当前登录主体"; + } + if (!isSingleAgreementChecked.value && !counterpartyParties.value.length) + return "请至少添加一个相对方"; + if ( + !isSingleAgreementChecked.value && + counterpartyParties.value.some((party) => !party.companyName?.trim()) + ) + return "请选择相对方"; + if (!detailState.value.contractName?.trim()) return "请填写合同名称"; + if (!detailState.value.contractTypeCode) return "请选择合同类型"; + if ( + detailState.value.contractPeriodType === "0" && + (!detailState.value.effectiveStart || !detailState.value.effectiveEnd) + ) + return "请选择固定期限起止日期"; + if ( + detailState.value.contractPeriodType === "1" && + !detailState.value.periodExplain?.trim() + ) + return "请填写期限说明"; + if (!detailState.value.contractBodyFileName?.trim()) + return "请先配置合同正文"; + if ( + !isSingleAgreementChecked.value && + requiresAuthAttachment.value && + !(detailState.value.authAttachmentList || []).length + ) + return "请上传授权委托书附件"; + // 履行计划:草稿保存时即要求至少一条且字段完整 + if (!(detailState.value.performancePlans || []).length) + return "请至少添加一条履行计划"; + for (const plan of detailState.value.performancePlans || []) { + if (!plan.planMatter?.trim()) return "请填写履行计划的履行事项"; + if (!plan.planWhere?.trim()) return "请填写履行计划的履约条件"; + if (!plan.planTime) return "请选择履行计划的节点日期"; + if ( + plan.planDay === null || + plan.planDay === undefined || + plan.planDay === "" + ) + return "请填写履行计划的提醒提前天数"; + if ( + !["0", "3"].includes(detailState.value.valuationMode) && + (plan.planMoney === null || + plan.planMoney === undefined || + plan.planMoney === "") + ) + return "请填写履行计划的款项金额"; + } + return ""; +} + +/** 提交法务校验(严格):补全 pushContract 所有必填项 + 履行计划 */ +function validateSubmit() { if ( !ourParties.value.length || ourParties.value.some((party) => !party.companyName?.trim()) @@ -2143,6 +2160,13 @@ function validateState() { detailState.value.needAmendments === "" ) return "请选择是否需修订条款"; + // 以下为 pushContract 必填项补充校验(接口文档要求) + if (detailState.value.isMajorContract === undefined || detailState.value.isMajorContract === null || detailState.value.isMajorContract === "") + return "请选择是否重大合同"; + if (detailState.value.isPublicTender === undefined || detailState.value.isPublicTender === null) + return "请选择是否公开招标"; + if (detailState.value.isInvolveHongKongMacaoTaiwan === undefined || detailState.value.isInvolveHongKongMacaoTaiwan === null) + return "请选择是否涉及港澳台"; if (!detailState.value.paymentDirection) return "请选择收支方向"; if (!detailState.value.contractTypeCode) return "请选择合同类型编码"; if (!detailState.value.executorAccount?.trim()) return "请填写合同执行人"; @@ -2180,7 +2204,7 @@ function validateState() { } function handleSave() { - const errorMessage = validateState(); + const errorMessage = validateDraft(); if (errorMessage) { message.warning(errorMessage); return; @@ -2359,14 +2383,8 @@ function buildLaunchRecord() { contractTextFilePath: detailState.value.contractBodyFilePath || "", contractTextFileType: detailState.value.contractBodyFileType || "docx", contractTextFileSize: detailState.value.contractBodyFileSize || null, - signDate: formatDateTimeValue(detailState.value.signDate), - sealDate: formatDateTimeValue(detailState.value.sealDate), invoiceDate: formatDateTimeValue(detailState.value.invoiceDate), receiveDate: formatDateTimeValue(detailState.value.receiveDate), - activeDate: formatDateTimeValue(detailState.value.activeDate), - sealQuantity: detailState.value.sealQuantity, - sealIsSeal: detailState.value.sealIsSeal || "1", - sealApproveSame: detailState.value.sealApproveSame || "1", templateFieldValuesJson: JSON.stringify( detailState.value.templateFieldValues || {}, ), diff --git a/src/views/contract/launch/index.vue b/src/views/contract/launch/index.vue index b451eff..d33435a 100644 --- a/src/views/contract/launch/index.vue +++ b/src/views/contract/launch/index.vue @@ -247,7 +247,7 @@ }} {{ - isSingleAgreementRecord(row) ? "测试生效" : "测试采集" + isSingleAgreementRecord(row) ? "测试生效" : "合同采集" }} {{ isSingleAgreementRecord(row) ? "办结" : "归档" @@ -278,6 +278,10 @@ ref="contractModalRef" @save="handleModalSave" /> + { + if (!isSuccessResponse(res) || !getDataResult(res)) { + message.error(getResponseMessage(res, "获取合同详情失败")); + return; + } + const detail = getDataResult(res); + const missingFields = []; + if (!detail.contractTypeCode) missingFields.push("合同类型"); + if (!detail.valuationMode) missingFields.push("计价方式"); + if (!detail.currencyName) missingFields.push("币种"); + if (!detail.sealType) missingFields.push("签订方式"); + if (!detail.isElectron) missingFields.push("签署方式"); + if (!detail.paymentDirection) missingFields.push("收支方向"); + if (!detail.textSource) missingFields.push("文本来源"); + if (!detail.contractSource) missingFields.push("合同来源"); + if (!detail.executorAccount) missingFields.push("合同执行人"); + if (detail.isMajorContract === null || detail.isMajorContract === undefined) missingFields.push("是否重大合同"); + if (detail.isOpenBidding === null || detail.isOpenBidding === undefined) missingFields.push("是否公开招标"); + if (detail.isSgat === null || detail.isSgat === undefined) missingFields.push("是否涉及港澳台"); + if (!detail.performancePlans || !detail.performancePlans.length) missingFields.push("履行计划"); + if (!detail.contractTextFileName) missingFields.push("合同正文"); + if (missingFields.length) { + message.warning(`以下必填项不完整,请先在编辑草稿中补全后再提交:\n${missingFields.join("、")}`); + return; + } + showSubmitConfirm(row, detail, false); + }); + } + // 单方协议:直接提交内部审批 + showSubmitConfirm(row, null, true); +} + +function showSubmitConfirm(row, detail, singleAgreement) { Modal.confirm({ title: singleAgreement ? "确认提交内部审批" : "确认提交法务审批", content: h("div", [ @@ -1032,24 +1072,19 @@ function handleModalSave(payload) { } function handleMockCollect(row) { - Modal.confirm({ - title: "测试操作:模拟合同采集", - content: `模拟将合同【${row.contractName}】信息采集同步至法务系统,状态将变为「待归档」。`, - okText: "确认模拟", - cancelText: "取消", - onOk: () => - mockCollectLaunch(row.id).then((res) => { - if (!isSuccessResponse(res)) { - message.error(getResponseMessage(res, "模拟合同采集失败")); - return; - } - message.success("测试合同采集完成,合同已流转到待归档"); - getList(); - }), - icon: null, + getLaunchDetail(row.id).then((res) => { + if (!isSuccessResponse(res) || !getDataResult(res)) { + message.error(getResponseMessage(res, "获取合同详情失败")); + return; + } + contractCollectModalRef.value?.showModal(getDataResult(res)); }); } +function handleCollectDone() { + getList(); +} + function handleArchive(row) { getLaunchDetail(row.id).then((res) => { if (!isSuccessResponse(res) || !getDataResult(res)) {