/** * 曼卡龙合同页面同步区(可复制到各合同页面 JS)。 * * 使用说明: * 1. 按当前页面修改 getMankalongContractFieldIds() 中的组件 ID。 * 2. didMount 中先调用 await this._mklLoad(),再调用 await this.initMankalongContractPage()。 * 3. 保留页面原有“生成合同”按钮及 generateSubFormImages 请求逻辑。 * 开始、结束、成功后分别调用 this.startMankalongContractGenerate()、 * this.finishMankalongContractGenerate()、this.markMankalongContractGenerated()。 * 4. “合同确认”按钮绑定 onClickContractConfirm。 * 5. 唯一标识必须从当前页面组件读取,读取失败直接抛出异常;合同确认内部使用 toast loading/error。 * 6. 已部署旧复制区的页面按函数级合并,复制区外代码和“页面自定义初始化保留区”不得覆盖。 * 7. 页面没有“主从合同”组件、但业务上关联特许经营合同时,mode 设为空字符串, * contractMode 固定设为“子合同”;不得按主合同处理,也不得伪造组件 ID。 * * 依赖:页面已加载 mjs.corp.mkl(https://mc.cloudpure.cn/mjs/mkl/mjs.min.js)。 */ // ============================================================ // 曼卡龙合同初始化与按钮防抖(可复制同步区域开始) // ============================================================ /** * 加载曼卡龙专用 MJS 公共库。 * @returns {Promise} 加载完成 */ export function _mklLoad() { if (window.__mankalongMjsReady) return window.__mankalongMjsReady; window.__mankalongMjsReady = new Promise((resolve, reject) => { const existing = document.querySelector('script[data-mankalong-mjs="1"]'); if (existing) { if (window.mjs && mjs.corp && mjs.corp.mkl) { this._mklInit().then(resolve).catch(reject); } else { existing.addEventListener('load', () => this._mklInit().then(resolve).catch(reject)); existing.addEventListener('error', reject); } return; } const script = document.createElement('script'); script.type = 'text/javascript'; script.src = 'https://mc.cloudpure.cn/mjs/mkl/mjs.min.js?v=20260831-3'; script.dataset.mankalongMjs = '1'; script.onload = () => this._mklInit().then(resolve).catch(reject); script.onerror = reject; document.head.appendChild(script); }); return window.__mankalongMjsReady; } /** * 初始化 MJS 曼卡龙模块。 * @returns {Promise} 初始化结果 */ export async function _mklInit() { await mjs.init(this, { vconsole: false }); mjs.corp.mkl.init({ environment: 'production', testApi: 'https://mc.cloudpure.cn/frphz/mankalong', productionApi: 'https://znht.mclon.com/api/mankalong', }); } /** * @returns {Object} 当前合同页面组件 ID */ export function getMankalongContractFieldIds() { return { // 合同唯一标识(业务唯一号) uniqueId: 'textField_mte3gh61', // 合同编号 contractNo: 'textField_mrishceq', // 主从合同 mode: 'radioField_mryiusal', // 没有主从合同组件时的固定业务值;关联特许经营合同的页面设为“子合同” contractMode: '', // 合同类型 type: 'textField_mspzgras', // 关联合同编号 masterNo: 'textField_mrylbq28', // 合同标题 name: 'textField_mryko9bh', // 合同正文 attachment: 'attachmentField_msv7rz7m', // 发起人 initiator: 'employeeField_mrishcex', // 生成合同按钮 generateButton: 'button_msiiyhct', // 合同确认按钮 confirmButton: 'button_mtfaz1tq', // 仅发起人可见区块 initiatorOnlySection: 'pageSection_mte7a077', // 合同操作区块 contractOperationSection: 'pageSection_mte7a078', // 合同预览区块 previewSection: 'pageSection_msruj1an', // 合同预览 iframe previewFrame: 'iframe_msn38cuu', // 生成预览附件地址 previewUrl: 'textField_msnynxia', }; } /** * 从当前页面实例读取合同业务唯一标识。 * @param {Object} page 当前宜搭页面实例 * @returns {string} 合同业务唯一标识 */ function readMankalongContractUniqueId(page, componentId) { const component = page && typeof page.$ === 'function' ? page.$(componentId) : null; if (!component || typeof component.getValue !== 'function') { throw new Error('合同唯一标识组件不存在: ' + componentId); } let value = component.getValue(); if (Array.isArray(value)) { value = value[0] && (value[0].value || value[0].label || value[0].name); } else if (value && typeof value === 'object') { value = value.value || value.label || value.name; } const normalized = String(value || '').trim(); if (!normalized) throw new Error('合同唯一标识不能为空'); return normalized; } /** * @param {Object} page 当前宜搭页面实例 * @param {string} componentId 字段组件 ID * @param {string} fieldName 字段名称 * @returns {string} 字段值 */ function readMankalongContractFieldValue(page, componentId, fieldName) { const component = page && typeof page.$ === 'function' ? page.$(componentId) : null; if (!component || typeof component.getValue !== 'function') { throw new Error(fieldName + '组件不存在: ' + componentId); } let value = component.getValue(); if (Array.isArray(value)) { value = value[0] && (value[0].value || value[0].label || value[0].name || value[0].zh_CN || value[0].en_US); } else if (value && typeof value === 'object') { value = value.value || value.label || value.name || value.zh_CN || value.en_US; } const normalized = String(value || '').trim(); if (!normalized) throw new Error(fieldName + '不能为空'); return normalized; } /** * @returns {Promise} 初始化后的合同页面状态 */ export async function initMankalongContractPage() { const ids = this.getMankalongContractFieldIds(); if (mjs.env == 0) { const initiatorOnlySection = this.$(ids.initiatorOnlySection); if (!initiatorOnlySection || typeof initiatorOnlySection.setBehavior !== 'function') { throw new Error('仅发起人可见区块不存在或不支持状态设置: ' + ids.initiatorOnlySection); } initiatorOnlySection.setBehavior('HIDDEN'); const contractNo = this.$(ids.contractNo); const contractValue = contractNo && typeof contractNo.getValue === 'function' ? contractNo.getValue() : ''; const contractNumber = Array.isArray(contractValue) ? (contractValue[0] && (contractValue[0].value || contractValue[0].label || contractValue[0].name)) || '' : contractValue && typeof contractValue === 'object' ? contractValue.value || contractValue.label || contractValue.name || '' : String(contractValue || ''); if (contractNumber) { const unique = this.$(ids.uniqueId); if (!unique || typeof unique.setValue !== 'function') { throw new Error('合同唯一标识组件不存在或不支持赋值: ' + ids.uniqueId); } const userId = this.utils && typeof this.utils.getLoginUserId === 'function' ? this.utils.getLoginUserId() : window.loginUser && window.loginUser.userId; if (!userId) throw new Error('当前用户 ID 不能为空,无法生成新的合同唯一标识'); unique.setValue(String(userId) + '-' + Date.now() + '-' + Math.random().toString(36).slice(2, 10)); } if (contractNo && typeof contractNo.reset === 'function') contractNo.reset(); const attachment = this.$(ids.attachment); if (attachment && typeof attachment.reset === 'function') attachment.reset(); // 页面自定义初始化保留区开始 // 页面自定义初始化保留区结束 } else { const initiatorUserId = readMankalongContractFieldValue(this, ids.initiator, '发起人'); const loginUserId = this.utils && typeof this.utils.getLoginUserId === 'function' ? this.utils.getLoginUserId() : window.loginUser && window.loginUser.userId; if (!loginUserId) throw new Error('当前登录用户 ID 不能为空'); if (initiatorUserId !== String(loginUserId)) { const initiatorOnlySection = this.$(ids.initiatorOnlySection); if (!initiatorOnlySection || typeof initiatorOnlySection.setBehavior !== 'function') { throw new Error('仅发起人可见区块不存在或不支持状态设置: ' + ids.initiatorOnlySection); } initiatorOnlySection.setBehavior('HIDDEN'); } const contractOperationSection = this.$(ids.contractOperationSection); if (!contractOperationSection || typeof contractOperationSection.setBehavior !== 'function') { throw new Error('合同操作区块不存在或不支持状态设置: ' + ids.contractOperationSection); } contractOperationSection.setBehavior('HIDDEN'); } return mjs.corp.mkl.initContractPage({ $this: this, componentIds: ids, }); } /** * @returns {boolean} 是否允许开始合同生成 */ export function startMankalongContractGenerate() { return mjs.corp.mkl.startContractGenerate({ $this: this, componentIds: this.getMankalongContractFieldIds(), }); } /** * @returns {Object} 当前页面合同状态 */ export function finishMankalongContractGenerate() { return mjs.corp.mkl.finishContractGenerate({ $this: this, componentIds: this.getMankalongContractFieldIds(), }); } /** * 原有合同生成请求成功后调用,仅更新合同确认按钮 UI 状态。 * @returns {Object} 当前页面合同状态 */ export function markMankalongContractGenerated() { return mjs.corp.mkl.markContractGenerated({ $this: this, componentIds: this.getMankalongContractFieldIds(), }); } /** * 通过原有合同合成接口生成正式文件,供 MJS 合同确认流程上传 OSS。 * @param {Object} params 合同生成参数 * @returns {Promise} 合成文件地址 */ export async function generateMankalongContractFile({ contractNumber, mode, allowMissingInstanceId }) { const ids = this.getMankalongContractFieldIds(); const fieldsResponse = await mjs.request.xhr.doPost('/api/yida/getFormFields', { formUuid: getFormUuid(), }, {}, { ignoreResponse: true, noLoading: true, noErrorTip: true, }); const fieldIds = fieldsResponse && Array.isArray(fieldsResponse.data) ? fieldsResponse.data : []; const formData = fieldIds .map((fieldId) => { try { const component = fieldId && this.$(fieldId); if (!component || typeof component.getValue !== 'function') { console.warn('跳过当前页面不存在的组件 ID:', fieldId); return null; } return { structKey: fieldId, structValue: String(component.getValue() || ''), }; } catch (error) { console.warn('读取组件 ID 失败,已跳过:', fieldId, error); return null; } }) .filter((item) => item !== null); const instanceId = this.utils.router.getQuery('procInsId') || (mjs.com && mjs.com.getFormInstIdByUrl && mjs.com.getFormInstIdByUrl()); const generateMode = mode || 'generate'; if (generateMode === 'generate' && !instanceId && !allowMissingInstanceId) { throw new Error('当前页面缺少流程实例 ID,无法生成正式合同'); } const body = { formUuid: getFormUuid(), mappings: [], formData, type: generateMode, unique: readMankalongContractUniqueId(this, ids.uniqueId), instanceId: instanceId || '', preSubmit: allowMissingInstanceId === true, dingOrgId: '908563201', dingUid: this.state && this.state.userId || this.utils.getLoginUserId(), corpId: 'ding3735baea6bea68ac24f2f5cc6abecb85', contractNumber, }; const response = await mjs.request.xhr.doPost('/api/yida/subform-to-image', {}, body, { noLoading: true, noErrorTip: true, }); const fileUrl = response && (response.message || response.downloadUrl || response.fileUrl || response.url); if (!fileUrl) throw new Error('合同合成接口未返回文件地址'); return fileUrl; } /** * @returns {Promise} 合同确认结果 */ export async function onClickContractConfirm() { const ids = this.getMankalongContractFieldIds(); const uniqueId = readMankalongContractUniqueId(this, ids.uniqueId); return mjs.corp.mkl.runContractConfirm({ $this: this, componentIds: ids, uniqueId, contractType: readMankalongContractFieldValue(this, ids.type, '合同类型'), contractMode: ids.contractMode || readMankalongContractFieldValue(this, ids.mode, '合同主从类型'), subDirectory: '工程类', generateMode: 'generate', allowMissingInstanceId: true, generateContract: (params) => this.generateMankalongContractFile(params), }); } /** * @returns {boolean} 是否允许提交 */ export function beforeSubmitContractReady() { if (!window.mjs || !mjs.corp || !mjs.corp.mkl) { this.utils.dialog({ type: 'alert', title: '提示', content: '合同还未正式生成,请操作!', }); return false; } return mjs.corp.mkl.beforeSubmitContract({ $this: this, componentIds: this.getMankalongContractFieldIds(), }); } /** * @returns {void} 清理合同页面状态 */ export function disposeMankalongContractPage() { if (!window.mjs || !mjs.corp || !mjs.corp.mkl) return; mjs.corp.mkl.disposeContractPage({ $this: this }); } // ============================================================ // 曼卡龙合同初始化与按钮防抖(可复制同步区域结束) // ============================================================