diff --git a/src/views/contract/launch/components/ContractPartyPlaceholderModal.vue b/src/views/contract/launch/components/ContractPartyPlaceholderModal.vue index e403e4d..43750cf 100644 --- a/src/views/contract/launch/components/ContractPartyPlaceholderModal.vue +++ b/src/views/contract/launch/components/ContractPartyPlaceholderModal.vue @@ -1080,12 +1080,9 @@ const paymentMethodOptions = [ { label: "银行转账(一次性结清)", value: "银行转账(一次性结清)" }, ]; -const SELF_COMPANY_NAME = "浙港物流平台有限公司"; const PARTY_ROLE_OUR = "OUR"; const PARTY_ROLE_OPPOSITE = "OPPOSITE"; -// ========== 工具函数 ========== - function formatDateTimeValue(value, endOfDay = false) { if (!value) return null; if (String(value).includes(" ")) return value; @@ -1354,7 +1351,6 @@ function normalizePartyState(partyState) { : [ { ...createEmptyParty(PARTY_ROLE_OUR, 0), - companyName: SELF_COMPANY_NAME, }, ]; const counterpartyList = normalizePartyArray( @@ -1467,7 +1463,6 @@ function createContractFormData() { ourPartyList: [ { ...createEmptyParty(PARTY_ROLE_OUR, 0), - companyName: SELF_COMPANY_NAME, }, ], counterpartyList: [], @@ -2446,7 +2441,7 @@ function applySelfProfile(profile = {}) { createEmptyParty(PARTY_ROLE_OUR, 0); currentSelfParty.value = { ...createEmptyParty(PARTY_ROLE_OUR, 0), - companyName: profile.orgName || SELF_COMPANY_NAME, + companyName: profile.orgName || "", subjectCode: profile.id || "", contactPhone: profile.contactPhone || "", contactEmail: profile.contactEmail || "", @@ -2458,9 +2453,9 @@ function applySelfProfile(profile = {}) { creditCode: profile.creditCode || "", }; const shouldHydrateFirstParty = - !firstOurParty.companyName || - firstOurParty.companyName === SELF_COMPANY_NAME || - firstOurParty.companyName === profile.orgName; + (!firstOurParty.companyName && !firstOurParty.subjectCode) || + firstOurParty.companyName === profile.orgName || + (profile.id && firstOurParty.subjectCode === profile.id); if (!shouldHydrateFirstParty) { return; } diff --git a/src/views/contract/launch/components/ContractTemplateFillDemoModal.vue b/src/views/contract/launch/components/ContractTemplateFillDemoModal.vue index 64751ed..03907ca 100644 --- a/src/views/contract/launch/components/ContractTemplateFillDemoModal.vue +++ b/src/views/contract/launch/components/ContractTemplateFillDemoModal.vue @@ -198,44 +198,14 @@ import { loadTemplateFieldList, } from "../../shared/templateFieldDict.js"; import { - contractSourceOptions, - contractTypeOptions, - currencyOptions, - dateTypeOptions, extraAmountFieldOptions, - getOptionLabel, - isElectronOptions, - paymentDirectionOptions, - sealTypeOptions, - textSourceOptions, - valuationModeOptions, } from "../contractLaunchOptions.js"; -// ======================================================================== -// 以下为表单模型 + 字典 + 工具函数,直接内联在此文件中。 -// 接入后端时,可保留这些函数,将入参来源/出参提交替换为真实接口即可。 -// ======================================================================== - -// ========== 创建方式选项 ========== const contractCreateModeOptions = [ { label: "模板创建", value: "template" }, { label: "手动创建", value: "manual" }, ]; -// ========== 格式化合同金额(如 368,000.00 元) ========== -function formatContractAmount(value) { - if (value === undefined || value === null || value === "") return ""; - return `${new Intl.NumberFormat("zh-CN", { - minimumFractionDigits: 2, - maximumFractionDigits: 2, - }).format(Number(value))} 元`; -} - -function getContractPeriodTypeLabel(value) { - if (value === "1") return "无固定期限"; - return "固定期限"; -} - function normalizeFileItem(item = {}) { return { uid: @@ -288,25 +258,6 @@ function splitFilesByCategory(source = {}) { }; } -function formatFileSummary(fileList = []) { - return fileList.length - ? fileList - .map((item) => item.name || item.fileName) - .filter(Boolean) - .join(";") - : "暂无附件"; -} - -function buildExtraAmountSummary(extraAmounts = {}) { - const parts = extraAmountFieldOptions - .filter((item) => extraAmounts[`${item.key}Enabled`]) - .map( - (item) => - `${item.label}${formatContractAmount(extraAmounts[item.key]) || "0.00 元"}`, - ); - return parts.length ? parts.join(";") : "无"; -} - function restoreExtraAmounts(source = {}, current = {}) { const result = { ...current, ...(source.extraAmounts || {}) }; const selectedCodes = String(source.ewAmountType || "") @@ -328,30 +279,9 @@ function restoreExtraAmounts(source = {}, current = {}) { return result; } -function buildPerformancePlanSummary(list = []) { - if (!list.length) return "暂无履行计划"; - return list - .map((item, index) => { - const money = - item.planMoney || item.planMoney === 0 - ? `,金额${formatContractAmount(item.planMoney)}` - : ""; - return `${index + 1}. ${item.planMatter || "未填写事项"},${item.planWhere || "未填写条件"},${item.planTime || "未填写日期"}${money}`; - }) - .join("\n"); -} -// ========== 合同方相关函数 ========== const PARTY_ROLE_OUR = "OUR"; const PARTY_ROLE_OPPOSITE = "OPPOSITE"; -const PARTY_NAME_KEYS = [ - "partyAName", - "partyBName", - "partyCName", - "partyDName", - "partyEName", - "partyFName", -]; function createParty(roleCode = PARTY_ROLE_OPPOSITE, index = 0) { return { @@ -456,71 +386,6 @@ function buildPartyStateFromList(list = []) { state.isThreePartyContract = state.counterpartyList.length > 1; return state; } - -/** 获取有效的合同方列表 */ -function getPartyList(partyState) { - const state = copyPartyState(partyState); - return [ - ...(state.ourPartyList || []), - ...(state.counterpartyList || []), - ].filter((item) => item && String(item.companyName || "").trim() !== ""); -} - -/** 获取合同方摘要(如 "甲方:xxx;乙方:xxx") */ -function getPartySummary(partyState) { - return getPartyList(partyState) - .map( - (item) => `${item.roleName || "未知"}:${item.companyName || "未填写"}`, - ) - .join(";"); -} - -/** 构建推送法务系统的相对方信息列表(排除甲方) */ -function buildContractOpposites(partyState) { - return getPartyList(partyState) - .filter((item) => item.roleCode === PARTY_ROLE_OPPOSITE) - .map((item) => ({ - roleName: item.roleName, - oppositeName: item.companyName, - oppCharacter: item.oppCharacter || "QY", - credirCode: item.oppCharacter === "QY" ? item.creditCode : "", - idCard: item.oppCharacter === "ZZR" ? item.naturalPersonIdNumber : "", - companyType: item.companyType, - companyNature: item.companyNature, - contactName: item.contactName, - contactPhone: item.contactPhone, - contactEmail: item.contactEmail, - })); -} - -/** 构建合同方同步列表(用于推送法务) */ -function buildPartySyncList(partyState) { - return getPartyList(partyState).map((item) => ({ - roleCode: item.roleCode, - roleName: item.roleName, - companyName: item.companyName, - oppCharacter: item.oppCharacter, - companyType: item.companyType, - companyNature: item.companyNature, - organizationNature: item.organizationNature, - enterpriseNatureLevel2: item.enterpriseNatureLevel2, - isHongKongMacaoTaiwan: item.isHongKongMacaoTaiwan ? 1 : 0, - isGroupInternal: item.isGroupInternal ? 1 : 0, - creditCode: item.creditCode, - naturalPersonIdType: item.naturalPersonIdType, - naturalPersonIdNumber: item.naturalPersonIdNumber, - legalRepresentative: item.legalRepresentative, - registeredAddress: item.registeredAddress, - contactName: item.contactName, - contactPhone: item.contactPhone, - contactEmail: item.contactEmail, - bankName: item.bankName, - bankAccount: item.bankAccount, - })); -} - -// ========== 履行计划 ========== - /** 创建一条空的履行计划 */ function createPerformancePlan() { return { @@ -535,10 +400,6 @@ function createPerformancePlan() { planDetail: "", }; } - -// ========== 合同发起表单数据模型 ========== - -/** 创建空白的合同表单数据 */ function createContractFormData() { return { id: null, @@ -738,9 +599,6 @@ function copyContractFormData(data = {}) { return form; } -// ========== 模板变量预览数据构建 ========== - -/** 将合同表单数据转换为模板变量字典(用于 docxtemplater 渲染) */ function buildTemplateRenderData(templateFieldValues = {}) { const data = {}; (templateFieldList.value || []).forEach((item) => { @@ -749,99 +607,10 @@ function buildTemplateRenderData(templateFieldValues = {}) { return data; } -// ========== 提交报文构建 ========== - -/** 构建推送法务系统的合同报文 */ -function buildContractSubmitPayload(formData, extra = {}) { - const form = copyContractFormData(formData); - - return { - creationMode: extra.creationMode || "template", - templateKey: extra.templateKey || "", - templateName: extra.templateName || "", - basicInfo: { - contractName: form.contractName, - contractCode: form.contractCode, - contractType: form.contractType, - contractTypeCode: form.contractTypeCode, - contractAmount: form.contractAmount, - effectiveStart: form.effectiveStart, - effectiveEnd: form.effectiveEnd, - contractPeriodType: form.contractPeriodType, - periodExplain: form.periodExplain, - paymentMethod: form.paymentMethod, - paymentDirection: form.paymentDirection, - isElectron: form.isElectron, - textSource: form.textSource, - contractSource: form.contractSource, - dateType: form.dateType, - valuationMode: form.valuationMode, - currencyName: form.currencyName, - sealType: form.sealType, - mandateType: form.mandateType, - cargoType: form.cargoType, - primaryContent: form.primaryContent, - amountExplain: form.amountExplain, - contractGistRemark: form.contractGistRemark, - bodySummary: form.bodySummary, - assistDept: form.assistDept, - executorAccount: form.executorAccount, - selfCode: form.selfCode, - mainContractCode: form.mainContractCode, - signingSubjectCode: - (form.partyState.ourPartyList || []) - .map((item) => String(item.subjectCode || "").trim()) - .filter(Boolean) - .join(",") || form.signingSubjectCode, - invoiceDate: form.invoiceDate, - receiveDate: form.receiveDate, - }, - partyMaintenance: { - isThreePartyContract: form.partyState.isThreePartyContract ? 1 : 0, - parties: buildPartySyncList(form.partyState), - }, - pushContractPayloadPreview: { - contractName: form.contractName, - contractTypeCode: form.contractTypeCode, - contractPeriod: form.contractPeriodType, - startTime: form.effectiveStart, - endTime: form.effectiveEnd, - periodExplain: form.periodExplain, - dateType: form.dateType, - valuationMode: form.valuationMode, - currencyName: form.currencyName, - sealType: form.sealType, - isText: form.textSource, - isElectron: form.isElectron, - paymentDirection: form.paymentDirection, - primaryContent: form.primaryContent, - amountExplain: form.amountExplain, - contractGistRemark: form.contractGistRemark, - isMajorContract: form.isMajorContract ? 1 : 0, - contractOpposites: buildContractOpposites(form.partyState), - otherAttach: form.otherAttachmentList.map((item) => ({ - fileName: item.name || item.fileName, - filePath: item.filePath, - fileType: item.fileType, - fileSize: item.size ?? item.fileSize, - })), - contractGistFile: form.contractGistFileList.map((item) => ({ - fileName: item.name || item.fileName, - filePath: item.filePath, - fileType: item.fileType, - fileSize: item.size ?? item.fileSize, - })), - contractBodyFileName: form.contractBodyFileName, - performancePlans: form.performancePlans, - }, - }; -} - const emit = defineEmits(["save"]); const visible = ref(false); const previewRef = ref(null); -const formRef = ref(null); const modalMode = ref("create"); const creationMode = ref("template"); const templateKey = ref(""); @@ -933,6 +702,20 @@ const emptyPreviewText = computed(() => : "请选择模板并完善模板变量后再预览。", ); +watch( + () => templateKey.value, + (value, prevValue) => { + if (value === prevValue) return; + previewBlob.value = null; + previewError.value = ""; + if (visible.value && creationMode.value === "template") { + nextTick(() => { + schedulePreview(); + }); + } + }, +); + watch( () => visible.value, (open) => { @@ -1030,6 +813,7 @@ function clearPreviewTimer() { } async function fetchTemplateBuffer(templateFilePath) { + const cached = templateBufferCache.get(templateFilePath); if (cached) { return cached.slice(0); diff --git a/src/views/contract/manifest/components/ContractTemplateManageModal.vue b/src/views/contract/manifest/components/ContractTemplateManageModal.vue index 4264bc7..4fd5f81 100644 --- a/src/views/contract/manifest/components/ContractTemplateManageModal.vue +++ b/src/views/contract/manifest/components/ContractTemplateManageModal.vue @@ -514,19 +514,6 @@ function resolveUploadedFilePath(res) { return '' } -async function readDocxArrayBuffer(source) { - if (!source) return null - - if (source instanceof ArrayBuffer) { - return source.slice(0) - } - - if (source.arrayBuffer) { - return await source.arrayBuffer() - } - - return null -} function extractVariablesFromText(text) { const result = new Set()