This commit is contained in:
2026-06-30 09:54:17 +08:00
parent 2326752b5d
commit 0b578df215
4 changed files with 508 additions and 99 deletions
@@ -691,39 +691,7 @@
placeholder="选填,用于应收账款提醒"
/>
</a-form-item>
<a-form-item class="tight-item" label="签订日期">
<a-date-picker
v-model:value="detailState.signDate"
value-format="YYYY-MM-DD"
style="width: 100%"
placeholder="签署完成前需补齐"
/>
</a-form-item>
<a-form-item class="tight-item" label="用印时间">
<a-date-picker
v-model:value="detailState.sealDate"
value-format="YYYY-MM-DD"
style="width: 100%"
placeholder="签署完成前需补齐"
/>
</a-form-item>
<a-form-item class="tight-item" label="合同生效日期">
<a-date-picker
v-model:value="detailState.activeDate"
value-format="YYYY-MM-DD"
style="width: 100%"
placeholder="必填,且必须在合同期限范围内"
/>
</a-form-item>
<a-form-item class="tight-item" label="用印数量">
<a-input-number
v-model:value="detailState.sealQuantity"
:min="1"
:precision="0"
style="width: 100%"
placeholder="默认1份"
/>
</a-form-item>
</div>
<div class="boolean-grid">
@@ -794,20 +762,7 @@
<a-radio value="0">否</a-radio>
</a-radio-group>
</div>
<div class="boolean-row">
<span>是否用印</span>
<a-radio-group v-model:value="detailState.sealIsSeal">
<a-radio value="1">是</a-radio>
<a-radio value="0">否</a-radio>
</a-radio-group>
</div>
<div class="boolean-row">
<span>审批是否一致</span>
<a-radio-group v-model:value="detailState.sealApproveSame">
<a-radio value="1">是</a-radio>
<a-radio value="0">否</a-radio>
</a-radio-group>
</div>
</div>
<div class="extra-amount-section">
@@ -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 @@
/>
</template>
</a-table-column>
<a-table-column
title="所属主体编码"
key="planSubjectCode"
width="160"
>
<template #default="{ record }">
<a-input
v-model:value="record.planSubjectCode"
placeholder="所属主体机构编码"
/>
</template>
</a-table-column>
<a-table-column
title="所属主体"
key="planSubjectName"
width="180"
width="200"
>
<template #default="{ record }">
<a-input
<a-select
v-model:value="record.planSubjectName"
placeholder="所属主体名称"
:options="ourParties.map(p => ({ label: `${p.companyName} (${p.subjectCode})`, value: p.companyName, subjectCode: p.subjectCode }))"
allow-clear
placeholder="从已选我方主体中选择"
:disabled="!ourParties.length"
style="width: 100%"
@change="(value, option) => { record.planSubjectCode = option?.subjectCode || ''; }"
/>
</template>
</a-table-column>
@@ -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 || {},
),