细节修改
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user