/** * 任务2 种子:简易工作流 * 1) 创建「原料出库审批」流程定义 + 节点(开始 → 车间主管审批 → 结束) * 2) 创建侧边栏菜单:工作流(目录)→ 待办中心 / 我发起的 * 用法:node server/scripts/seed-workflow.mjs */ const BASE = process.env.F9MES_API || 'http://localhost:5136'; const PHONE = '13800000000'; const PASSWORD = '123456'; // 默认审批人:超级管理员(用户ID=1) const APPROVER_ID = 1; async function api(h, method, url, body) { const res = await fetch(BASE + url, { method, headers: h, body: body ? JSON.stringify(body) : undefined, }); const text = await res.text(); let json = null; try { json = JSON.parse(text); } catch { /* ignore */ } if (!res.ok || (json && json.code !== 0)) { throw new Error(`HTTP ${res.status} ${url}: ${text.slice(0, 300)}`); } return json; } async function main() { const login = await api({ 'Content-Type': 'application/json' }, 'POST', '/api/auth/login', { phone: PHONE, password: PASSWORD, }); const token = login.data.token; const h = { Authorization: 'Bearer ' + token, 'Content-Type': 'application/json' }; // ============ 1. 流程定义 ============ const flows = (await api(h, 'GET', '/api/workflow/definitions?bizType=RawMaterial_OutStock')).data || []; let flow = flows.find((f) => f.code === 'RM_OUT_APPROVE'); if (flow) { console.log('流程已存在:id=' + flow.id + ' name=' + flow.name + '(跳过创建)'); } else { // 直接写库:Common_Workflow + Common_WorkflowNode(走通用 data 接口) const addFlow = await api(h, 'POST', '/api/data/Common_Workflow/add', { name: '原料出库审批', code: 'RM_OUT_APPROVE', bizType: 'RawMaterial_OutStock', status: 1, }); const flowId = addFlow.data && (addFlow.data.id ?? addFlow.data); console.log('流程已创建 id=' + flowId); const nodes = [ { workflowId: flowId, name: '发起', nodeType: 0, sort: 10 }, { workflowId: flowId, name: '车间主管审批', nodeType: 1, approverJson: JSON.stringify([APPROVER_ID]), sort: 20 }, { workflowId: flowId, name: '结束', nodeType: 4, sort: 99 }, ]; for (const n of nodes) { const r = await api(h, 'POST', '/api/data/Common_WorkflowNode/add', n); console.log(' 节点「' + n.name + '」id=' + (r.data && (r.data.id ?? r.data))); } flow = { id: flowId }; } // ============ 2. 菜单 ============ const menus = (await api(h, 'GET', '/api/data/BaseSys_Menu/all')).data || []; const items = (menus.items || (Array.isArray(menus) ? menus : [])); let dir = items.find((m) => m.name === '工作流' && m.menuType === 0); if (!dir) { const r = await api(h, 'POST', '/api/data/BaseSys_Menu/add', { name: '工作流', menuType: 0, routePath: '', component: '', icon: 'Checked', isVisible: 1, isEnable: 1, sort: 999, parentId: 0, level: 0, path: '', }); dir = { id: r.data && (r.data.id ?? r.data) }; console.log('菜单目录「工作流」已创建 id=' + dir.id); } else { console.log('菜单目录「工作流」已存在 id=' + dir.id); } const dirId = dir.id; const childDefs = [ { name: '待办中心', routePath: '/workflow/todo', component: 'WorkFlow/todo', icon: 'Bell', sort: 10 }, { name: '我发起的', routePath: '/workflow/my', component: 'WorkFlow/my', icon: 'Document', sort: 20 }, ]; const refresh = (await api(h, 'GET', '/api/data/BaseSys_Menu/all')).data || {}; const allMenus = refresh.items || (Array.isArray(refresh) ? refresh : []); for (const c of childDefs) { const exists = allMenus.find((m) => m.parentId === dirId && m.routePath === c.routePath); if (exists) { console.log('菜单「' + c.name + '」已存在 id=' + exists.id); continue; } const r = await api(h, 'POST', '/api/data/BaseSys_Menu/add', { name: c.name, menuType: 1, routePath: c.routePath, component: c.component, icon: c.icon, isVisible: 1, isEnable: 1, sort: c.sort, parentId: dirId, level: 1, path: '/' + dirId, }); console.log('菜单「' + c.name + '」已创建 id=' + (r.data && (r.data.id ?? r.data))); } console.log('\n完成。流程=' + (flow.id || '?') + '(原料出库审批 RM_OUT_APPROVE)'); } main().catch((e) => { console.error('ERR: ' + e.message); process.exit(1); });