-
-
@@ -219,81 +214,84 @@ import {
// ========== 创建方式选项 ==========
const contractCreateModeOptions = [
- { label: '模板创建', value: 'template' },
- { label: '手动创建', value: 'manual' },
-]
+ { label: "模板创建", value: "template" },
+ { label: "手动创建", value: "manual" },
+];
// ========== 可绑定业务字段列表(用于映射下拉和展示) ==========
const templateFieldList = [
- { value: 'contractName', label: '合同名称' },
- { value: 'contractCode', label: '合同编码' },
- { value: 'contractType', label: '合同类型' },
- { value: 'contractAmountDisplay', label: '合同金额' },
- { value: 'effectiveStart', label: '有效期起' },
- { value: 'effectiveEnd', label: '有效期止' },
- { value: 'effectivePeriod', label: '有效期区间' },
- { value: 'paymentMethod', label: '付款方式' },
- { value: 'primaryContent', label: '合同标的说明' },
- { value: 'amountExplain', label: '金额说明' },
- { value: 'partyAName', label: '甲方名称' },
- { value: 'partyBName', label: '乙方名称' },
- { value: 'partyCName', label: '丙方名称' },
- { value: 'partyDName', label: '丁方名称' },
- { value: 'partyEName', label: '戊方名称' },
- { value: 'partyFName', label: '己方名称' },
- { value: 'counterpartySummary', label: '合同方摘要' },
- { value: 'attachmentSummary', label: '附件情况' },
- { value: 'templateLabel', label: '模板名称' },
- { value: 'signDate', label: '签署日期' },
- { value: 'businessRemark', label: '业务备注' },
- { value: 'contractSubject', label: '合同标的说明' },
-]
+ { value: "contractName", label: "合同名称" },
+ { value: "contractCode", label: "合同编码" },
+ { value: "contractType", label: "合同类型" },
+ { value: "contractAmountDisplay", label: "合同金额" },
+ { value: "effectiveStart", label: "有效期起" },
+ { value: "effectiveEnd", label: "有效期止" },
+ { value: "effectivePeriod", label: "有效期区间" },
+ { value: "paymentMethod", label: "付款方式" },
+ { value: "primaryContent", label: "合同标的说明" },
+ { value: "amountExplain", label: "金额说明" },
+ { value: "partyAName", label: "甲方名称" },
+ { value: "partyBName", label: "乙方名称" },
+ { value: "partyCName", label: "丙方名称" },
+ { value: "partyDName", label: "丁方名称" },
+ { value: "partyEName", label: "戊方名称" },
+ { value: "partyFName", label: "己方名称" },
+ { value: "counterpartySummary", label: "合同方摘要" },
+ { value: "attachmentSummary", label: "附件情况" },
+ { value: "templateLabel", label: "模板名称" },
+ { value: "signDate", label: "签署日期" },
+ { value: "businessRemark", label: "业务备注" },
+ { value: "contractSubject", label: "合同标的说明" },
+];
// ========== 格式化合同金额(如 368,000.00 元) ==========
function formatContractAmount(value) {
- if (value === undefined || value === null || value === '') return ''
- return `${new Intl.NumberFormat('zh-CN', {
+ if (value === undefined || value === null || value === "") return "";
+ return `${new Intl.NumberFormat("zh-CN", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
- }).format(Number(value))} 元`
+ }).format(Number(value))} 元`;
}
function getContractPeriodTypeLabel(value) {
- if (value === '1') return '无固定期限'
- return '固定期限'
+ if (value === "1") return "无固定期限";
+ return "固定期限";
}
function normalizeFileItem(item = {}) {
return {
- uid: item.uid || `file_${Date.now()}_${Math.random().toString(16).slice(2, 8)}`,
- name: item.name || item.fileName || '',
+ uid:
+ item.uid ||
+ `file_${Date.now()}_${Math.random().toString(16).slice(2, 8)}`,
+ name: item.name || item.fileName || "",
size: item.size ?? item.fileSize ?? 0,
- status: item.status || 'done',
- filePath: item.filePath || '',
- fileType: item.fileType || '',
- fileCategory: item.fileCategory || '',
- }
+ status: item.status || "done",
+ filePath: item.filePath || "",
+ fileType: item.fileType || "",
+ fileCategory: item.fileCategory || "",
+ };
}
function splitFilesByCategory(source = {}) {
- const sourceFiles = source.fileList || []
- const bodyFile = sourceFiles.find((item) => item.fileCategory === 'body') || {}
+ const sourceFiles = source.fileList || [];
+ const bodyFile =
+ sourceFiles.find((item) => item.fileCategory === "body") || {};
return {
contractBodyFileName:
source.contractBodyFileName ||
source.contractTextFileName ||
bodyFile.fileName ||
- '',
+ "",
contractBodyFilePath:
source.contractBodyFilePath ||
source.contractTextFilePath ||
bodyFile.filePath ||
- '',
+ "",
contractBodyFileType:
source.contractBodyFileType ||
source.contractTextFileType ||
bodyFile.fileType ||
- '',
+ "",
contractBodyFileSize:
source.contractBodyFileSize ??
source.contractTextFileSize ??
@@ -302,182 +300,225 @@ function splitFilesByCategory(source = {}) {
otherAttachmentList: source.otherAttachmentList?.length
? source.otherAttachmentList.map(normalizeFileItem)
: sourceFiles
- .filter((item) => item.fileCategory === 'other')
+ .filter((item) => item.fileCategory === "other")
.map(normalizeFileItem),
contractGistFileList: source.contractGistFileList?.length
? source.contractGistFileList.map(normalizeFileItem)
: sourceFiles
- .filter((item) => item.fileCategory === 'gist')
+ .filter((item) => item.fileCategory === "gist")
.map(normalizeFileItem),
- }
+ };
}
function formatFileSummary(fileList = []) {
return fileList.length
- ? fileList.map((item) => item.name || item.fileName).filter(Boolean).join(';')
- : '暂无附件'
+ ? 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(';') : '无'
+ .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 || '')
- .split(',')
+ const result = { ...current, ...(source.extraAmounts || {}) };
+ const selectedCodes = String(source.ewAmountType || "")
+ .split(",")
.map((item) => item.trim())
- .filter(Boolean)
+ .filter(Boolean);
extraAmountFieldOptions.forEach((item) => {
- const amount = source[item.amountField]
+ const amount = source[item.amountField];
if (selectedCodes.includes(item.code) || amount || amount === 0) {
- result[`${item.key}Enabled`] = selectedCodes.includes(item.code) || amount > 0
+ result[`${item.key}Enabled`] =
+ selectedCodes.includes(item.code) || amount > 0;
if (amount !== undefined && amount !== null) {
- result[item.key] = amount
+ result[item.key] = amount;
}
}
- })
+ });
- return result
+ return result;
}
function buildPerformancePlanSummary(list = []) {
- if (!list.length) return '暂无履行计划'
+ 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}`
+ const money =
+ item.planMoney || item.planMoney === 0
+ ? `,金额${formatContractAmount(item.planMoney)}`
+ : "";
+ return `${index + 1}. ${item.planMatter || "未填写事项"},${item.planWhere || "未填写条件"},${item.planTime || "未填写日期"}${money}`;
})
- .join('\n')
+ .join("\n");
}
// ========== 合同方相关函数 ==========
-const COUNTERPARTY_ROLE_CODES = ['B', 'C', 'D', 'E', 'F']
+const PARTY_ROLE_OUR = "OUR";
+const PARTY_ROLE_OPPOSITE = "OPPOSITE";
+const PARTY_NAME_KEYS = [
+ "partyAName",
+ "partyBName",
+ "partyCName",
+ "partyDName",
+ "partyEName",
+ "partyFName",
+];
-/** 深拷贝合同方状态 */
-function copyPartyState(input) {
- const source = input || {}
- const listState = buildPartyStateFromList(source.partyList)
- const sourceCounterpartyList = Array.isArray(source.counterpartyList)
- ? source.counterpartyList
- : [
- source.partyB?.companyName ? { ...source.partyB, roleKey: 'B' } : null,
- source.partyC?.companyName ? { ...source.partyC, roleKey: 'C' } : null,
- ].filter(Boolean)
+function createParty(roleCode = PARTY_ROLE_OPPOSITE, index = 0) {
return {
- partyA: {
- roleKey: 'A',
- roleName: '我方',
- displayName: '我方',
- companyName: '',
- ...(source.partyA || source.parties?.A || {}),
- ...(listState?.partyA || {}),
- },
- counterpartyList: listState?.counterpartyList?.length
- ? listState.counterpartyList.map((item) => ({ ...item }))
- : sourceCounterpartyList.map((item, index) => ({
- roleKey: item.roleKey || COUNTERPARTY_ROLE_CODES[index],
- roleName: item.roleName || '相对方',
- displayName: `相对方${index + 1}`,
- companyName: '',
- ...item,
- })),
- isThreePartyContract: Boolean(
- (listState?.counterpartyList || sourceCounterpartyList || []).length > 1,
- ),
- }
+ roleCode,
+ roleName: roleCode === PARTY_ROLE_OUR ? "我方" : "相对方",
+ displayName:
+ roleCode === PARTY_ROLE_OUR
+ ? `我方主体${index + 1}`
+ : `相对方${index + 1}`,
+ subjectCode: "",
+ companyName: "",
+ };
}
function mapLaunchPartyToFormParty(item = {}) {
- const roleIndex = COUNTERPARTY_ROLE_CODES.indexOf(item.roleCode || 'B')
+ const roleCode =
+ String(item.roleCode || PARTY_ROLE_OPPOSITE).toUpperCase() ===
+ PARTY_ROLE_OUR
+ ? PARTY_ROLE_OUR
+ : PARTY_ROLE_OPPOSITE;
return {
- roleKey: item.roleCode || 'B',
- roleName: item.roleCode === 'A' ? '我方' : item.roleName || '相对方',
- displayName:
- item.roleCode === 'A'
- ? '我方'
- : `相对方${roleIndex >= 0 ? roleIndex + 1 : 1}`,
+ ...createParty(roleCode),
+ roleCode,
+ roleName: roleCode === PARTY_ROLE_OUR ? "我方" : item.roleName || "相对方",
+ displayName: "",
partnerId: item.partnerId || null,
- oppositeId: item.oppositeId || '',
- companyName: item.companyName || '',
- companyType: item.companyType || '',
- oppCharacter: item.oppositeCharacter || '',
- contactName: item.contactName || '',
- contactPhone: item.contactPhone || '',
- contactEmail: item.contactEmail || '',
- contactAddress: item.contactAddress || '',
- registeredAddress: item.registeredAddress || '',
- legalRepresentative: item.legalRepresentative || '',
- creditCode: item.creditCode || '',
- bankName: item.bankName || '',
- bankAccount: item.bankAccount || '',
- naturalPersonIdType: item.naturalPersonIdType || '',
- naturalPersonIdNumber: item.naturalPersonIdNumber || '',
- isGroupInternal: item.isGroupInternal === '1' || item.isGroupInternal === true,
- isHongKongMacaoTaiwan: item.isHongKongMacaoTaiwan === '1' || item.isHongKongMacaoTaiwan === true,
- }
+ oppositeId: item.oppositeId || "",
+ companyName: item.companyName || "",
+ companyType: item.companyType || "",
+ oppCharacter: item.oppositeCharacter || "",
+ contactName: item.contactName || "",
+ contactPhone: item.contactPhone || "",
+ contactEmail: item.contactEmail || "",
+ contactAddress: item.contactAddress || "",
+ registeredAddress: item.registeredAddress || "",
+ legalRepresentative: item.legalRepresentative || "",
+ creditCode: item.creditCode || "",
+ bankName: item.bankName || "",
+ bankAccount: item.bankAccount || "",
+ naturalPersonIdType: item.naturalPersonIdType || "",
+ naturalPersonIdNumber: item.naturalPersonIdNumber || "",
+ isGroupInternal:
+ item.isGroupInternal === "1" || item.isGroupInternal === true,
+ isHongKongMacaoTaiwan:
+ item.isHongKongMacaoTaiwan === "1" || item.isHongKongMacaoTaiwan === true,
+ };
+}
+
+/** 深拷贝合同方状态 */
+function copyPartyState(input) {
+ const source = input || {};
+ const listState = buildPartyStateFromList(source.partyList);
+ if (listState) return listState;
+ const ourPartyList = Array.isArray(source.ourPartyList)
+ ? source.ourPartyList
+ : [];
+ const counterpartyList = Array.isArray(source.counterpartyList)
+ ? source.counterpartyList
+ : [];
+ return {
+ ourPartyList: ourPartyList.map((item, index) => ({
+ ...createParty(PARTY_ROLE_OUR, index),
+ ...item,
+ roleCode: PARTY_ROLE_OUR,
+ roleName: "我方",
+ displayName: `我方主体${index + 1}`,
+ })),
+ counterpartyList: counterpartyList.map((item, index) => ({
+ ...createParty(PARTY_ROLE_OPPOSITE, index),
+ ...item,
+ roleCode: PARTY_ROLE_OPPOSITE,
+ roleName: "相对方",
+ displayName: `相对方${index + 1}`,
+ })),
+ isThreePartyContract: counterpartyList.length > 1,
+ };
}
function buildPartyStateFromList(list = []) {
- if (!Array.isArray(list) || !list.length) return null
- const state = { partyA: {}, counterpartyList: [], isThreePartyContract: false }
+ if (!Array.isArray(list) || !list.length) return null;
+ const state = {
+ ourPartyList: [],
+ counterpartyList: [],
+ isThreePartyContract: false,
+ };
list.forEach((item) => {
- if (item.roleCode === 'A') {
- state.partyA = mapLaunchPartyToFormParty(item)
+ const party = mapLaunchPartyToFormParty(item);
+ if (party.roleCode === PARTY_ROLE_OUR) {
+ state.ourPartyList.push(party);
} else {
- state.counterpartyList.push(mapLaunchPartyToFormParty(item))
+ state.counterpartyList.push(party);
}
- })
+ });
+ state.ourPartyList = state.ourPartyList.map((item, index) => ({
+ ...item,
+ displayName: `我方主体${index + 1}`,
+ }));
state.counterpartyList = state.counterpartyList.map((item, index) => ({
...item,
- roleKey: item.roleKey || COUNTERPARTY_ROLE_CODES[index],
displayName: `相对方${index + 1}`,
- }))
- state.isThreePartyContract = state.counterpartyList.length > 1
- return state
+ }));
+ state.isThreePartyContract = state.counterpartyList.length > 1;
+ return state;
}
/** 获取有效的合同方列表 */
function getPartyList(partyState) {
- const state = copyPartyState(partyState)
- return [state.partyA, ...(state.counterpartyList || [])].filter(
- (item) => item && String(item.companyName || '').trim() !== '',
- )
+ 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(';')
+ .map(
+ (item) => `${item.roleName || "未知"}:${item.companyName || "未填写"}`,
+ )
+ .join(";");
}
/** 构建推送法务系统的相对方信息列表(排除甲方) */
function buildContractOpposites(partyState) {
return getPartyList(partyState)
- .filter((item) => item.roleKey !== 'A')
+ .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 : '',
+ 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) => ({
- roleKey: item.roleKey,
+ roleCode: item.roleCode,
roleName: item.roleName,
companyName: item.companyName,
oppCharacter: item.oppCharacter,
@@ -497,7 +538,7 @@ function buildPartySyncList(partyState) {
contactEmail: item.contactEmail,
bankName: item.bankName,
bankAccount: item.bankAccount,
- }))
+ }));
}
// ========== 履行计划 ==========
@@ -506,15 +547,15 @@ function buildPartySyncList(partyState) {
function createPerformancePlan() {
return {
id: `plan_${Date.now()}_${Math.random().toString(16).slice(2, 8)}`,
- planMatter: '',
- planWhere: '',
- planTime: '',
+ planMatter: "",
+ planWhere: "",
+ planTime: "",
planDay: 0,
- planMoney: '',
- planSubjectCode: '',
- planSubjectName: '',
- planDetail: '',
- }
+ planMoney: "",
+ planSubjectCode: "",
+ planSubjectName: "",
+ planDetail: "",
+ };
}
// ========== 合同发起表单数据模型 ==========
@@ -524,71 +565,76 @@ function createContractFormData() {
return {
id: null,
// 合同基本信息
- contractName: '', // 合同名称
- contractCode: '', // 合同编码
- contractType: '', // 合同类型
- contractTypeCode: '', // 合同类型编码
- contractAmount: null, // 合同金额(元)
- effectiveStart: '', // 有效期起 YYYY-MM-DD
- effectiveEnd: '', // 有效期止 YYYY-MM-DD
- contractPeriodType: '0', // 合同期限类型: 0-固定期限 1-无固定期限
- periodExplain: '', // 期限说明(无固定期限时填写)
- paymentMethod: '', // 付款方式
- paymentDirection: '0', // 收支方向
- isElectron: '1', // 签署方式: 0-纸质 1-电子
- textSource: 'standardText', // 文本来源
- contractSource: 'ECP', // 合同来源
- dateType: '0', // 固定期间日期类型:0-年 1-月 2-日
- valuationMode: '', // 计价方式: 0-无金额 1-固定总价 2-预估总价 3-无法预估总价 4-固定单价
- currencyName: '', // 币种: RMB/USD/HKD/EUR/IDR
- sealType: '', // 签订方式: GZ/HTZYZ/...
- mandateType: '', // 委托类型
- cargoType: '', // 货种
- primaryContent: '', // 合同主要内容
- amountExplain: '', // 金额说明
- contractGistRemark: '', // 签订依据说明
- bodySummary: '', // 正文摘要
- assistDept: '', // 协助部门
- executorAccount: '', // 合同执行人手机号
- selfCode: '', // 二级单位合同编码
- mainContractCode: '', // 主合同编码
- signingSubjectCode: '', // 签约主体编码
- invoiceDate: '', // 开票时间
- receiveDate: '', // 收款时间
+ contractName: "", // 合同名称
+ contractCode: "", // 合同编码
+ contractType: "", // 合同类型
+ contractTypeCode: "", // 合同类型编码
+ contractAmount: null, // 合同金额(元)
+ effectiveStart: "", // 有效期起 YYYY-MM-DD
+ effectiveEnd: "", // 有效期止 YYYY-MM-DD
+ contractPeriodType: "0", // 合同期限类型: 0-固定期限 1-无固定期限
+ periodExplain: "", // 期限说明(无固定期限时填写)
+ paymentMethod: "", // 付款方式
+ paymentDirection: "0", // 收支方向
+ isElectron: "1", // 签署方式: 0-纸质 1-电子
+ textSource: "standardText", // 文本来源
+ contractSource: "ECP", // 合同来源
+ dateType: "0", // 固定期间日期类型:0-年 1-月 2-日
+ valuationMode: "", // 计价方式: 0-无金额 1-固定总价 2-预估总价 3-无法预估总价 4-固定单价
+ currencyName: "", // 币种: RMB/USD/HKD/EUR/IDR
+ sealType: "", // 签订方式: GZ/HTZYZ/...
+ mandateType: "", // 委托类型
+ cargoType: "", // 货种
+ primaryContent: "", // 合同主要内容
+ amountExplain: "", // 金额说明
+ contractGistRemark: "", // 签订依据说明
+ bodySummary: "", // 正文摘要
+ assistDept: "", // 协助部门
+ executorAccount: "", // 合同执行人手机号
+ selfCode: "", // 二级单位合同编码
+ mainContractCode: "", // 主合同编码
+ signingSubjectCode: "", // 签约主体编码
+ invoiceDate: "", // 开票时间
+ receiveDate: "", // 收款时间
// 文件
- contractBodyFileName: '', // 合同正文文件名
- contractBodyFilePath: '',
- contractBodyFileType: '',
+ contractBodyFileName: "", // 合同正文文件名
+ contractBodyFilePath: "",
+ contractBodyFileType: "",
contractBodyFileSize: null,
contractBodyArrayBuffer: null, // 合同正文文件二进制
- otherAttachmentList: [], // 其他附件列表
- contractGistFileList: [], // 签订依据附件列表
- templateFieldValues: {}, // 模板字段值,统一按 {字段名: 值} 保存
+ otherAttachmentList: [], // 其他附件列表
+ contractGistFileList: [], // 签订依据附件列表
+ templateFieldValues: {}, // 模板字段值,统一按 {字段名: 值} 保存
// 合同方
partyState: {
isThreePartyContract: false,
- partyA: { companyName: '', roleKey: 'A', roleName: '我方', displayName: '我方' },
+ ourPartyList: [createParty(PARTY_ROLE_OUR, 0)],
counterpartyList: [],
},
+ isSingleAgreement: "0",
// 合同属性
- isInvolveHongKongMacaoTaiwan: false, // 是否涉及港澳台
- isPublicTender: false, // 是否公开招标
- isForeignRelatedSubject: false, // 签约主体是否涉外
- isIncludedInCurrentYearBudget: false, // 是否列入当年预算
- isShared: false, // 是否共享
- isMajorContract: false, // 是否重大合同
+ isInvolveHongKongMacaoTaiwan: false, // 是否涉及港澳台
+ isPublicTender: false, // 是否公开招标
+ isForeignRelatedSubject: false, // 签约主体是否涉外
+ isIncludedInCurrentYearBudget: false, // 是否列入当年预算
+ isShared: false, // 是否共享
+ isMajorContract: false, // 是否重大合同
// 额外金额
extraAmounts: {
- depositEnabled: false, deposit: 0,
- pledgeEnabled: false, pledge: 0,
- advanceEnabled: false, advance: 0,
- guaranteeEnabled: false, guarantee: 0,
+ depositEnabled: false,
+ deposit: 0,
+ pledgeEnabled: false,
+ pledge: 0,
+ advanceEnabled: false,
+ advance: 0,
+ guaranteeEnabled: false,
+ guarantee: 0,
},
- ewAmountType: '',
+ ewAmountType: "",
djAmount: 0,
yjAmount: 0,
yfkAmount: 0,
@@ -598,153 +644,194 @@ function createContractFormData() {
performancePlans: [],
// 签署日期
- signDate: dayjs().format('YYYY-MM-DD'),
- }
+ signDate: dayjs().format("YYYY-MM-DD"),
+ };
}
/** 深拷贝合同表单数据(用 source 覆盖默认值) */
function copyContractFormData(data = {}) {
- const form = createContractFormData()
- const source = data || {}
- const fileState = splitFilesByCategory(source)
+ const form = createContractFormData();
+ const source = data || {};
+ const fileState = splitFilesByCategory(source);
- form.contractName = source.contractName ?? form.contractName
- form.contractCode = source.contractCode ?? form.contractCode
- form.contractType = source.contractType ?? form.contractType
- form.contractTypeCode = source.contractTypeCode ?? source.contractType ?? form.contractTypeCode
- form.contractAmount = source.contractAmount ?? form.contractAmount
- form.effectiveStart = source.effectiveStart ? String(source.effectiveStart).slice(0, 10) : form.effectiveStart
- form.effectiveEnd = source.effectiveEnd ? String(source.effectiveEnd).slice(0, 10) : form.effectiveEnd
- form.contractPeriodType = source.contractPeriodType ?? form.contractPeriodType
- form.periodExplain = source.periodExplain ?? form.periodExplain
- form.paymentMethod = source.paymentMethod ?? form.paymentMethod
- form.paymentDirection = source.paymentDirection ?? form.paymentDirection
- form.isElectron = source.isElectron ?? form.isElectron
- form.textSource = source.textSource ?? form.textSource
- form.contractSource = source.contractSource ?? form.contractSource
- form.dateType = source.dateType ?? form.dateType
- form.valuationMode = source.valuationMode ?? form.valuationMode
- form.currencyName = source.currencyName ?? form.currencyName
- form.sealType = source.sealType ?? form.sealType
- form.mandateType = source.mandateType ?? form.mandateType
- form.cargoType = source.cargoType ?? form.cargoType
- form.primaryContent = source.primaryContent ?? form.primaryContent
- form.amountExplain = source.amountExplain ?? form.amountExplain
- form.contractGistRemark = source.contractGistRemark ?? form.contractGistRemark
- form.bodySummary = source.bodySummary ?? form.bodySummary
- form.assistDept = source.assistDept ?? source.assistDepartmentName ?? form.assistDept
- form.executorAccount = source.executorAccount ?? form.executorAccount
- form.selfCode = source.selfCode ?? form.selfCode
- form.mainContractCode = source.mainContractCode ?? form.mainContractCode
- form.signingSubjectCode = source.signingSubjectCode ?? source.orgId ?? form.signingSubjectCode
- form.invoiceDate = source.invoiceDate ? String(source.invoiceDate).slice(0, 10) : form.invoiceDate
- form.receiveDate = source.receiveDate ? String(source.receiveDate).slice(0, 10) : form.receiveDate
- form.contractBodyFileName = fileState.contractBodyFileName
- form.contractBodyFilePath = fileState.contractBodyFilePath
- form.contractBodyFileType = fileState.contractBodyFileType
- form.contractBodyFileSize = fileState.contractBodyFileSize
- form.templateFieldValues = source.templateFieldValues && typeof source.templateFieldValues === 'object'
- ? { ...source.templateFieldValues }
- : source.templateFieldValuesJson
- ? (() => {
- try {
- return JSON.parse(source.templateFieldValuesJson)
- } catch (error) {
- return {}
- }
- })()
- : {}
+ form.contractName = source.contractName ?? form.contractName;
+ form.contractCode = source.contractCode ?? form.contractCode;
+ form.contractType = source.contractType ?? form.contractType;
+ form.contractTypeCode =
+ source.contractTypeCode ?? source.contractType ?? form.contractTypeCode;
+ form.contractAmount = source.contractAmount ?? form.contractAmount;
+ form.effectiveStart = source.effectiveStart
+ ? String(source.effectiveStart).slice(0, 10)
+ : form.effectiveStart;
+ form.effectiveEnd = source.effectiveEnd
+ ? String(source.effectiveEnd).slice(0, 10)
+ : form.effectiveEnd;
+ form.contractPeriodType =
+ source.contractPeriodType ?? form.contractPeriodType;
+ form.periodExplain = source.periodExplain ?? form.periodExplain;
+ form.paymentMethod = source.paymentMethod ?? form.paymentMethod;
+ form.paymentDirection = source.paymentDirection ?? form.paymentDirection;
+ form.isElectron = source.isElectron ?? form.isElectron;
+ form.textSource = source.textSource ?? form.textSource;
+ form.contractSource = source.contractSource ?? form.contractSource;
+ form.dateType = source.dateType ?? form.dateType;
+ form.valuationMode = source.valuationMode ?? form.valuationMode;
+ form.currencyName = source.currencyName ?? form.currencyName;
+ form.sealType = source.sealType ?? form.sealType;
+ form.mandateType = source.mandateType ?? form.mandateType;
+ form.cargoType = source.cargoType ?? form.cargoType;
+ form.primaryContent = source.primaryContent ?? form.primaryContent;
+ form.amountExplain = source.amountExplain ?? form.amountExplain;
+ form.contractGistRemark =
+ source.contractGistRemark ?? form.contractGistRemark;
+ form.bodySummary = source.bodySummary ?? form.bodySummary;
+ form.assistDept =
+ source.assistDept ?? source.assistDepartmentName ?? form.assistDept;
+ form.executorAccount = source.executorAccount ?? form.executorAccount;
+ form.selfCode = source.selfCode ?? form.selfCode;
+ form.mainContractCode = source.mainContractCode ?? form.mainContractCode;
+ form.signingSubjectCode =
+ source.signingSubjectCode ?? source.orgId ?? form.signingSubjectCode;
+ form.isSingleAgreement = source.isSingleAgreement ?? form.isSingleAgreement;
+ form.invoiceDate = source.invoiceDate
+ ? String(source.invoiceDate).slice(0, 10)
+ : form.invoiceDate;
+ form.receiveDate = source.receiveDate
+ ? String(source.receiveDate).slice(0, 10)
+ : form.receiveDate;
+ form.contractBodyFileName = fileState.contractBodyFileName;
+ form.contractBodyFilePath = fileState.contractBodyFilePath;
+ form.contractBodyFileType = fileState.contractBodyFileType;
+ form.contractBodyFileSize = fileState.contractBodyFileSize;
+ form.templateFieldValues =
+ source.templateFieldValues && typeof source.templateFieldValues === "object"
+ ? { ...source.templateFieldValues }
+ : source.templateFieldValuesJson
+ ? (() => {
+ try {
+ return JSON.parse(source.templateFieldValuesJson);
+ } catch (error) {
+ return {};
+ }
+ })()
+ : {};
form.contractBodyArrayBuffer = source.contractBodyArrayBuffer
- ? (source.contractBodyArrayBuffer instanceof ArrayBuffer ? source.contractBodyArrayBuffer.slice(0) : null)
- : null
- form.otherAttachmentList = fileState.otherAttachmentList
- form.contractGistFileList = fileState.contractGistFileList
- form.partyState = copyPartyState(source.partyState || source)
- form.isInvolveHongKongMacaoTaiwan = source.isInvolveHongKongMacaoTaiwan ?? form.isInvolveHongKongMacaoTaiwan
- form.isPublicTender = source.isPublicTender ?? form.isPublicTender
- form.isForeignRelatedSubject = source.isForeignRelatedSubject ?? form.isForeignRelatedSubject
- form.isIncludedInCurrentYearBudget = source.isIncludedInCurrentYearBudget ?? form.isIncludedInCurrentYearBudget
- form.isShared = source.isShared ?? form.isShared
- form.isMajorContract = source.isMajorContract ?? form.isMajorContract
- form.signDate = source.signDate ? String(source.signDate).slice(0, 10) : form.signDate
+ ? source.contractBodyArrayBuffer instanceof ArrayBuffer
+ ? source.contractBodyArrayBuffer.slice(0)
+ : null
+ : null;
+ form.otherAttachmentList = fileState.otherAttachmentList;
+ form.contractGistFileList = fileState.contractGistFileList;
+ form.partyState = copyPartyState(source.partyState || source);
+ form.isInvolveHongKongMacaoTaiwan =
+ source.isInvolveHongKongMacaoTaiwan ?? form.isInvolveHongKongMacaoTaiwan;
+ form.isPublicTender = source.isPublicTender ?? form.isPublicTender;
+ form.isForeignRelatedSubject =
+ source.isForeignRelatedSubject ?? form.isForeignRelatedSubject;
+ form.isIncludedInCurrentYearBudget =
+ source.isIncludedInCurrentYearBudget ?? form.isIncludedInCurrentYearBudget;
+ form.isShared = source.isShared ?? form.isShared;
+ form.isMajorContract = source.isMajorContract ?? form.isMajorContract;
+ form.signDate = source.signDate
+ ? String(source.signDate).slice(0, 10)
+ : form.signDate;
form.extraAmounts = {
- depositEnabled: false, deposit: 0,
- pledgeEnabled: false, pledge: 0,
- advanceEnabled: false, advance: 0,
- guaranteeEnabled: false, guarantee: 0,
- }
- form.extraAmounts = restoreExtraAmounts(source, form.extraAmounts)
- form.ewAmountType = source.ewAmountType ?? form.ewAmountType
- form.djAmount = source.djAmount ?? form.djAmount
- form.yjAmount = source.yjAmount ?? form.yjAmount
- form.yfkAmount = source.yfkAmount ?? form.yfkAmount
- form.bzjAmount = source.bzjAmount ?? form.bzjAmount
+ depositEnabled: false,
+ deposit: 0,
+ pledgeEnabled: false,
+ pledge: 0,
+ advanceEnabled: false,
+ advance: 0,
+ guaranteeEnabled: false,
+ guarantee: 0,
+ };
+ form.extraAmounts = restoreExtraAmounts(source, form.extraAmounts);
+ form.ewAmountType = source.ewAmountType ?? form.ewAmountType;
+ form.djAmount = source.djAmount ?? form.djAmount;
+ form.yjAmount = source.yjAmount ?? form.yjAmount;
+ form.yfkAmount = source.yfkAmount ?? form.yfkAmount;
+ form.bzjAmount = source.bzjAmount ?? form.bzjAmount;
form.performancePlans = (source.performancePlans || []).map((item) => ({
...createPerformancePlan(),
...item,
- planTime: item.planTime ? String(item.planTime).slice(0, 10) : '',
- }))
+ planTime: item.planTime ? String(item.planTime).slice(0, 10) : "",
+ }));
- return form
+ return form;
}
// ========== 模板变量预览数据构建 ==========
/** 将合同表单数据转换为模板变量字典(用于 docxtemplater 渲染) */
-function buildTemplatePreviewData(formData, templateLabel = '', creationMode = 'template') {
- const form = copyContractFormData(formData)
- const partyA = getPartyList(form).find((item) => item.roleCode === 'A') || {}
- const partyB = getPartyList(form).find((item) => item.roleCode === 'B') || {}
- const partyC = getPartyList(form).find((item) => item.roleCode === 'C') || {}
- const partyD = getPartyList(form).find((item) => item.roleCode === 'D') || {}
- const partyE = getPartyList(form).find((item) => item.roleCode === 'E') || {}
- const partyF = getPartyList(form).find((item) => item.roleCode === 'F') || {}
- const templateValues = form.templateFieldValues || {}
+function buildTemplatePreviewData(
+ formData,
+ templateLabel = "",
+ creationMode = "template",
+) {
+ const form = copyContractFormData(formData);
+ const parties = getPartyList(form);
+ const templateValues = form.templateFieldValues || {};
- function pick(fieldKey, fallback = '') {
- if (templateValues[fieldKey] !== undefined && templateValues[fieldKey] !== null && templateValues[fieldKey] !== '') {
- return templateValues[fieldKey]
+ function pick(fieldKey, fallback = "") {
+ if (
+ templateValues[fieldKey] !== undefined &&
+ templateValues[fieldKey] !== null &&
+ templateValues[fieldKey] !== ""
+ ) {
+ return templateValues[fieldKey];
}
- return fallback
+ return fallback;
}
return {
- contractName: pick('contractName', form.contractName || ''),
- contractCode: pick('contractCode', form.contractCode || ''),
- contractType: pick('contractType', form.contractType || ''),
- contractAmountDisplay: pick('contractAmountDisplay', formatContractAmount(form.contractAmount)),
- effectiveStart: pick('effectiveStart', form.effectiveStart || ''),
- effectiveEnd: pick('effectiveEnd', form.effectiveEnd || ''),
- effectivePeriod: pick('effectivePeriod', [form.effectiveStart, form.effectiveEnd].filter(Boolean).join(' 至 ')),
- paymentMethod: pick('paymentMethod', form.paymentMethod || ''),
- primaryContent: pick('primaryContent', form.primaryContent || ''),
- amountExplain: pick('amountExplain', form.amountExplain || ''),
- partyAName: pick('partyAName', partyA.companyName || ''),
- partyBName: pick('partyBName', partyB.companyName || ''),
- partyCName: pick('partyCName', partyC.companyName || ''),
- partyDName: pick('partyDName', partyD.companyName || ''),
- partyEName: pick('partyEName', partyE.companyName || ''),
- partyFName: pick('partyFName', partyF.companyName || ''),
- counterpartySummary: pick('counterpartySummary', getPartySummary(form)),
- attachmentSummary: pick('attachmentSummary', formatFileSummary(form.otherAttachmentList)),
- templateLabel: pick('templateLabel', templateLabel || (creationMode === 'manual' ? '手动创建' : '')),
- signDate: pick('signDate', form.signDate || dayjs().format('YYYY-MM-DD')),
- businessRemark: pick('businessRemark', ''),
- contractSubject: pick('contractSubject', ''),
+ contractName: pick("contractName", form.contractName || ""),
+ contractCode: pick("contractCode", form.contractCode || ""),
+ contractType: pick("contractType", form.contractType || ""),
+ contractAmountDisplay: pick(
+ "contractAmountDisplay",
+ formatContractAmount(form.contractAmount),
+ ),
+ effectiveStart: pick("effectiveStart", form.effectiveStart || ""),
+ effectiveEnd: pick("effectiveEnd", form.effectiveEnd || ""),
+ effectivePeriod: pick(
+ "effectivePeriod",
+ [form.effectiveStart, form.effectiveEnd].filter(Boolean).join(" 至 "),
+ ),
+ paymentMethod: pick("paymentMethod", form.paymentMethod || ""),
+ primaryContent: pick("primaryContent", form.primaryContent || ""),
+ amountExplain: pick("amountExplain", form.amountExplain || ""),
+ partyAName: pick("partyAName", parties[0]?.companyName || ""),
+ partyBName: pick("partyBName", parties[1]?.companyName || ""),
+ partyCName: pick("partyCName", parties[2]?.companyName || ""),
+ partyDName: pick("partyDName", parties[3]?.companyName || ""),
+ partyEName: pick("partyEName", parties[4]?.companyName || ""),
+ partyFName: pick("partyFName", parties[5]?.companyName || ""),
+ counterpartySummary: pick("counterpartySummary", getPartySummary(form)),
+ attachmentSummary: pick(
+ "attachmentSummary",
+ formatFileSummary(form.otherAttachmentList),
+ ),
+ templateLabel: pick(
+ "templateLabel",
+ templateLabel || (creationMode === "manual" ? "手动创建" : ""),
+ ),
+ signDate: pick("signDate", form.signDate || dayjs().format("YYYY-MM-DD")),
+ businessRemark: pick("businessRemark", ""),
+ contractSubject: pick("contractSubject", ""),
templateFieldValuesJson: JSON.stringify(form.templateFieldValues || {}),
- }
+ };
}
// ========== 提交报文构建 ==========
/** 构建推送法务系统的合同报文 */
function buildContractSubmitPayload(formData, extra = {}) {
- const form = copyContractFormData(formData)
+ const form = copyContractFormData(formData);
return {
- creationMode: extra.creationMode || 'template',
- templateKey: extra.templateKey || '',
- templateName: extra.templateName || '',
+ creationMode: extra.creationMode || "template",
+ templateKey: extra.templateKey || "",
+ templateName: extra.templateName || "",
basicInfo: {
contractName: form.contractName,
contractCode: form.contractCode,
@@ -774,7 +861,11 @@ function buildContractSubmitPayload(formData, extra = {}) {
executorAccount: form.executorAccount,
selfCode: form.selfCode,
mainContractCode: form.mainContractCode,
- signingSubjectCode: form.signingSubjectCode,
+ signingSubjectCode:
+ (form.partyState.ourPartyList || [])
+ .map((item) => String(item.subjectCode || "").trim())
+ .filter(Boolean)
+ .join(",") || form.signingSubjectCode,
invoiceDate: form.invoiceDate,
receiveDate: form.receiveDate,
},
@@ -816,7 +907,7 @@ function buildContractSubmitPayload(formData, extra = {}) {
contractBodyFileName: form.contractBodyFileName,
performancePlans: form.performancePlans,
},
- }
+ };
}
const emit = defineEmits(["save"]);
@@ -881,52 +972,65 @@ const launchFieldList = computed(() => {
/** 模板字段中与合同主信息同名的直接映射字段 */
const CONTRACT_DIRECT_FIELDS = [
- 'contractName', 'contractCode', 'contractType',
- 'effectiveStart', 'effectiveEnd',
- 'paymentMethod', 'primaryContent', 'amountExplain',
- 'businessRemark', 'contractSubject',
-]
+ "contractName",
+ "contractCode",
+ "contractType",
+ "effectiveStart",
+ "effectiveEnd",
+ "paymentMethod",
+ "primaryContent",
+ "amountExplain",
+ "businessRemark",
+ "contractSubject",
+];
function getLaunchFieldValue(fieldKey) {
// 1. 优先返回用户在"模板信息录入"中自定义的值
- const templateVal = contractDetailState.value.templateFieldValues?.[fieldKey]
- if (templateVal !== undefined && templateVal !== null && templateVal !== '') {
- return templateVal
+ const templateVal = contractDetailState.value.templateFieldValues?.[fieldKey];
+ if (templateVal !== undefined && templateVal !== null && templateVal !== "") {
+ return templateVal;
}
// 2. 若字段与合同主信息直接同名,自动带入主信息的值
if (CONTRACT_DIRECT_FIELDS.includes(fieldKey)) {
- return contractDetailState.value[fieldKey] ?? ''
+ return contractDetailState.value[fieldKey] ?? "";
}
// 3. 特殊计算字段
- if (fieldKey === 'contractAmountDisplay') {
- return formatContractAmount(contractDetailState.value.contractAmount)
+ if (fieldKey === "contractAmountDisplay") {
+ return formatContractAmount(contractDetailState.value.contractAmount);
}
- if (fieldKey === 'effectivePeriod') {
- return [contractDetailState.value.effectiveStart, contractDetailState.value.effectiveEnd].filter(Boolean).join(' 至 ')
+ if (fieldKey === "effectivePeriod") {
+ return [
+ contractDetailState.value.effectiveStart,
+ contractDetailState.value.effectiveEnd,
+ ]
+ .filter(Boolean)
+ .join(" 至 ");
}
- if (fieldKey === 'templateLabel') {
- return activeTemplate.value?.templateName || ''
+ if (fieldKey === "templateLabel") {
+ return activeTemplate.value?.templateName || "";
}
- if (fieldKey === 'signDate') {
- return contractDetailState.value.signDate || dayjs().format('YYYY-MM-DD')
+ if (fieldKey === "signDate") {
+ return contractDetailState.value.signDate || dayjs().format("YYYY-MM-DD");
}
- if (fieldKey === 'counterpartySummary') {
- return getPartySummary(contractDetailState.value.partyState)
+ if (fieldKey === "counterpartySummary") {
+ return getPartySummary(contractDetailState.value.partyState);
}
- if (fieldKey === 'attachmentSummary') {
- return formatFileSummary(contractDetailState.value.otherAttachmentList)
+ if (fieldKey === "attachmentSummary") {
+ return formatFileSummary(contractDetailState.value.otherAttachmentList);
}
// 4. 合同方名称字段
if (/^party[A-F]Name$/.test(fieldKey)) {
- const roleCode = fieldKey.replace('party', '').replace('Name', '')
- const party = getPartyList(contractDetailState.value.partyState).find((item) => item.roleCode === roleCode)
- return party?.companyName ?? ''
+ const fieldIndex = PARTY_NAME_KEYS.indexOf(fieldKey);
+ return (
+ getPartyList(contractDetailState.value.partyState)[fieldIndex]
+ ?.companyName ?? ""
+ );
}
- return ''
+ return "";
}
function setLaunchFieldValue(fieldKey, value) {
@@ -1243,9 +1347,8 @@ async function handleManualContractBodyUpload(file) {
file.name.split(".").pop()?.toLowerCase() || "docx";
contractDetailState.value.contractBodyFileSize = file.size;
contractDetailState.value.textSource = "draftBySelf";
- contractDetailState.value.contractBodyArrayBuffer = await readFileAsArrayBuffer(
- file,
- );
+ contractDetailState.value.contractBodyArrayBuffer =
+ await readFileAsArrayBuffer(file);
syncManualBodyFileList();
previewBlob.value = null;
previewError.value = "";
@@ -1369,7 +1472,10 @@ async function showModal(initialValues = {}, mode = "create") {
: "template");
templateKey.value = isCreate
? publishedTemplates.value[0]?.id || ""
- : initialValues.templateKey || initialValues.templateId || initialValues.detailState?.templateId || "";
+ : initialValues.templateKey ||
+ initialValues.templateId ||
+ initialValues.detailState?.templateId ||
+ "";
contractDetailState.value = isCreate
? createContractFormData()
: initialValues.detailState
diff --git a/src/views/contract/launch/index.vue b/src/views/contract/launch/index.vue
index 6f7dcb8..62b094a 100644
--- a/src/views/contract/launch/index.vue
+++ b/src/views/contract/launch/index.vue
@@ -108,10 +108,11 @@
复制
变更
编辑
- 提交法务
+ {{ isSingleAgreementRecord(row) ? "提交审批" : "提交法务" }}
审批记录
回调data
- 测试通过
+ {{ isSingleAgreementRecord(row) ? "审批通过" : "测试通过" }}
+ {{ isSingleAgreementRecord(row) ? "审批驳回" : "测试驳回" }}
在线签订
下载签署文件
上传已签署版本
@@ -347,12 +348,19 @@ function canArchive(row) {
return row.status === "pending_archive";
}
+function isSingleAgreementRecord(row) {
+ return String(row?.isSingleAgreement || "0") === "1";
+}
+
function canViewApprove(row) {
- return Boolean(row.lawContractId) && ["reviewing", "rejected", "pending_sign", "signing", "pending_collect", "pending_archive", "completed"].includes(row.status);
+ return !isSingleAgreementRecord(row)
+ && Boolean(row.lawContractId)
+ && ["reviewing", "rejected", "pending_sign", "signing", "pending_collect", "pending_archive", "completed"].includes(row.status);
}
function canViewLawCallback(row) {
- return ["reviewing", "rejected", "pending_sign", "signing", "pending_collect", "pending_archive", "completed"].includes(row.status);
+ return !isSingleAgreementRecord(row)
+ && ["reviewing", "rejected", "pending_sign", "signing", "pending_collect", "pending_archive", "completed"].includes(row.status);
}
function canDownloadSigned(row) {
@@ -499,10 +507,13 @@ function handleChange(row) {
}
function handleSubmit(row) {
+ const singleAgreement = isSingleAgreementRecord(row);
Modal.confirm({
- title: "确认提交法务审批",
+ title: singleAgreement ? "确认提交内部审批" : "确认提交法务审批",
content: h("div", [
- h("p", `确定将合同【${row.contractName}】提交法务系统审批吗?`),
+ h("p", singleAgreement
+ ? `确定将单方协议【${row.contractName}】提交内部审批吗?`
+ : `确定将合同【${row.contractName}】提交法务系统审批吗?`),
h("p", { style: { color: "#999", fontSize: "12px" } }, "提交后合同进入「审批中」状态,审批完成前不可编辑。"),
]),
okText: "确认提交",
@@ -510,10 +521,10 @@ function handleSubmit(row) {
onOk: () =>
submitLaunchRecord(row.id).then((res) => {
if (!isSuccessResponse(res)) {
- message.error(getResponseMessage(res, "提交法务失败"));
+ message.error(getResponseMessage(res, singleAgreement ? "提交内部审批失败" : "提交法务失败"));
return;
}
- message.success("已提交法务,等待审批");
+ message.success(singleAgreement ? "已提交内部审批,等待审批" : "已提交法务,等待审批");
getList();
}),
icon: null,
@@ -605,9 +616,12 @@ function handleViewLawCallback(row) {
}
function handleMockApprove(row) {
+ const singleAgreement = isSingleAgreementRecord(row);
Modal.confirm({
- title: "测试操作:模拟审批通过",
- content: `模拟法务审批通过合同【${row.contractName}】,状态将变为「待签署」。`,
+ title: singleAgreement ? "测试操作:模拟内部审批通过" : "测试操作:模拟审批通过",
+ content: singleAgreement
+ ? `模拟单方协议【${row.contractName}】内部审批通过,状态将变为「待签署」。`
+ : `模拟法务审批通过合同【${row.contractName}】,状态将变为「待签署」。`,
okText: "确认模拟",
cancelText: "取消",
onOk: () =>
@@ -624,10 +638,13 @@ function handleMockApprove(row) {
}
function handleMockReject(row) {
+ const singleAgreement = isSingleAgreementRecord(row);
Modal.confirm({
- title: "测试操作:模拟审批驳回",
+ title: singleAgreement ? "测试操作:模拟内部审批驳回" : "测试操作:模拟审批驳回",
content: h("div", [
- h("p", `模拟法务审批驳回合同【${row.contractName}】,状态将回到「已驳回」。`),
+ h("p", singleAgreement
+ ? `模拟单方协议【${row.contractName}】内部审批驳回,状态将回到「已驳回」。`
+ : `模拟法务审批驳回合同【${row.contractName}】,状态将回到「已驳回」。`),
h("p", { style: { color: "#999", fontSize: "12px" } }, "驳回后可重新编辑再提交。"),
]),
okText: "确认驳回",
-
导出 Word
-
+
保存
@@ -176,7 +172,6 @@
-
-
- 合同主信息
-
-
-
@@ -1044,7 +1189,6 @@ const contractCompanyOptions = ref([
// ========== 合同相关字典 ==========
-
const mandateTypeOptions = [
{ label: "海铁联运委托", value: "海铁联运委托" },
{ label: "一站式物流委托", value: "一站式物流委托" },
@@ -1069,8 +1213,8 @@ const paymentMethodOptions = [
];
const SELF_COMPANY_NAME = "浙港物流平台有限公司";
-const MAX_COUNTERPARTY_COUNT = 5;
-const COUNTERPARTY_ROLE_CODES = ["B", "C", "D", "E", "F"];
+const PARTY_ROLE_OUR = "OUR";
+const PARTY_ROLE_OPPOSITE = "OPPOSITE";
// ========== 工具函数 ==========
@@ -1082,7 +1226,9 @@ function formatDateTimeValue(value, endOfDay = false) {
function normalizeFileItem(item = {}) {
return {
- uid: item.uid || `file_${Date.now()}_${Math.random().toString(16).slice(2, 8)}`,
+ uid:
+ item.uid ||
+ `file_${Date.now()}_${Math.random().toString(16).slice(2, 8)}`,
name: item.name || item.fileName || "",
size: item.size ?? item.fileSize ?? 0,
status: item.status || "done",
@@ -1094,8 +1240,10 @@ function normalizeFileItem(item = {}) {
function normalizeBooleanValue(value) {
if (value === true || value === false) return value;
- if (value === 1 || value === "1" || value === "Y" || value === "true") return true;
- if (value === 0 || value === "0" || value === "N" || value === "false") return false;
+ if (value === 1 || value === "1" || value === "Y" || value === "true")
+ return true;
+ if (value === 0 || value === "0" || value === "N" || value === "false")
+ return false;
return false;
}
@@ -1136,7 +1284,8 @@ function getFileNameFromDetail(source, category) {
function splitFilesByCategory(source = {}) {
const sourceFiles = source.fileList || [];
- const bodyFile = sourceFiles.find((item) => item.fileCategory === "body") || {};
+ const bodyFile =
+ sourceFiles.find((item) => item.fileCategory === "body") || {};
return {
contractBodyFileName:
@@ -1203,7 +1352,8 @@ function restoreExtraAmounts(source = {}, current = {}) {
extraAmountFieldOptions.forEach((item) => {
const amount = source[item.amountField];
if (selectedCodes.includes(item.code) || amount || amount === 0) {
- result[`${item.key}Enabled`] = selectedCodes.includes(item.code) || amount > 0;
+ result[`${item.key}Enabled`] =
+ selectedCodes.includes(item.code) || amount > 0;
if (amount !== undefined && amount !== null) {
result[item.key] = amount;
}
@@ -1213,120 +1363,86 @@ function restoreExtraAmounts(source = {}, current = {}) {
return result;
}
-/** 深拷贝合同方状态 */
-function copyPartyState(input) {
- const source = input || {};
- const listState = buildPartyStateFromList(source.partyList);
- const sourcePartyA = source.partyA || source.parties?.A || {};
- const sourcePartyB = source.partyB || source.parties?.B || {};
- const sourcePartyC = source.partyC || source.parties?.C || {};
- const sourceCounterpartyList = Array.isArray(source.counterpartyList)
- ? source.counterpartyList
- : [
- String(sourcePartyB.companyName || "").trim() ? { ...sourcePartyB, roleKey: "B" } : null,
- String(sourcePartyC.companyName || "").trim() ? { ...sourcePartyC, roleKey: "C" } : null,
- ].filter(Boolean);
- const state = {
- isThreePartyContract: Boolean(source.isThreePartyContract),
- partyA: {
- roleKey: "A",
- roleName: "我方",
- displayName: "我方",
- ...sourcePartyA,
- companyName: sourcePartyA.companyName || SELF_COMPANY_NAME,
- },
- partyB: {
- roleKey: "B",
- roleName: "相对方",
- displayName: "相对方1",
- companyName: "",
- ...sourcePartyB,
- },
- partyC: {
- roleKey: "C",
- roleName: "相对方",
- displayName: "相对方2",
- companyName: "",
- ...sourcePartyC,
- },
- counterpartyList: sourceCounterpartyList.map((item, index) => ({
- ...createEmptyCounterparty(item.roleKey || COUNTERPARTY_ROLE_CODES[index]),
- ...item,
- roleKey: item.roleKey || COUNTERPARTY_ROLE_CODES[index],
- displayName: `相对方${index + 1}`,
- })),
+function createLocalId(prefix = "party") {
+ return `${prefix}_${Date.now()}_${Math.random().toString(16).slice(2, 8)}`;
+}
+
+function createEmptyParty(roleCode, index = 0) {
+ const isOur = roleCode === PARTY_ROLE_OUR;
+ return {
+ localId: createLocalId(isOur ? "our" : "opposite"),
+ roleCode,
+ roleName: isOur ? "我方" : "相对方",
+ displayName: isOur ? `我方主体${index + 1}` : `相对方${index + 1}`,
+ subjectCode: "",
+ partnerId: null,
+ customerSysid: null,
+ oppositeId: "",
+ companyName: "",
+ companyType: "",
+ oppositeCharacter: "",
+ oppCharacter: "",
+ companyNature: "",
+ organizationNature: "",
+ enterpriseNatureLevel2: "",
+ contactName: "",
+ contactPhone: "",
+ contactEmail: "",
+ contactAddress: "",
+ registeredAddress: "",
+ legalRepresentative: "",
+ creditCode: "",
+ bankName: "",
+ bankAccount: "",
+ naturalPersonIdType: "",
+ naturalPersonIdNumber: "",
+ isGroupInternal: false,
+ isHongKongMacaoTaiwan: false,
+ invoiceTitleOptions: [],
};
- if (listState) {
- state.partyA = { ...state.partyA, ...listState.partyA };
- state.counterpartyList = listState.counterpartyList.map((item) => ({ ...item }));
- state.partyB = { ...state.partyB, ...(state.counterpartyList[0] || {}) };
- state.partyC = { ...state.partyC, ...(state.counterpartyList[1] || {}) };
- state.isThreePartyContract = listState.isThreePartyContract;
- } else {
- state.partyB = { ...state.partyB, ...(state.counterpartyList[0] || {}) };
- state.partyC = { ...state.partyC, ...(state.counterpartyList[1] || {}) };
- }
- return state;
}
function mapLaunchPartyToFormParty(item = {}) {
- const roleIndex = COUNTERPARTY_ROLE_CODES.indexOf(item.roleCode || "B");
+ const roleCode =
+ String(item.roleCode || PARTY_ROLE_OPPOSITE).toUpperCase() ===
+ PARTY_ROLE_OUR
+ ? PARTY_ROLE_OUR
+ : PARTY_ROLE_OPPOSITE;
return {
- roleKey: item.roleCode || "B",
- roleName: item.roleName || "",
- displayName:
- item.roleCode === "A" ? "我方" : `相对方${roleIndex >= 0 ? roleIndex + 1 : 1}`,
- partnerId: item.partnerId || null,
- customerSysid: item.partnerId || null,
- oppositeId: item.oppositeId || "",
- companyName: item.companyName || "",
- companyType: item.companyType || "",
- oppositeCharacter: item.oppositeCharacter || "",
- oppCharacter: item.oppositeCharacter || "",
- companyNature: getCompanyNatureByOppositeCharacter(item.oppositeCharacter),
- contactName: item.contactName || "",
- contactPhone: item.contactPhone || "",
- contactEmail: item.contactEmail || "",
- contactAddress: item.contactAddress || "",
- registeredAddress: item.registeredAddress || "",
- legalRepresentative: item.legalRepresentative || "",
- creditCode: item.creditCode || "",
- bankName: item.bankName || "",
- bankAccount: item.bankAccount || "",
- naturalPersonIdType: item.naturalPersonIdType || "",
- naturalPersonIdNumber: item.naturalPersonIdNumber || "",
- isGroupInternal: item.isGroupInternal === "1" || item.isGroupInternal === true,
- isHongKongMacaoTaiwan:
- item.isHongKongMacaoTaiwan === "1" || item.isHongKongMacaoTaiwan === true,
+ ...createEmptyParty(roleCode),
+ ...item,
+ localId:
+ item.localId ||
+ createLocalId(roleCode === PARTY_ROLE_OUR ? "our" : "opposite"),
+ roleCode,
+ roleName: roleCode === PARTY_ROLE_OUR ? "我方" : "相对方",
+ subjectCode: item.subjectCode || "",
+ companyNature: getCompanyNatureByOppositeCharacter(
+ item.oppositeCharacter || item.oppCharacter,
+ ),
+ oppCharacter: item.oppositeCharacter || item.oppCharacter || "",
+ oppositeCharacter: item.oppositeCharacter || item.oppCharacter || "",
+ displayName: "",
+ customerSysid: item.customerSysid || item.partnerId || null,
};
}
function buildPartyStateFromList(list = []) {
if (!Array.isArray(list) || !list.length) return null;
const result = {
- isThreePartyContract: false,
- partyA: {},
- partyB: {},
- partyC: {},
+ ourPartyList: [],
counterpartyList: [],
};
list.forEach((item) => {
if (!item?.roleCode) return;
- if (item.roleCode === "A") {
- result.partyA = mapLaunchPartyToFormParty(item);
+ const mapped = mapLaunchPartyToFormParty(item);
+ if (mapped.roleCode === PARTY_ROLE_OUR) {
+ result.ourPartyList.push(mapped);
} else {
- result.counterpartyList.push(mapLaunchPartyToFormParty(item));
+ result.counterpartyList.push(mapped);
}
});
- result.counterpartyList = result.counterpartyList.map((item, index) => ({
- ...item,
- roleKey: item.roleKey || COUNTERPARTY_ROLE_CODES[index],
- displayName: `相对方${index + 1}`,
- }));
- result.partyB = result.counterpartyList[0] || {};
- result.partyC = result.counterpartyList[1] || {};
- result.isThreePartyContract = result.counterpartyList.length > 1;
- return result;
+ return normalizePartyState(result);
}
function getCompanyNatureByOppositeCharacter(value) {
@@ -1339,17 +1455,13 @@ function getCompanyNatureByOppositeCharacter(value) {
return map[String(value || "")] || "";
}
-function createEmptyCounterparty(roleKey) {
- return {
- roleKey,
- roleName: "相对方",
- displayName: `相对方${COUNTERPARTY_ROLE_CODES.indexOf(roleKey) + 1}`,
- companyName: "",
- };
-}
-
function isPartyFilled(party = {}) {
- const ignoreKeys = new Set(["roleKey", "roleName", "displayName"]);
+ const ignoreKeys = new Set([
+ "localId",
+ "roleCode",
+ "roleName",
+ "displayName",
+ ]);
return Object.entries(party).some(([key, value]) => {
if (ignoreKeys.has(key)) return false;
if (Array.isArray(value)) return value.length > 0;
@@ -1358,38 +1470,89 @@ function isPartyFilled(party = {}) {
});
}
-function buildCounterpartyRoleKeys(partyState) {
- const state = partyState || {};
- const sourceList = Array.isArray(state.counterpartyList)
- ? state.counterpartyList
- : COUNTERPARTY_ROLE_CODES.map((roleKey) => state[`party${roleKey}`]).filter(Boolean);
- return sourceList
+function normalizePartyArray(list = [], roleCode) {
+ return (Array.isArray(list) ? list : [])
.filter((party) => isPartyFilled(party))
- .map((party, index) => party.roleKey || COUNTERPARTY_ROLE_CODES[index])
- .slice(0, MAX_COUNTERPARTY_COUNT);
+ .map((party, index) => ({
+ ...createEmptyParty(roleCode, index),
+ ...party,
+ localId:
+ party.localId ||
+ createLocalId(roleCode === PARTY_ROLE_OUR ? "our" : "opposite"),
+ roleCode,
+ roleName: roleCode === PARTY_ROLE_OUR ? "我方" : "相对方",
+ displayName:
+ roleCode === PARTY_ROLE_OUR
+ ? `我方主体${index + 1}`
+ : `相对方${index + 1}`,
+ }));
}
function normalizePartyState(partyState) {
- const state = copyPartyState(partyState);
- state.partyA.companyName = state.partyA.companyName || SELF_COMPANY_NAME;
- state.counterpartyList = (Array.isArray(state.counterpartyList) ? state.counterpartyList : [])
- .filter((party) => isPartyFilled(party))
- .slice(0, MAX_COUNTERPARTY_COUNT)
- .map((party, index) => ({
- ...createEmptyCounterparty(party.roleKey || COUNTERPARTY_ROLE_CODES[index]),
- ...party,
- roleKey: party.roleKey || COUNTERPARTY_ROLE_CODES[index],
- displayName: `相对方${index + 1}`,
- }));
- state.partyB = state.counterpartyList[0] || createEmptyCounterparty("B");
- state.partyC = state.counterpartyList[1] || createEmptyCounterparty("C");
- state.isThreePartyContract = state.counterpartyList.length > 1;
+ const state = partyState || {};
+ const ourPartyList = normalizePartyArray(
+ Array.isArray(state.ourPartyList)
+ ? state.ourPartyList
+ : state.partyA
+ ? [state.partyA]
+ : [],
+ PARTY_ROLE_OUR,
+ );
+ const normalizedOurList = ourPartyList.length
+ ? ourPartyList
+ : [
+ {
+ ...createEmptyParty(PARTY_ROLE_OUR, 0),
+ companyName: SELF_COMPANY_NAME,
+ },
+ ];
+ const counterpartyList = normalizePartyArray(
+ state.counterpartyList,
+ PARTY_ROLE_OPPOSITE,
+ );
+ return {
+ partyA: { ...normalizedOurList[0] },
+ ourPartyList: normalizedOurList,
+ counterpartyList,
+ isThreePartyContract: counterpartyList.length > 1,
+ };
+}
+
+function applySubjectCodesToPartyState(partyState, signingSubjectCode) {
+ const state = normalizePartyState(partyState);
+ const codes = String(signingSubjectCode || "")
+ .split(",")
+ .map((item) => item.trim())
+ .filter(Boolean);
+ state.ourPartyList = state.ourPartyList.map((party, index) => ({
+ ...party,
+ subjectCode:
+ party.subjectCode || (codes.length === 1 ? codes[0] : codes[index] || ""),
+ }));
+ state.partyA = state.ourPartyList[0] || createEmptyParty(PARTY_ROLE_OUR, 0);
return state;
}
-function getPartyByRoleKey(partyState, roleKey) {
- if (roleKey === "A") return partyState.partyA;
- return (partyState.counterpartyList || []).find((item) => item.roleKey === roleKey);
+function copyPartyState(input) {
+ const source = input || {};
+ const listState = buildPartyStateFromList(source.partyList);
+ if (listState) {
+ return applySubjectCodesToPartyState(
+ listState,
+ source.signingSubjectCode ?? "",
+ );
+ }
+ return normalizePartyState({
+ ourPartyList: source.ourPartyList || (source.partyA ? [source.partyA] : []),
+ counterpartyList: source.counterpartyList || [],
+ isThreePartyContract: source.isThreePartyContract,
+ });
+}
+
+function getPartyByLocalId(list = [], localId) {
+ return (Array.isArray(list) ? list : []).find(
+ (item) => item.localId === localId,
+ );
}
/** 创建一条空的履行计划 */
@@ -1457,11 +1620,15 @@ function createContractFormData() {
templateFieldValues: {},
partyState: {
isThreePartyContract: false,
- partyA: { companyName: SELF_COMPANY_NAME },
- partyB: { companyName: "" },
- partyC: { companyName: "" },
+ ourPartyList: [
+ {
+ ...createEmptyParty(PARTY_ROLE_OUR, 0),
+ companyName: SELF_COMPANY_NAME,
+ },
+ ],
counterpartyList: [],
},
+ isSingleAgreement: "0",
isInvolveHongKongMacaoTaiwan: false,
isPublicTender: false,
isForeignRelatedSubject: false,
@@ -1501,7 +1668,10 @@ function copyContractFormData(data = {}) {
if (key === "extraAmounts") {
form.extraAmounts = restoreExtraAmounts(source, form.extraAmounts);
} else if (key === "templateFieldValues") {
- if (source.templateFieldValues && typeof source.templateFieldValues === "object") {
+ if (
+ source.templateFieldValues &&
+ typeof source.templateFieldValues === "object"
+ ) {
form.templateFieldValues = { ...source.templateFieldValues };
} else if (source.templateFieldValuesJson) {
try {
@@ -1518,7 +1688,7 @@ function copyContractFormData(data = {}) {
...item,
}));
} else if (key === "partyState") {
- form.partyState = normalizePartyState(source.partyState || source);
+ form.partyState = copyPartyState(source.partyState || source);
} else if (key === "otherAttachmentList") {
form.otherAttachmentList = fileState.otherAttachmentList;
} else if (key === "contractGistFileList") {
@@ -1540,13 +1710,23 @@ function copyContractFormData(data = {}) {
? source.contractBodyArrayBuffer.slice(0)
: null
: null;
- } else if (key === "signDate" || key === "sealDate" || key === "invoiceDate" || key === "receiveDate" || key === "activeDate") {
+ } else if (
+ key === "signDate" ||
+ key === "sealDate" ||
+ key === "invoiceDate" ||
+ key === "receiveDate" ||
+ key === "activeDate"
+ ) {
form[key] = source[key] ? String(source[key]).slice(0, 10) : form[key];
} else if (key === "assistDept") {
- form.assistDept = source.assistDept ?? source.assistDepartmentName ?? form.assistDept;
+ form.assistDept =
+ source.assistDept ?? source.assistDepartmentName ?? form.assistDept;
} else if (key === "signingSubjectCode") {
form.signingSubjectCode =
source.signingSubjectCode ?? source.orgId ?? form.signingSubjectCode;
+ } else if (key === "isSingleAgreement") {
+ form.isSingleAgreement =
+ source.isSingleAgreement ?? form.isSingleAgreement;
} else if (
[
"isInvolveHongKongMacaoTaiwan",
@@ -1583,7 +1763,7 @@ const otherAttachmentList = ref([]);
const gistAttachmentList = ref([]);
const authAttachmentUploadList = ref([]);
const bodyConfigModalRef = ref(null);
-const counterpartyRoleKeys = ref([]);
+const currentSelfParty = ref(null);
const companyProfileMap = {
扬州宏富特种材料有限公司: {
@@ -1626,10 +1806,16 @@ const companyProfileMap = {
const isViewMode = computed(() => modalMode.value === "view");
-const counterpartyParties = computed(() =>
- (detailState.value.partyState.counterpartyList || []).filter((party) =>
- counterpartyRoleKeys.value.includes(party.roleKey),
- ),
+const isSingleAgreementChecked = computed(
+ () => String(detailState.value.isSingleAgreement || "0") === "1",
+);
+
+const ourParties = computed(
+ () => detailState.value.partyState.ourPartyList || [],
+);
+
+const counterpartyParties = computed(
+ () => detailState.value.partyState.counterpartyList || [],
);
const counterpartySummaryText = computed(() =>
@@ -1640,11 +1826,36 @@ const counterpartySummaryText = computed(() =>
: "未填写",
);
-const contractBodyDisplayText = computed(() =>
- detailState.value.contractBodyFileName ||
- (creationMode.value === "manual"
- ? "点击上传合同正文 Word 文件"
- : templateName.value || "点击配置合同正文"),
+const ourPartySummaryText = computed(() =>
+ ourParties.value.length
+ ? ourParties.value
+ .map((party) => party.companyName || party.displayName)
+ .join(";")
+ : "未填写",
+);
+
+const allPartyDetails = computed(() => [
+ ...ourParties.value,
+ ...counterpartyParties.value,
+]);
+
+const signingSubjectCodeText = computed(() =>
+ ourParties.value
+ .map((party) => String(party.subjectCode || "").trim())
+ .filter(Boolean)
+ .join(","),
+);
+
+const currentSelfSubjectCode = computed(() =>
+ String(currentSelfParty.value?.subjectCode || "").trim(),
+);
+
+const contractBodyDisplayText = computed(
+ () =>
+ detailState.value.contractBodyFileName ||
+ (creationMode.value === "manual"
+ ? "点击上传合同正文 Word 文件"
+ : templateName.value || "点击配置合同正文"),
);
const contractBodyHint = computed(() =>
@@ -1676,36 +1887,46 @@ function syncUploadLists() {
status: item.status || "done",
}),
);
- authAttachmentUploadList.value = (detailState.value.authAttachmentList || []).map(
- (item, index) => ({
- uid: item.uid || `auth_${index + 1}`,
- name: item.name || item.fileName,
- size: item.size ?? item.fileSize,
- status: item.status || "done",
- }),
- );
+ authAttachmentUploadList.value = (
+ detailState.value.authAttachmentList || []
+ ).map((item, index) => ({
+ uid: item.uid || `auth_${index + 1}`,
+ name: item.name || item.fileName,
+ size: item.size ?? item.fileSize,
+ status: item.status || "done",
+ }));
}
function syncCounterpartyState() {
- detailState.value.partyState = normalizePartyState(detailState.value.partyState);
- counterpartyRoleKeys.value = buildCounterpartyRoleKeys(detailState.value.partyState);
- detailState.value.partyState.counterpartyList =
- detailState.value.partyState.counterpartyList || [];
- detailState.value.partyState.isThreePartyContract = counterpartyRoleKeys.value.length > 1;
+ detailState.value.partyState = normalizePartyState(
+ detailState.value.partyState,
+ );
refreshPartyDisplayMeta();
}
function refreshPartyDisplayMeta() {
- detailState.value.partyState.partyA.roleKey = "A";
- detailState.value.partyState.partyA.roleName = "我方";
- detailState.value.partyState.partyA.displayName = "我方";
-
- (detailState.value.partyState.counterpartyList || []).forEach((party, index) => {
- const roleKey = party.roleKey || COUNTERPARTY_ROLE_CODES[index];
- party.roleKey = roleKey;
- party.roleName = "相对方";
- party.displayName = `相对方${index + 1}`;
- });
+ detailState.value.partyState.ourPartyList = (
+ detailState.value.partyState.ourPartyList || []
+ ).map((party, index) => ({
+ ...party,
+ roleCode: PARTY_ROLE_OUR,
+ roleName: "我方",
+ displayName: `我方主体${index + 1}`,
+ }));
+ detailState.value.partyState.counterpartyList = (
+ detailState.value.partyState.counterpartyList || []
+ ).map((party, index) => ({
+ ...party,
+ roleCode: PARTY_ROLE_OPPOSITE,
+ roleName: "相对方",
+ displayName: `相对方${index + 1}`,
+ }));
+ detailState.value.partyState.partyA =
+ detailState.value.partyState.ourPartyList[0] ||
+ createEmptyParty(PARTY_ROLE_OUR, 0);
+ detailState.value.partyState.isThreePartyContract =
+ detailState.value.partyState.counterpartyList.length > 1;
+ detailState.value.signingSubjectCode = signingSubjectCodeText.value;
}
function resetCurrentState() {
@@ -1718,19 +1939,11 @@ function resetCurrentState() {
}
function showSearchTip(title) {
- if (title === "我方详情") {
- message.info("我方信息当前按登录组织只读带出,后续接入真实组织主数据后自动完善。");
- return;
- }
loadPartnerOptions();
- message.info(`${title}数据已从相对方管理加载,可直接在下拉框搜索选择。`);
+ message.info(`${title}数据已从客户/主体库加载,可直接在下拉框搜索选择。`);
}
function showInvoiceTitles(party, roleName) {
- if (roleName === "我方") {
- message.info("我方开票抬头当前不在发起页维护,后续建议从组织主数据自动带出。");
- return;
- }
const titles = party.invoiceTitleOptions || [];
message.info(
titles.length
@@ -1740,9 +1953,16 @@ function showInvoiceTitles(party, roleName) {
}
function filterPartnerOption(input, option) {
- const keyword = String(input || "").trim().toLowerCase();
+ const keyword = String(input || "")
+ .trim()
+ .toLowerCase();
if (!keyword) return true;
- return [option?.label, option?.value, option?.raw?.oppositeCode, option?.raw?.oppositeId]
+ return [
+ option?.label,
+ option?.value,
+ option?.raw?.oppositeCode,
+ option?.raw?.oppositeId,
+ ]
.filter(Boolean)
.some((item) => String(item).toLowerCase().includes(keyword));
}
@@ -1781,9 +2001,13 @@ function getEnterpriseNatureLevel2Label(value) {
function mapPartnerToParty(raw = {}, roleKey, companyName) {
const firstContact = raw.contacts?.[0] || {};
+ const roleCode =
+ roleKey === PARTY_ROLE_OUR ? PARTY_ROLE_OUR : PARTY_ROLE_OPPOSITE;
return {
+ ...createEmptyParty(roleCode),
partnerId: raw.customerSysid || null,
customerSysid: raw.customerSysid || null,
+ subjectCode: raw.orgId == null ? "" : String(raw.orgId),
oppositeId: raw.oppositeId || "",
companyName: raw.customerNameC || companyName || "",
companyType: getRelativeTypeLabel(raw.relativeType),
@@ -1791,7 +2015,9 @@ function mapPartnerToParty(raw = {}, roleKey, companyName) {
oppCharacter: raw.oppositeCharacter || "",
companyNature: getCompanyNatureByOppositeCharacter(raw.oppositeCharacter),
organizationNature: getOrganizationNatureLabel(raw.natureOfEnterpriseOrg),
- enterpriseNatureLevel2: getEnterpriseNatureLevel2Label(raw.natureOfEnterpriseOrgLev),
+ enterpriseNatureLevel2: getEnterpriseNatureLevel2Label(
+ raw.natureOfEnterpriseOrgLev,
+ ),
creditCode: raw.customerTaxno || "",
tinNo: raw.tinCode || "",
countryCode: raw.country || "",
@@ -1809,24 +2035,59 @@ function mapPartnerToParty(raw = {}, roleKey, companyName) {
isGroupInternal: raw.groupFlag === "Y" || raw.isJtn === "1",
isHongKongMacaoTaiwan: raw.gatFlag === "Y" || raw.isSgat === "1",
invoiceTitleOptions: raw.customerNameC ? [raw.customerNameC] : [],
- roleKey,
- roleName: roleKey === "A" ? "我方" : "相对方",
- displayName: roleKey === "A" ? "我方" : roleKey === "C" ? "相对方2" : "相对方1",
+ roleCode,
+ roleName: roleCode === PARTY_ROLE_OUR ? "我方" : "相对方",
};
}
-function handleCompanySelect(roleKey, companyName, option = {}) {
- const party =
- roleKey === "A"
- ? detailState.value.partyState.partyA
- : getPartyByRoleKey(detailState.value.partyState, roleKey);
+function getPartyOptions(roleCode) {
+ const baseOptions = contractCompanyOptions.value || [];
+ if (roleCode !== PARTY_ROLE_OUR) {
+ return baseOptions;
+ }
+ const selfParty = currentSelfParty.value;
+ if (!selfParty?.companyName) {
+ return baseOptions;
+ }
+ const exists = baseOptions.some(
+ (item) => item.value === selfParty.companyName,
+ );
+ if (exists) {
+ return baseOptions;
+ }
+ return [
+ {
+ label: `${selfParty.companyName}(当前主体)`,
+ value: selfParty.companyName,
+ raw: {
+ customerNameC: selfParty.companyName,
+ orgId: selfParty.subjectCode,
+ officephone: selfParty.contactPhone,
+ emailAddress: selfParty.contactEmail,
+ customerAddress: selfParty.contactAddress,
+ customerRegaddr: selfParty.registeredAddress,
+ customerBank: selfParty.bankName,
+ customerBankaccount: selfParty.bankAccount,
+ legalPersonName: selfParty.legalRepresentative,
+ customerTaxno: selfParty.creditCode,
+ },
+ },
+ ...baseOptions,
+ ];
+}
+
+function handleCompanySelect(party, companyName, option = {}) {
if (!party) return;
const rawPartner =
option?.raw ||
- contractCompanyOptions.value.find((item) => item.value === companyName)?.raw;
+ contractCompanyOptions.value.find((item) => item.value === companyName)
+ ?.raw;
if (rawPartner) {
- Object.assign(party, mapPartnerToParty(rawPartner, roleKey, companyName));
+ Object.assign(
+ party,
+ mapPartnerToParty(rawPartner, party.roleCode, companyName),
+ );
refreshPartyDisplayMeta();
return;
}
@@ -1838,19 +2099,32 @@ function handleCompanySelect(roleKey, companyName, option = {}) {
}
Object.assign(party, {
- companyName,
- contactPhone: party.contactPhone || profile.contactPhone,
- registeredAddress: party.registeredAddress || profile.registeredAddress,
- bankAccount: party.bankAccount || profile.bankAccount,
- bankName: party.bankName || profile.bankName,
- contactName: party.contactName || profile.contactName,
- legalRepresentative:
- party.legalRepresentative || profile.legalRepresentative,
- creditCode: party.creditCode || profile.creditCode,
- oppCharacter:
- party.oppCharacter ||
- (String(party.companyNature || "").includes("个人") ? "2" : "1"),
- });
+ companyName,
+ subjectCode: party.subjectCode || "",
+ contactPhone: party.contactPhone || profile.contactPhone,
+ registeredAddress: party.registeredAddress || profile.registeredAddress,
+ bankAccount: party.bankAccount || profile.bankAccount,
+ bankName: party.bankName || profile.bankName,
+ contactName: party.contactName || profile.contactName,
+ legalRepresentative:
+ party.legalRepresentative || profile.legalRepresentative,
+ creditCode: party.creditCode || profile.creditCode,
+ oppCharacter:
+ party.oppCharacter ||
+ (String(party.companyNature || "").includes("个人") ? "2" : "1"),
+ });
+}
+
+function handleAddOurParty() {
+ detailState.value.partyState.ourPartyList =
+ detailState.value.partyState.ourPartyList || [];
+ detailState.value.partyState.ourPartyList.push(
+ createEmptyParty(
+ PARTY_ROLE_OUR,
+ detailState.value.partyState.ourPartyList.length,
+ ),
+ );
+ refreshPartyDisplayMeta();
}
function handleContractTypeChange(value) {
@@ -1862,39 +2136,33 @@ function handleContractTypeCodeChange(value) {
}
function handleAddCounterparty() {
- if (counterpartyRoleKeys.value.length >= MAX_COUNTERPARTY_COUNT) {
- message.warning(`最多支持添加 ${MAX_COUNTERPARTY_COUNT} 个相对方`);
- return;
- }
-
- const nextRoleKey = COUNTERPARTY_ROLE_CODES.find(
- (roleKey) => !counterpartyRoleKeys.value.includes(roleKey),
- );
- if (!nextRoleKey) return;
-
detailState.value.partyState.counterpartyList =
detailState.value.partyState.counterpartyList || [];
detailState.value.partyState.counterpartyList.push(
- createEmptyCounterparty(nextRoleKey),
+ createEmptyParty(
+ PARTY_ROLE_OPPOSITE,
+ detailState.value.partyState.counterpartyList.length,
+ ),
);
- counterpartyRoleKeys.value = [...counterpartyRoleKeys.value, nextRoleKey];
- detailState.value.partyState.isThreePartyContract = counterpartyRoleKeys.value.length > 1;
refreshPartyDisplayMeta();
}
-function handleRemoveCounterparty(roleKey) {
- detailState.value.partyState.counterpartyList =
- (detailState.value.partyState.counterpartyList || [])
- .filter((item) => item.roleKey !== roleKey)
- .map((item, index) => ({
- ...item,
- roleKey: COUNTERPARTY_ROLE_CODES[index],
- displayName: `相对方${index + 1}`,
- }));
- counterpartyRoleKeys.value = detailState.value.partyState.counterpartyList.map(
- (item) => item.roleKey,
- );
- detailState.value.partyState.isThreePartyContract = counterpartyRoleKeys.value.length > 1;
+function handleRemoveOurParty(localId) {
+ detailState.value.partyState.ourPartyList = (
+ detailState.value.partyState.ourPartyList || []
+ ).filter((item) => item.localId !== localId);
+ if (!detailState.value.partyState.ourPartyList.length) {
+ detailState.value.partyState.ourPartyList = [
+ createEmptyParty(PARTY_ROLE_OUR, 0),
+ ];
+ }
+ refreshPartyDisplayMeta();
+}
+
+function handleRemoveCounterparty(localId) {
+ detailState.value.partyState.counterpartyList = (
+ detailState.value.partyState.counterpartyList || []
+ ).filter((item) => item.localId !== localId);
refreshPartyDisplayMeta();
}
@@ -2017,7 +2285,9 @@ function handleBodyConfigSave(payload = {}) {
if (modalMode.value === "edit" && detailState.value.id) {
const errorMessage = validateState();
if (errorMessage) {
- message.success("合同正文配置已保存到当前页面,请继续完善主信息后再保存合同草稿。");
+ message.success(
+ "合同正文配置已保存到当前页面,请继续完善主信息后再保存合同草稿。",
+ );
return;
}
@@ -2037,7 +2307,9 @@ function handleBodyConfigSave(payload = {}) {
return;
}
- message.success("合同正文配置已保存到当前页面,请继续点击底部“保存”提交合同草稿。");
+ message.success(
+ "合同正文配置已保存到当前页面,请继续点击底部“保存”提交合同草稿。",
+ );
}
function addPerformancePlan() {
@@ -2050,10 +2322,24 @@ function removePerformancePlan(id) {
}
function validateState() {
- if (!detailState.value.partyState.partyA.companyName?.trim())
- return "请确认我方信息";
- if (!counterpartyRoleKeys.value.length) return "请至少添加一个相对方";
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 && !counterpartyParties.value.length)
+ return "请至少添加一个相对方";
+ if (
+ !isSingleAgreementChecked.value &&
counterpartyParties.value.some((party) => !party.companyName?.trim())
)
return "请选择相对方";
@@ -2106,7 +2392,11 @@ function validateState() {
if (!detailState.value.sealType) return "请选择签订方式";
if (!detailState.value.textSource) return "请选择文本来源";
// needAmendments 必填(文档要求)
- if (!detailState.value.needAmendments || detailState.value.needAmendments === "") return "请选择是否需修订条款";
+ if (
+ !detailState.value.needAmendments ||
+ detailState.value.needAmendments === ""
+ )
+ return "请选择是否需修订条款";
if (!detailState.value.paymentDirection) return "请选择收支方向";
if (!detailState.value.contractTypeCode) return "请选择合同类型编码";
if (!detailState.value.executorAccount?.trim()) return "请填写合同执行人";
@@ -2125,11 +2415,17 @@ function validateState() {
if (!plan.planMatter?.trim()) return "请填写履行计划的履行事项";
if (!plan.planWhere?.trim()) return "请填写履行计划的履约条件";
if (!plan.planTime) return "请选择履行计划的节点日期";
- if (plan.planDay === null || plan.planDay === undefined || plan.planDay === "")
+ 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 === "")
+ (plan.planMoney === null ||
+ plan.planMoney === undefined ||
+ plan.planMoney === "")
)
return "请填写履行计划的款项金额";
}
@@ -2168,32 +2464,11 @@ function handleSave() {
function buildLaunchRecord() {
const partyList = [];
- const partyA = detailState.value.partyState.partyA || {};
- partyList.push({
- roleCode: "A",
- roleName: "甲方",
- companyName: partyA.companyName,
- companyType: partyA.companyType,
- oppositeCharacter:
- partyA.oppCharacter ||
- (String(partyA.companyNature || "").includes("个人") ? "2" : "1"),
- contactName: partyA.contactName,
- contactPhone: partyA.contactPhone,
- contactEmail: partyA.contactEmail,
- contactAddress: partyA.contactAddress,
- registeredAddress: partyA.registeredAddress,
- legalRepresentative: partyA.legalRepresentative,
- creditCode: partyA.creditCode,
- bankName: partyA.bankName,
- bankAccount: partyA.bankAccount,
- naturalPersonIdType: partyA.naturalPersonIdType,
- naturalPersonIdNumber: partyA.naturalPersonIdNumber,
- });
-
- counterpartyParties.value.forEach((party, index) => {
+ ourParties.value.forEach((party) => {
partyList.push({
- roleCode: party.roleKey || COUNTERPARTY_ROLE_CODES[index],
- roleName: party.displayName || `相对方${index + 1}`,
+ roleCode: PARTY_ROLE_OUR,
+ roleName: "我方",
+ subjectCode: party.subjectCode || "",
partnerId: party.partnerId || party.customerSysid || null,
oppositeId: party.oppositeId,
companyName: party.companyName,
@@ -2217,6 +2492,35 @@ function buildLaunchRecord() {
});
});
+ if (!isSingleAgreementChecked.value) {
+ counterpartyParties.value.forEach((party) => {
+ partyList.push({
+ roleCode: PARTY_ROLE_OPPOSITE,
+ roleName: "相对方",
+ partnerId: party.partnerId || party.customerSysid || null,
+ oppositeId: party.oppositeId,
+ companyName: party.companyName,
+ companyType: party.companyType,
+ oppositeCharacter:
+ party.oppCharacter ||
+ (String(party.companyNature || "").includes("个人") ? "2" : "1"),
+ contactName: party.contactName,
+ contactPhone: party.contactPhone,
+ contactEmail: party.contactEmail,
+ contactAddress: party.contactAddress,
+ registeredAddress: party.registeredAddress,
+ legalRepresentative: party.legalRepresentative,
+ creditCode: party.creditCode,
+ bankName: party.bankName,
+ bankAccount: party.bankAccount,
+ naturalPersonIdType: party.naturalPersonIdType,
+ naturalPersonIdNumber: party.naturalPersonIdNumber,
+ isGroupInternal: party.isGroupInternal ? "1" : "0",
+ isHongKongMacaoTaiwan: party.isHongKongMacaoTaiwan ? "1" : "0",
+ });
+ });
+ }
+
const fileList = [];
if (detailState.value.contractBodyFileName) {
fileList.push({
@@ -2255,14 +2559,20 @@ function buildLaunchRecord() {
});
});
- const extraAmountPayload = buildExtraAmountPayload(detailState.value.extraAmounts);
+ const extraAmountPayload = buildExtraAmountPayload(
+ detailState.value.extraAmounts,
+ );
return {
id: detailState.value.id || null,
contractCode: detailState.value.contractCode,
contractName: detailState.value.contractName,
- contractType: getOptionLabel(contractTypeOptions, detailState.value.contractType),
- contractTypeCode: detailState.value.contractTypeCode || detailState.value.contractType,
+ contractType: getOptionLabel(
+ contractTypeOptions,
+ detailState.value.contractType,
+ ),
+ contractTypeCode:
+ detailState.value.contractTypeCode || detailState.value.contractType,
contractSource: detailState.value.contractSource || "ECP",
creationMode: creationMode.value,
templateId: templateKey.value || null,
@@ -2296,6 +2606,7 @@ function buildLaunchRecord() {
dateType: detailState.value.dateType || "0",
isAddit: detailState.value.mainContractCode ? 1 : 2,
isElectron: detailState.value.isElectron || "1",
+ isSingleAgreement: detailState.value.isSingleAgreement || "0",
paymentDirection: detailState.value.paymentDirection || "0",
isMajorContract: detailState.value.isMajorContract ? 1 : 0,
isOpenBidding: detailState.value.isPublicTender ? 1 : 0,
@@ -2303,9 +2614,12 @@ function buildLaunchRecord() {
isShare: detailState.value.isShared ? "1" : "0",
contractNature: detailState.value.isForeignRelatedSubject ? "1" : "0",
isSgat: detailState.value.isInvolveHongKongMacaoTaiwan ? "1" : "0",
- biddingNo: detailState.value.isPublicTender ? detailState.value.biddingNo || "" : "",
+ biddingNo: detailState.value.isPublicTender
+ ? detailState.value.biddingNo || ""
+ : "",
contractGistRemark: detailState.value.contractGistRemark || "",
- bodySummary: detailState.value.bodySummary || detailState.value.primaryContent || "",
+ bodySummary:
+ detailState.value.bodySummary || detailState.value.primaryContent || "",
contractTextFileName: detailState.value.contractBodyFileName || "",
contractTextFilePath: detailState.value.contractBodyFilePath || "",
contractTextFileType: detailState.value.contractBodyFileType || "docx",
@@ -2320,54 +2634,91 @@ function buildLaunchRecord() {
detailState.value.templateFieldValues || {},
),
remindDays: 3,
- signingSubjectCode: detailState.value.signingSubjectCode || "",
+ signingSubjectCode:
+ signingSubjectCodeText.value ||
+ detailState.value.signingSubjectCode ||
+ "",
extraAmounts: { ...detailState.value.extraAmounts },
...extraAmountPayload,
partyList,
fileList,
- performancePlans: (detailState.value.performancePlans || []).map((item) => ({
- planMatter: item.planMatter,
- planWhere: item.planWhere,
- planTime: formatDateTimeValue(item.planTime),
- planDay: item.planDay,
- planMoney: item.planMoney,
- planSubjectCode: item.planSubjectCode,
- planSubjectName: item.planSubjectName,
- executorUnitId: item.executorUnitId || null,
- planDetail: item.planDetail,
- planStatus: "0",
- })),
+ performancePlans: (detailState.value.performancePlans || []).map(
+ (item) => ({
+ planMatter: item.planMatter,
+ planWhere: item.planWhere,
+ planTime: formatDateTimeValue(item.planTime),
+ planDay: item.planDay,
+ planMoney: item.planMoney,
+ planSubjectCode: item.planSubjectCode,
+ planSubjectName: item.planSubjectName,
+ executorUnitId: item.executorUnitId || null,
+ planDetail: item.planDetail,
+ planStatus: "0",
+ }),
+ ),
};
}
function applySelfProfile(profile = {}) {
- detailState.value.partyState.partyA = {
- ...detailState.value.partyState.partyA,
- companyName: profile.orgName || detailState.value.partyState.partyA.companyName,
- contactPhone: profile.contactPhone || detailState.value.partyState.partyA.contactPhone,
- contactEmail: profile.contactEmail || detailState.value.partyState.partyA.contactEmail,
- contactAddress: profile.contactAddress || detailState.value.partyState.partyA.contactAddress,
- registeredAddress:
- profile.registeredAddress || detailState.value.partyState.partyA.registeredAddress,
- bankName: profile.bankName || detailState.value.partyState.partyA.bankName,
- bankAccount: profile.bankAccount || detailState.value.partyState.partyA.bankAccount,
- legalRepresentative:
- profile.legalRepresentative || detailState.value.partyState.partyA.legalRepresentative,
- creditCode: profile.creditCode || detailState.value.partyState.partyA.creditCode,
- invoiceTitleOptions:
- profile.invoiceTitleOptions || detailState.value.partyState.partyA.invoiceTitleOptions || [],
+ const firstOurParty =
+ detailState.value.partyState.ourPartyList?.[0] ||
+ createEmptyParty(PARTY_ROLE_OUR, 0);
+ currentSelfParty.value = {
+ ...createEmptyParty(PARTY_ROLE_OUR, 0),
+ companyName: profile.orgName || SELF_COMPANY_NAME,
+ subjectCode: profile.id || "",
+ contactPhone: profile.contactPhone || "",
+ contactEmail: profile.contactEmail || "",
+ contactAddress: profile.contactAddress || "",
+ registeredAddress: profile.registeredAddress || "",
+ bankName: profile.bankName || "",
+ bankAccount: profile.bankAccount || "",
+ legalRepresentative: profile.legalRepresentative || "",
+ creditCode: profile.creditCode || "",
+ invoiceTitleOptions: profile.invoiceTitleOptions || [],
};
+ const shouldHydrateFirstParty =
+ !firstOurParty.companyName ||
+ firstOurParty.companyName === SELF_COMPANY_NAME ||
+ firstOurParty.companyName === profile.orgName;
+ if (!shouldHydrateFirstParty) {
+ return;
+ }
+ detailState.value.partyState.ourPartyList = [
+ {
+ ...firstOurParty,
+ companyName: profile.orgName || firstOurParty.companyName,
+ subjectCode: profile.id || firstOurParty.subjectCode,
+ contactPhone: profile.contactPhone || firstOurParty.contactPhone,
+ contactEmail: profile.contactEmail || firstOurParty.contactEmail,
+ contactAddress: profile.contactAddress || firstOurParty.contactAddress,
+ registeredAddress:
+ profile.registeredAddress || firstOurParty.registeredAddress,
+ bankName: profile.bankName || firstOurParty.bankName,
+ bankAccount: profile.bankAccount || firstOurParty.bankAccount,
+ legalRepresentative:
+ profile.legalRepresentative || firstOurParty.legalRepresentative,
+ creditCode: profile.creditCode || firstOurParty.creditCode,
+ invoiceTitleOptions:
+ profile.invoiceTitleOptions || firstOurParty.invoiceTitleOptions || [],
+ },
+ ...(detailState.value.partyState.ourPartyList || []).slice(1),
+ ];
+ refreshPartyDisplayMeta();
}
async function showModal(context = {}, mode = "create") {
modalMode.value = mode || "create";
- const source = context.detailState ||
+ const source =
+ context.detailState ||
(Object.keys(context || {}).length ? context : createContractFormData());
creationMode.value =
context.creationMode ||
source.creationMode ||
- (source.contractBodyArrayBuffer || source.contractBodyFilePath ? "manual" : "template");
+ (source.contractBodyArrayBuffer || source.contractBodyFilePath
+ ? "manual"
+ : "template");
templateKey.value = context.templateKey || source.templateId || "";
templateName.value = context.templateName || source.templateName || "";
detailState.value = copyContractFormData(source);
@@ -2386,7 +2737,9 @@ function loadPartnerOptions() {
value: item.customerNameC,
raw: item,
}));
- contractCompanyOptions.value = options.length ? options : contractCompanyOptions.value;
+ contractCompanyOptions.value = options.length
+ ? options
+ : contractCompanyOptions.value;
});
}
diff --git a/src/views/contract/launch/components/ContractTemplateFillDemoModal.vue b/src/views/contract/launch/components/ContractTemplateFillDemoModal.vue
index 6cd0027..10ba189 100644
--- a/src/views/contract/launch/components/ContractTemplateFillDemoModal.vue
+++ b/src/views/contract/launch/components/ContractTemplateFillDemoModal.vue
@@ -130,11 +130,7 @@
我方
-
-
-
-
+
-
-
+
+
- 我方{{
- detailState.partyState.partyA.companyName || "/"
- }}
-
-
- 电话{{
- detailState.partyState.partyA.contactPhone || "/"
- }}
-
-
- 公司地址{{
- detailState.partyState.partyA.registeredAddress || "/"
- }}
-
-
- 银行/账号{{
- detailState.partyState.partyA.bankAccount || "/"
- }}
-
-
+
-
+
+
+
-
- 备选开票抬头选择
-
-
-
-
-
+
- 合同主信息
-
-
-
-
- {{ party.displayName }}
+
-
- handleCompanySelect(party.roleKey, value, option)"
- />
-
-
-
+
-
+ 当前登录主体必须包含在我方主体中
-
-
-
-
-
-
- {{ party.displayName }}{{
- party.companyName || "/"
- }}
-
-
- 电话{{ party.contactPhone || "/" }}
-
-
- 公司地址{{ party.registeredAddress || "/" }}
-
-
- 银行/账号{{ party.bankAccount || "/" }}
-
-
- 暂无相对方,请点击右上角“添加”
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 固定期限
- 无固定期限
-
-
-
- 合同起止时间
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 基本信息
-
-
-
-
-
- 合同名称{{ detailState.contractName || "未填写" }}
-
-
- 我方{{
- detailState.partyState.partyA.companyName || "未填写"
- }}
-
-
- 合同编号{{ detailState.contractCode || "未填写" }}
-
-
- 相对方{{ counterpartySummaryText }}
-
-
-
-
- 下载
-
-
-
-
- 合同正文
-
-
-
- {{ contractBodyDisplayText }}
-
-
- {{ contractBodyHint }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ 签订依据附件
- 签订依据文件,对应法务 contractGistFile
-
-
+
-
-
+
- 下载 {{ item.name || item.fileName }}
+ 删除
-
-
-
+ {{ party.displayName }}
+
-
-
-
-
- 授权委托书附件
- 当前签订方式需要上传授权委托书附件
-
-
-
- 下载 {{ item.name || item.fileName }}
-
-
-
-
-
-
-
-
- 其他附件
- 其他附件(可上传多个文件)
-
-
-
- 下载 {{ item.name || item.fileName }}
-
-
-
-
-
-
- 下载
-
-
-
-
- 已签署文件
-
-
-
- {{ detailState.signedFileName || "已签署文件" }}
-
- 当前合同的签署完成版本
-
-
-
- 合同属性
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 是否需修订条款
-
- 是
- 否
-
-
-
- 是否涉及港澳台
-
- 是
- 否
-
-
-
- 是否公开招标
-
- 是
- 否
-
-
-
- 签约主体是否涉外
-
- 是
- 否
-
-
-
- 是否列入当年预算
-
- 是
- 否
-
-
-
- 是否共享
-
- 是
- 否
-
-
-
- 是否重大合同
-
- 是
- 否
-
-
-
-
-
- 额外金额
-
-
-
-
-
-
-
-
- 新增履行计划
+ 备选开票抬头选择
-
-
- 履行计划
-
-
+
+
+
+
+
+ {{ party.displayName }}{{ party.companyName || "/" }}
+
+
+ 主体编码{{ party.subjectCode || "/" }}
+
+
+ 电话{{ party.contactPhone || "/" }}
+
+
+ 公司地址{{ party.registeredAddress || "/" }}
+
+
+ 银行/账号{{ party.bankAccount || "/" }}
+
+ 相对方
+
-
+
+
+
+
删除
-
-
-
-
+
+ {{ party.displayName }}
+
暂无数据
-
-
+
+
+ handleCompanySelect(party, value, option)
+ "
+ />
+
+
+
+
+
+
+
+
+
+
+ {{ party.displayName }}{{ party.companyName || "/" }}
+
+
+ 电话{{ party.contactPhone || "/" }}
+
+
+ 公司地址{{ party.registeredAddress || "/" }}
+
+
+ 银行/账号{{ party.bankAccount || "/" }}
+
+
+ 暂无相对方,请点击右上角“添加”
+
+
+
+ 当前为单方协议,无需维护相对方
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 固定期限
+ 无固定期限
+
+
+
+
+ 合同起止时间
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 基本信息
+
+
+
+
+
+ 合同名称{{ detailState.contractName || "未填写" }}
+
+
+ 我方{{ ourPartySummaryText }}
+
+
+ 合同编号{{ detailState.contractCode || "未填写" }}
+
+
+ 相对方{{ counterpartySummaryText }}
+
+
+
+
+ 下载
+
+
+
+
+ 合同正文
+
+
+
+ {{ contractBodyDisplayText }}
+
+
+ {{ contractBodyHint }}
+
+
+
+
+
+
+ 签订依据附件
+
+ 签订依据文件,对应法务 contractGistFile
+
+
+
+
+ 下载 {{ item.name || item.fileName }}
+
+
+
+
+
+
+
+
+ 授权委托书附件
+
+ 当前签订方式需要上传授权委托书附件
+
+
+
+
+ 下载 {{ item.name || item.fileName }}
+
+
+
+
+
+
+
+
+ 其他附件
+
+ 其他附件(可上传多个文件)
+
+
+
+
+ 下载 {{ item.name || item.fileName }}
+
+
+
+
+
+
+ 下载
+
+
+
+
+ 已签署文件
+
+
+
+ {{ detailState.signedFileName || "已签署文件" }}
+
+
+ 当前合同的签署完成版本
+
+
+
+ 合同属性
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 是否需修订条款
+
+ 是
+ 否
+
+
+
+ 是否涉及港澳台
+
+ 是
+ 否
+
+
+
+ 是否公开招标
+
+ 是
+ 否
+
+
+
+ 签约主体是否涉外
+
+ 是
+ 否
+
+
+
+ 是否列入当年预算
+
+ 是
+ 否
+
+
+
+ 是否共享
+
+ 是
+ 否
+
+
+
+ 是否重大合同
+
+ 是
+ 否
+
+
+
+ 是否单方协议
+
+ 是
+ 否
+
+
+
+
+
+ 额外金额
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 删除
+
+
+
+
+
+
+
+
+ 履行计划
+
+
+ 暂无数据
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+