import { NfNode } from "./entity/nfnode"; /** * 人工任务候选人 / 指派工具。 * * 用户、组在任务字段中一律使用 id,存储格式为 `,1,2,3,`。 */ export class NFTaskUtil{ /** * 将 id 列表格式化为 `,1,2,3,`,便于 `like` 查询。 * * @param ids - 用户或组 id 数组 * @returns 逗号包裹串;空列表为 `,,` */ static formatIdList(ids:Array):string{ if(!ids || ids.length === 0){ return ',,'; } const arr = ids.map(v=>Number(v)).filter(n=>!isNaN(n)); if(arr.length === 0){ return ',,'; } return ',' + arr.join(',') + ','; } /** * 解析候选人 / 候选组 id 串,兼容单个数字或数组。 * * @param str - 逗号串、数字或数组 * @returns 数字 id 数组 */ static parseIdList(str:string|number|Array):number[]{ if(str == null || str === ''){ return []; } if(typeof str === 'number'){ return isNaN(str) ? [] : [str]; } if(Array.isArray(str)){ return str.map(v=>Number(v)).filter(n=>!isNaN(n)); } return String(str).split(',').map(s=>s.trim()).filter(s=>s !== '').map(s=>Number(s)).filter(n=>!isNaN(n)); } /** * 判断用户所属组是否命中节点 `candidateGroups`(按组 id)。 * * @param stored - 节点上存储的候选组串 * @param groupIds - 用户所属组 id * @returns 是否命中 */ static matchCandidateGroups(stored:string,groupIds?:number[]):boolean{ if(!stored || !groupIds || groupIds.length === 0){ return false; } const nodeGroups = new Set(NFTaskUtil.parseIdList(stored)); return groupIds.some(g=>nodeGroups.has(Number(g))); } /** * 判断用户是否可办理该任务:已指派给本人,或未指派且在候选人 / 候选组中。 * * @param node - 任务节点实体 * @param userId - 用户 id * @param groupIds - 用户所属组 id * @returns 是否可办理 */ static isCandidate(node:NfNode,userId:number,groupIds?:number[]):boolean{ if(!node || userId == null){ return false; } if(node.assignee != null){ return Number(node.assignee) === Number(userId); } if(NFTaskUtil.parseIdList(node.candidateUsers).includes(Number(userId))){ return true; } return NFTaskUtil.matchCandidateGroups(node.candidateGroups, groupIds); } }