细节修改
This commit is contained in:
@@ -1080,12 +1080,9 @@ const paymentMethodOptions = [
|
|||||||
{ label: "银行转账(一次性结清)", value: "银行转账(一次性结清)" },
|
{ label: "银行转账(一次性结清)", value: "银行转账(一次性结清)" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const SELF_COMPANY_NAME = "浙港物流平台有限公司";
|
|
||||||
const PARTY_ROLE_OUR = "OUR";
|
const PARTY_ROLE_OUR = "OUR";
|
||||||
const PARTY_ROLE_OPPOSITE = "OPPOSITE";
|
const PARTY_ROLE_OPPOSITE = "OPPOSITE";
|
||||||
|
|
||||||
// ========== 工具函数 ==========
|
|
||||||
|
|
||||||
function formatDateTimeValue(value, endOfDay = false) {
|
function formatDateTimeValue(value, endOfDay = false) {
|
||||||
if (!value) return null;
|
if (!value) return null;
|
||||||
if (String(value).includes(" ")) return value;
|
if (String(value).includes(" ")) return value;
|
||||||
@@ -1354,7 +1351,6 @@ function normalizePartyState(partyState) {
|
|||||||
: [
|
: [
|
||||||
{
|
{
|
||||||
...createEmptyParty(PARTY_ROLE_OUR, 0),
|
...createEmptyParty(PARTY_ROLE_OUR, 0),
|
||||||
companyName: SELF_COMPANY_NAME,
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const counterpartyList = normalizePartyArray(
|
const counterpartyList = normalizePartyArray(
|
||||||
@@ -1467,7 +1463,6 @@ function createContractFormData() {
|
|||||||
ourPartyList: [
|
ourPartyList: [
|
||||||
{
|
{
|
||||||
...createEmptyParty(PARTY_ROLE_OUR, 0),
|
...createEmptyParty(PARTY_ROLE_OUR, 0),
|
||||||
companyName: SELF_COMPANY_NAME,
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
counterpartyList: [],
|
counterpartyList: [],
|
||||||
@@ -2446,7 +2441,7 @@ function applySelfProfile(profile = {}) {
|
|||||||
createEmptyParty(PARTY_ROLE_OUR, 0);
|
createEmptyParty(PARTY_ROLE_OUR, 0);
|
||||||
currentSelfParty.value = {
|
currentSelfParty.value = {
|
||||||
...createEmptyParty(PARTY_ROLE_OUR, 0),
|
...createEmptyParty(PARTY_ROLE_OUR, 0),
|
||||||
companyName: profile.orgName || SELF_COMPANY_NAME,
|
companyName: profile.orgName || "",
|
||||||
subjectCode: profile.id || "",
|
subjectCode: profile.id || "",
|
||||||
contactPhone: profile.contactPhone || "",
|
contactPhone: profile.contactPhone || "",
|
||||||
contactEmail: profile.contactEmail || "",
|
contactEmail: profile.contactEmail || "",
|
||||||
@@ -2458,9 +2453,9 @@ function applySelfProfile(profile = {}) {
|
|||||||
creditCode: profile.creditCode || "",
|
creditCode: profile.creditCode || "",
|
||||||
};
|
};
|
||||||
const shouldHydrateFirstParty =
|
const shouldHydrateFirstParty =
|
||||||
!firstOurParty.companyName ||
|
(!firstOurParty.companyName && !firstOurParty.subjectCode) ||
|
||||||
firstOurParty.companyName === SELF_COMPANY_NAME ||
|
firstOurParty.companyName === profile.orgName ||
|
||||||
firstOurParty.companyName === profile.orgName;
|
(profile.id && firstOurParty.subjectCode === profile.id);
|
||||||
if (!shouldHydrateFirstParty) {
|
if (!shouldHydrateFirstParty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -198,44 +198,14 @@ import {
|
|||||||
loadTemplateFieldList,
|
loadTemplateFieldList,
|
||||||
} from "../../shared/templateFieldDict.js";
|
} from "../../shared/templateFieldDict.js";
|
||||||
import {
|
import {
|
||||||
contractSourceOptions,
|
|
||||||
contractTypeOptions,
|
|
||||||
currencyOptions,
|
|
||||||
dateTypeOptions,
|
|
||||||
extraAmountFieldOptions,
|
extraAmountFieldOptions,
|
||||||
getOptionLabel,
|
|
||||||
isElectronOptions,
|
|
||||||
paymentDirectionOptions,
|
|
||||||
sealTypeOptions,
|
|
||||||
textSourceOptions,
|
|
||||||
valuationModeOptions,
|
|
||||||
} from "../contractLaunchOptions.js";
|
} from "../contractLaunchOptions.js";
|
||||||
|
|
||||||
// ========================================================================
|
|
||||||
// 以下为表单模型 + 字典 + 工具函数,直接内联在此文件中。
|
|
||||||
// 接入后端时,可保留这些函数,将入参来源/出参提交替换为真实接口即可。
|
|
||||||
// ========================================================================
|
|
||||||
|
|
||||||
// ========== 创建方式选项 ==========
|
|
||||||
const contractCreateModeOptions = [
|
const contractCreateModeOptions = [
|
||||||
{ label: "模板创建", value: "template" },
|
{ label: "模板创建", value: "template" },
|
||||||
{ label: "手动创建", value: "manual" },
|
{ 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 = {}) {
|
function normalizeFileItem(item = {}) {
|
||||||
return {
|
return {
|
||||||
uid:
|
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 = {}) {
|
function restoreExtraAmounts(source = {}, current = {}) {
|
||||||
const result = { ...current, ...(source.extraAmounts || {}) };
|
const result = { ...current, ...(source.extraAmounts || {}) };
|
||||||
const selectedCodes = String(source.ewAmountType || "")
|
const selectedCodes = String(source.ewAmountType || "")
|
||||||
@@ -328,30 +279,9 @@ function restoreExtraAmounts(source = {}, current = {}) {
|
|||||||
return result;
|
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_OUR = "OUR";
|
||||||
const PARTY_ROLE_OPPOSITE = "OPPOSITE";
|
const PARTY_ROLE_OPPOSITE = "OPPOSITE";
|
||||||
const PARTY_NAME_KEYS = [
|
|
||||||
"partyAName",
|
|
||||||
"partyBName",
|
|
||||||
"partyCName",
|
|
||||||
"partyDName",
|
|
||||||
"partyEName",
|
|
||||||
"partyFName",
|
|
||||||
];
|
|
||||||
|
|
||||||
function createParty(roleCode = PARTY_ROLE_OPPOSITE, index = 0) {
|
function createParty(roleCode = PARTY_ROLE_OPPOSITE, index = 0) {
|
||||||
return {
|
return {
|
||||||
@@ -456,71 +386,6 @@ function buildPartyStateFromList(list = []) {
|
|||||||
state.isThreePartyContract = state.counterpartyList.length > 1;
|
state.isThreePartyContract = state.counterpartyList.length > 1;
|
||||||
return state;
|
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() {
|
function createPerformancePlan() {
|
||||||
return {
|
return {
|
||||||
@@ -535,10 +400,6 @@ function createPerformancePlan() {
|
|||||||
planDetail: "",
|
planDetail: "",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 合同发起表单数据模型 ==========
|
|
||||||
|
|
||||||
/** 创建空白的合同表单数据 */
|
|
||||||
function createContractFormData() {
|
function createContractFormData() {
|
||||||
return {
|
return {
|
||||||
id: null,
|
id: null,
|
||||||
@@ -738,9 +599,6 @@ function copyContractFormData(data = {}) {
|
|||||||
return form;
|
return form;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 模板变量预览数据构建 ==========
|
|
||||||
|
|
||||||
/** 将合同表单数据转换为模板变量字典(用于 docxtemplater 渲染) */
|
|
||||||
function buildTemplateRenderData(templateFieldValues = {}) {
|
function buildTemplateRenderData(templateFieldValues = {}) {
|
||||||
const data = {};
|
const data = {};
|
||||||
(templateFieldList.value || []).forEach((item) => {
|
(templateFieldList.value || []).forEach((item) => {
|
||||||
@@ -749,99 +607,10 @@ function buildTemplateRenderData(templateFieldValues = {}) {
|
|||||||
return data;
|
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 emit = defineEmits(["save"]);
|
||||||
|
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
const previewRef = ref(null);
|
const previewRef = ref(null);
|
||||||
const formRef = ref(null);
|
|
||||||
const modalMode = ref("create");
|
const modalMode = ref("create");
|
||||||
const creationMode = ref("template");
|
const creationMode = ref("template");
|
||||||
const templateKey = ref("");
|
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(
|
watch(
|
||||||
() => visible.value,
|
() => visible.value,
|
||||||
(open) => {
|
(open) => {
|
||||||
@@ -1030,6 +813,7 @@ function clearPreviewTimer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchTemplateBuffer(templateFilePath) {
|
async function fetchTemplateBuffer(templateFilePath) {
|
||||||
|
|
||||||
const cached = templateBufferCache.get(templateFilePath);
|
const cached = templateBufferCache.get(templateFilePath);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
return cached.slice(0);
|
return cached.slice(0);
|
||||||
|
|||||||
@@ -514,19 +514,6 @@ function resolveUploadedFilePath(res) {
|
|||||||
return ''
|
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) {
|
function extractVariablesFromText(text) {
|
||||||
const result = new Set()
|
const result = new Set()
|
||||||
|
|||||||
Reference in New Issue
Block a user