/** * 审批流引擎 * 支持最多 3 步审批(发起人 → 直属上级 → 部门负责人) */ import prisma from '../lib/prisma' interface ApprovalStep { step: number approverType: 'SUPERVISOR' | 'DEPT_HEAD' | 'PERSON' approverId?: string name: string } interface ApprovalRecord { step: number approverId: string approverName: string result: 'APPROVED' | 'REJECTED' comment?: string timestamp: string } /** * 创建审批实例 */ export async function createApprovalInstance( orgId: string, userId: string, type: string, bizId: string, bizType: string, employeeId: string, ): Promise<{ instance: any; firstApprover?: any }> { // 查找该类型的审批流配置 const flow = await prisma.approvalFlow.findFirst({ where: { orgId, type, enabled: true }, }) if (!flow) { // 无审批流配置,直接通过 return { instance: null } } const steps = flow.steps as unknown as ApprovalStep[] if (!steps || steps.length === 0) { return { instance: null } } const instance = await prisma.approvalInstance.create({ data: { orgId, flowId: flow.id, type, bizId, bizType, status: 'PENDING', currentStep: 1, approvals: [], employeeId, createdBy: userId, }, }) // 计算第一步审批人 const firstApprover = await resolveApprover(orgId, employeeId, steps[0]) return { instance, firstApprover } } /** * 根据步骤配置解析审批人 */ async function resolveApprover(orgId: string, employeeId: string, step: ApprovalStep): Promise { const employee = await prisma.employee.findFirst({ where: { id: employeeId, orgId }, include: { dept: true, supervisor: true }, }) if (!employee) return null if (step.approverType === 'SUPERVISOR') { return employee.supervisor ? { id: employee.supervisor.id, name: employee.supervisor.name } : null } else if (step.approverType === 'DEPT_HEAD') { // 部门负责人暂用部门创建人(简化实现) if (employee.dept) { return { id: employee.dept.createdBy, name: '部门负责人' } } return null } else if (step.approverType === 'PERSON' && step.approverId) { const approver = await prisma.employee.findFirst({ where: { id: step.approverId, orgId } }) return approver ? { id: approver.id, name: approver.name } : null } return null } /** * 处理审批 */ export async function processApproval( orgId: string, instanceId: string, approverId: string, approverName: string, result: 'APPROVED' | 'REJECTED', comment?: string, ): Promise<{ status: string; nextApprover?: any }> { const instance = await prisma.approvalInstance.findFirst({ where: { id: instanceId, orgId }, include: { flow: true }, }) if (!instance) throw { code: 'NOT_FOUND', message: '审批实例不存在' } if (instance.status !== 'PENDING') throw { code: 'VALIDATION_ERROR', message: '审批实例已处理' } const steps = instance.flow.steps as unknown as ApprovalStep[] const currentStepConfig = steps.find(s => s.step === instance.currentStep) if (!currentStepConfig) throw { code: 'VALIDATION_ERROR', message: '步骤配置错误' } // 记录审批结果 const approvals = (instance.approvals as unknown as ApprovalRecord[]) || [] approvals.push({ step: instance.currentStep, approverId, approverName, result, comment, timestamp: new Date().toISOString(), }) if (result === 'REJECTED') { await prisma.approvalInstance.update({ where: { id: instanceId }, data: { status: 'REJECTED', approvals: approvals as any }, }) return { status: 'REJECTED' } } // 查找下一步 const nextStepConfig = steps.find(s => s.step === instance.currentStep + 1) if (!nextStepConfig) { // 全部通过 await prisma.approvalInstance.update({ where: { id: instanceId }, data: { status: 'APPROVED', approvals: approvals as any }, }) return { status: 'APPROVED' } } // 进入下一步 const nextApprover = await resolveApprover(orgId, instance.employeeId || '', nextStepConfig) await prisma.approvalInstance.update({ where: { id: instanceId }, data: { currentStep: instance.currentStep + 1, approvals: approvals as any }, }) return { status: 'PENDING', nextApprover } } /** * 取消审批 */ export async function cancelApproval(orgId: string, instanceId: string): Promise { await prisma.approvalInstance.update({ where: { id: instanceId }, data: { status: 'CANCELLED' }, }) }