/** * 动火作业票流程环节的运行时辅助 * * 职责: * 1) 取流程实例当前待办任务的信息(任务定义 key + 任务名称) * —— 任务定义 key 由流程设计器决定,与源系统(HO_PERMIT_FIRE_*)不同, * 环节识别需要同时参考任务名称。 * 2) 按节点 schema 从数据源取值(回显) * 3) 环节内容写入流程实例表单变量(合并写入,保留作业票原有字段) * 4) 生成随审批提交的流程变量(字符串化,兼容流程变量类型限制) */ import { getTaskListByProcessInstanceId } from '@/api/bpm/task'; import { getProcessInstance } from '@/api/bpm/processInstance'; import { getFieldKeys } from './fireFlowNodes'; /** * 取流程实例当前待办任务的信息 * @param {string} processInstanceId 流程实例 id * @param {string} taskDefinitionKey 当前任务定义 key(用于精确匹配) * @returns {Promise<{name: string, taskDefinitionKey: string, result: number}>} */ export async function getCurrentTaskInfo(processInstanceId, taskDefinitionKey) { const empty = { name: '', taskDefinitionKey: '', result: 0 }; if (!processInstanceId) { return empty; } try { const list = await getTaskListByProcessInstanceId(processInstanceId); const tasks = Array.isArray(list) ? list : []; if (!tasks.length) { return empty; } const matched = taskDefinitionKey ? tasks.find((task) => task.taskDefinitionKey === taskDefinitionKey) : null; // 待处理中的任务:result 1-待处理、6-处理中 const pending = tasks.find((task) => task.result == 1 || task.result == 6); const task = matched || pending || tasks[0]; return { name: task.name || '', taskDefinitionKey: task.taskDefinitionKey || '', result: task.result }; } catch (e) { return empty; } } /** * 读流程实例表单变量 * @returns {Promise<{loaded: boolean, vars: object}>} loaded=false 表示读取失败(不可合并写入) */ export async function loadProcessFormVariables(processInstanceId) { if (!processInstanceId) { return { loaded: false, vars: {} }; } try { const instance = await getProcessInstance(processInstanceId); return { loaded: true, vars: parseJsonObject(instance && instance.formVariables) }; } catch (e) { return { loaded: false, vars: {} }; } } /** * 合并作业票内容(extensionJson)与环节数据 * @param {object} extension 作业票现有内容 * @param {object} payload 环节字段值 * @returns {object} 合并后的作业票内容 */ export function mergeExtension(extension, payload) { return { ...(extension || {}), ...(payload || {}) }; } /** * 组装作业票修改参数(后端「危险作业票修改请求」契约) * - 扩展数据字段名是 extensionJson,且要求 JSON 字符串 * - 不接收 workId(所属危险作业不可变更) * - status 不传则不修改 * - 取不到的字段直接剔除,避免后端把未取到的值置空 * @param {object} ticket 作业票详情 * @param {object} extension 合并后的作业票内容 * @param {string|number} fallbackId 作业票 id(详情未返回时兜底) * @returns {object} 修改参数 */ export function buildTicketUpdateParams(ticket, extension, fallbackId) { const t = ticket || {}; const params = { id: t.id !== undefined && t.id !== null ? t.id : fallbackId, workType: t.workType === undefined || t.workType === null || t.workType === '' ? undefined : String(t.workType), applyDeptId: t.applyDeptId, applyDeptName: t.applyDeptName, applicantId: t.applicantId, applicantName: t.applicantName, workLocation: t.workLocation, startTime: t.startTime, endTime: t.endTime, extensionJson: JSON.stringify(extension || {}) }; Object.keys(params).forEach((key) => { if (params[key] === undefined) { delete params[key]; } }); return params; } /** * 按节点 schema 从数据源中取值(回显) * @param {object} node 节点定义 * @param {Array} sources 数据源,按优先级从高到低 * @returns {object} { [field.key]: value } */ export function loadNodeValues(node, sources) { const values = {}; (node?.fields || []).forEach((field) => { let value; const keys = getFieldKeys(field); for (const source of sources || []) { for (const key of keys) { const item = source && source[key]; if (item !== undefined && item !== null && item !== '') { value = item; break; } } if (value !== undefined) { break; } } values[field.key] = value; }); return values; } /** * 环节内容转成流程变量(字符串化,兼容流程变量的类型限制) * @param {object} node 节点定义 * @param {object} values 环节字段值 * @returns {object} 流程变量 */ export function buildNodeVariables(node, values) { const vars = {}; (node?.fields || []).forEach((field) => { const value = values ? values[field.key] : undefined; if (value === undefined || value === null || value === '') { return; } if (field.type === 'table') { if (!Array.isArray(value) || !value.length) { return; } vars[field.key] = JSON.stringify(value); return; } if (Array.isArray(value)) { if (!value.length) { return; } vars[field.key] = value.join(','); return; } vars[field.key] = String(value); }); return vars; } /** * 环节内容(保留原始类型,便于详情页按数组/对象回显) * @param {object} node 节点定义 * @param {object} values 环节字段值 * @returns {object} */ export function buildNodePayload(node, values) { const payload = {}; (node?.fields || []).forEach((field) => { const value = values ? values[field.key] : undefined; if (value === undefined || value === null || value === '') { return; } if (Array.isArray(value) && !value.length) { return; } payload[field.key] = value; }); return payload; } /** * 解析 JSON 对象(字符串或对象) */ export function parseJsonObject(raw) { if (!raw) { return {}; } if (typeof raw === 'object') { return Array.isArray(raw) ? {} : { ...raw }; } try { const data = JSON.parse(raw); return data && typeof data === 'object' && !Array.isArray(data) ? data : {}; } catch (e) { return {}; } }