import dayjs from "dayjs"; import { APPROVAL_TYPE_OPTIONS, SUBMIT_TEMPLATES } from "../approve-list/approveListConstants.js"; /** 节点内审批方式:会签 / 或签 */ export const NODE_SIGN_MODE_OPTIONS = [ { value: "countersign", label: "会签", desc: "本节点所有审批人均需通过" }, { value: "or_sign", label: "或签", desc: "本节点任一审批人通过即可" }, ]; export const STORAGE_KEY = "oa_approve_template_custom_v1"; /** 系统内置常用审批(只读展示,来源于审批列表提交模板) */ export function getBuiltinTemplates() { return Object.entries(SUBMIT_TEMPLATES).map(([key, tpl]) => ({ key, approvalType: tpl.approvalType, label: tpl.label, summary: tpl.summaryPlaceholder || "系统预置填报字段", fieldCount: (tpl.fields || []).length, defaultMode: tpl.approvalMode, })); } export function nodeSignModeLabel(mode) { return NODE_SIGN_MODE_OPTIONS.find((x) => x.value === mode)?.label || "—"; } export function approvalTypeLabel(type) { return APPROVAL_TYPE_OPTIONS.find((x) => x.value === type)?.label || type || "—"; } export function createEmptyNode(order = 1) { return { nodeOrder: order, signMode: "countersign", approvers: [], }; } export function createEmptyTemplateForm() { return { id: "", templateName: "", description: "", enabled: true, flowNodes: [createEmptyNode(1)], }; } export function normalizeFlowNodes(nodes) { const list = Array.isArray(nodes) ? nodes : []; return list.map((n, i) => ({ nodeOrder: i + 1, signMode: n.signMode === "or_sign" ? "or_sign" : "countersign", approvers: (n.approvers || []) .filter((a) => a?.approverId != null && a.approverId !== "") .map((a) => ({ approverId: a.approverId, approverName: a.approverName || "", })), })); } export function validateTemplateForm(form) { const name = (form.templateName || "").trim(); if (!name) return { ok: false, message: "请填写模板名称" }; const nodes = normalizeFlowNodes(form.flowNodes); if (!nodes.length) return { ok: false, message: "请至少配置一个审批节点" }; for (let i = 0; i < nodes.length; i++) { if (!nodes[i].approvers.length) { return { ok: false, message: `请为第 ${i + 1} 个节点选择至少一名审批人` }; } } return { ok: true, nodes, name }; } export function flowNodesSummary(nodes) { const list = normalizeFlowNodes(nodes); if (!list.length) return "—"; return list .map((n, i) => { const names = n.approvers.map((a) => a.approverName || "未命名").join("、") || "未配置"; return `节点${i + 1}(${nodeSignModeLabel(n.signMode)}:${names})`; }) .join(" → "); } export function createInitialMockTemplates() { const now = dayjs().format("YYYY-MM-DD HH:mm:ss"); return [ { id: "tpl_demo_1", templateName: "项目立项审批", description: "跨部门项目立项,需技术、财务依次会签", enabled: true, createTime: dayjs().subtract(5, "day").format("YYYY-MM-DD HH:mm:ss"), updateTime: now, flowNodes: [ { nodeOrder: 1, signMode: "countersign", approvers: [ { approverId: "mock_tech_lead", approverName: "技术负责人" }, { approverId: "mock_pm", approverName: "项目经理" }, ], }, { nodeOrder: 2, signMode: "or_sign", approvers: [ { approverId: "mock_finance", approverName: "财务主管" }, { approverId: "mock_cfo", approverName: "财务总监" }, ], }, ], }, { id: "tpl_demo_2", templateName: "合同用印申请", description: "法务与行政或签后,总经理终审", enabled: true, createTime: dayjs().subtract(12, "day").format("YYYY-MM-DD HH:mm:ss"), updateTime: dayjs().subtract(2, "day").format("YYYY-MM-DD HH:mm:ss"), flowNodes: [ { nodeOrder: 1, signMode: "or_sign", approvers: [ { approverId: "mock_legal", approverName: "法务专员" }, { approverId: "mock_admin", approverName: "行政主管" }, ], }, { nodeOrder: 2, signMode: "countersign", approvers: [{ approverId: "mock_ceo", approverName: "总经理" }], }, ], }, ]; } export function loadStoredTemplates() { try { const raw = localStorage.getItem(STORAGE_KEY); if (!raw) return null; const parsed = JSON.parse(raw); return Array.isArray(parsed) ? parsed : null; } catch { return null; } } export function saveStoredTemplates(rows) { try { localStorage.setItem(STORAGE_KEY, JSON.stringify(rows)); } catch { /* ignore */ } }