import { Method } from "alova"; import { alovaInstance } from "@/utils/alova/alova-iview"; /** * 流程中心用户面/管理面接口(/api/flow/**)。 * 响应 {code,msg,data} 由 alova 实例统一解包(code!=0 抛错提示)。 */ const ROOT = "/api/flow"; function get(url: string, params?: Record): Method { return new Method("GET", alovaInstance, url, { params }); } // alova 的请求体是 Method 构造的第 5 个参数(instance.data),不是 config 上的键: // 写进 config 的 body/data 都会被适配器忽略,POST 将发出空 body。 function post(url: string, body?: any): Method { return new Method("POST", alovaInstance, url, {}, body); } /** 状态枚举(后端 FlwEnums 口径) */ export const INSTANCE_STATUS: Record = { 10: "审批中", 20: "已完成", 30: "已拒绝", 40: "已撤回", }; /** 状态列 Tag 主题色(与 INSTANCE_STATUS 同码表,缺省灰) */ export const INSTANCE_STATUS_COLOR: Record = { 10: "blue", 20: "green", 30: "red", 40: "gray", }; export const TASK_STATUS: Record = { 0: "待办", 1: "同意", 2: "拒绝", 3: "失效", 4: "退回", 5: "移交", // 6/7 为轨迹留痕事件行(发起/重新提交、撤回),不是审批动作 6: "提交", 7: "撤回", }; /** 任务结果 Tag 主题色(同 TASK_STATUS 码表,缺省灰) */ export const TASK_STATUS_COLOR: Record = { 0: "blue", 1: "green", 2: "red", 3: "default", 4: "orange", 5: "cyan", 6: "green", 7: "orange", }; class FlowApi { // ==================== 用户面 ==================== /** 我的待办(appKey=按应用筛选,可空) */ todo(params: { page?: number; size?: number; appKey?: string }) { return get(`${ROOT}/todo`, params); } /** 我的已办(appKey=按应用筛选,可空) */ done(params: { page?: number; size?: number; appKey?: string }) { return get(`${ROOT}/done`, params); } /** 我的抄送(NOTIFY 节点落库;知会不占待办,独立页签) */ ccMy(params: { page?: number; size?: number; appKey?: string }) { return get(`${ROOT}/cc/my`, params); } /** 我提交的办件 */ my(params: { status?: number; page?: number; size?: number; appKey?: string }) { return get(`${ROOT}/my`, params); } /** 办件详情(提交人/办理人/本校管理员可见) */ detail(instanceId: number | string) { return get(`${ROOT}/instance/${instanceId}`); } /** 任务定位办件详情(办理页 /task/:taskId 数据源) */ taskDetail(taskId: number | string) { return get(`${ROOT}/task/${taskId}/detail`); } /** 同意(多出口节点必须传 edgeName=所选出口名,单出口可省) */ approve(taskId: number | string, opinion?: string, edgeName?: string) { return post(`${ROOT}/task/${taskId}/approve`, { opinion: opinion || null, edgeName: edgeName || null }); } /** 退回(targetNodeId 可选=缺省最近已办主线节点;opinion 可选) */ returnBack(taskId: number | string, targetNodeId?: string, opinion?: string) { return post(`${ROOT}/task/${taskId}/returnBack`, { targetNodeId: targetNodeId || null, opinion: opinion || null }); } /** 移交(toUserId 必填;reason 可选) */ transfer(taskId: number | string, toUserId: number, reason?: string) { return post(`${ROOT}/task/${taskId}/transfer`, { toUserId, reason: reason || null }); } /** 拒绝(opinion 必填) */ reject(taskId: number | string, opinion: string) { return post(`${ROOT}/task/${taskId}/reject`, { opinion }); } /** 撤回(提交人;仅尚无任务被办理时) */ withdraw(instanceId: number | string) { return post(`${ROOT}/instance/${instanceId}/withdraw`); } /** 催办(提交人/管理员) */ urge(instanceId: number | string) { return post(`${ROOT}/instance/${instanceId}/urge`); } // ==================== 用户面:流程示意图 ==================== /** 流程示意图(flowGuid=最高已发布版;instanceId=办件 def 快照版;mode=dept|user,缺省 user) */ diagram(params: { flowGuid?: string; instanceId?: number | string; mode?: string }) { return get(`${ROOT}/diagram`, params); } /** 流程源码(图示页「源码」抽屉;可见性同 /diagram) */ defSource(params: { flowGuid?: string; instanceId?: number | string }) { return get(`${ROOT}/def/source`, params); } // ==================== 管理面:流程定义 ==================== defList(params?: { status?: number; appKey?: string }) { return get(`${ROOT}/admin/def/list`, params); } /** 应用清单("按应用筛选"下拉):本校 flw_def 已标注 ∪ 已注册回调的应用 */ defAppKeys() { return get(`${ROOT}/admin/def/appkeys`); } // ==================== 管理面:应用设置(2026-10-10) ==================== /** 应用管理列表(flw_app 白名单;附带学校池静默同步,UserBase 不可达降级本地行) */ appList() { return get(`${ROOT}/admin/app/list`); } /** 开关某应用是否对接流程(停用后 defSave 归属应用校验拦截新引用) */ appEnable(id: number | string, enabled: boolean) { return post(`${ROOT}/admin/app/enable`, { id, enabled }); } /** 应用辅助统计:appKey → 回调注册数(本校) */ appStats() { return get(`${ROOT}/admin/app/stats`); } defGet(id: number | string) { return get(`${ROOT}/admin/def/get`, { id }); } defSave(body: { id?: number; code: string; name: string; contentJson: string; baseGuid?: string; appKey?: string; changeLog?: string }) { return post(`${ROOT}/admin/def/save`, body); } /** 元数据原地编辑(2026-10-10 议题2):只改 name/appKey 不升版本;已发布亦可 */ defUpdateMeta(body: { id: number; name: string; appKey?: string }) { return post(`${ROOT}/admin/def/updateMeta`, body); } defPublish(id: number | string) { return post(`${ROOT}/admin/def/publish/${id}`); } defOffline(id: number | string) { return post(`${ROOT}/admin/def/offline/${id}`); } /** 启用(与 defOffline 对称:仅停用版 → 已发布,重跑发布期静态校验) */ defEnable(id: number | string) { return post(`${ROOT}/admin/def/enable/${id}`); } defVersions(flowGuid: string) { return get(`${ROOT}/admin/def/versions`, { flowGuid }); } /** 在途办件数(议题二④):flowGuid → 审批中办件数,无在途的流程线也返回 0 键 */ defInflight(flowGuids: string[]) { return get(`${ROOT}/admin/def/inflight`, { flowGuids: flowGuids.join(",") }); } /** 流程定义示意图(管理面:defId 任意版本,草稿可预览) */ adminDefDiagram(params: { id: number | string; mode?: string }) { return get(`${ROOT}/admin/def/diagram`, params); } // ==================== 管理面:科室管理(2026-10-10,取代旧 /map/* 映射 CRUD) ==================== /** 科室列表(deptKey=自增 id 字符串 + 启用成员数;编辑器 ctx.depts 同结构) */ deptList() { return get(`${ROOT}/admin/dept/list`); } deptCreate(deptName: string) { return post(`${ROOT}/admin/dept/create`, { deptName }); } deptRename(id: number | string, deptName: string) { return post(`${ROOT}/admin/dept/rename`, { id, deptName }); } deptStatus(id: number | string, enabled: boolean) { return post(`${ROOT}/admin/dept/status`, { id, enabled }); } deptDelete(id: number | string) { return post(`${ROOT}/admin/dept/delete`, { id }); } deptMembers(deptId: number | string) { return get(`${ROOT}/admin/dept/members`, { deptId }); } /** 批量加成员(返回新增数) */ deptMemberAdd(deptId: number | string, userIds: number[]) { return post(`${ROOT}/admin/dept/memberAdd`, { deptId, userIds }); } deptMemberRemove(memberId: number | string) { return post(`${ROOT}/admin/dept/memberRemove`, { memberId }); } /** 一键拉取教师组·预览(不落库,确认后导入) */ deptGroupPreview() { return get(`${ROOT}/admin/dept/groupPreview`); } /** 一键拉取教师组·导入(source_group_id 幂等;重复拉取=刷新组名与成员集) */ deptImportGroups() { return post(`${ROOT}/admin/dept/importGroups`); } /** 成员检索(UserBase byId;编辑器选人/姓名补全共用,原 /map/lookupUser 通道保留) */ mapLookupUser(userId: number) { return get(`${ROOT}/admin/map/lookupUser`, { userId }); } /** 选人组件数据源:学校组树(组→组内用户叶子) */ adminUserTree() { return get(`${ROOT}/admin/user/tree`); } /** 选人组件数据源·教师版(仿 Notice:组树骨架 + YschClassOpenApi 教师按 GroupIds 挂组) */ adminTeacherTree() { return get(`${ROOT}/admin/user/teacherTree`); } // ==================== 管理面:回调注册/日志/死信 ==================== regList() { return get(`${ROOT}/admin/callback/regList`); } regStatus(id: number | string, enabled: boolean) { return post(`${ROOT}/admin/callback/regStatus/${id}?enabled=${enabled}`); } regResetSecret(id: number | string) { return post(`${ROOT}/admin/callback/resetSecret/${id}`); } /** 回调探测:对该注册同步推一条 flow.ping(未知事件码),返回 {success,httpStatus,elapsedMs,respSnippet,error} */ callbackProbe(id: number | string) { return post(`${ROOT}/admin/callback/probe/${id}`); } callbackLogs(params: { status?: number; event?: string; instanceId?: number; page?: number; size?: number }) { return get(`${ROOT}/admin/callback/logs`, params); } callbackDead(params: { page?: number; size?: number }) { return get(`${ROOT}/admin/callback/dead`, params); } /** 挂起列表(待推且重试达阈值) */ callbackHung(params: { page?: number; size?: number }) { return get(`${ROOT}/admin/callback/hung`, params); } /** 手工标记死信(标记后可 repush 复活) */ callbackMarkDead(id: number | string) { return post(`${ROOT}/admin/callback/markDead/${id}`); } callbackRepush(ids: number[]) { return post(`${ROOT}/admin/callback/repush`, ids); } /** 对接健康度体检(2026-10-15 P2):每应用一行六项检查 + 综合评分,零新增表 */ callbackHealth() { return get(`${ROOT}/admin/callback/health`); } // ==================== 管理面:条件路由注册 / 重跑 ==================== /** 判断服务注册列表(flw_router 全局表;编辑器下拉与管理页共用) */ routerList() { return get(`${ROOT}/admin/router/list`); } routerSave(body: { id?: number; routerKey: string; name: string; serviceKey: string; path: string; basePath?: string; }) { return post(`${ROOT}/admin/router/save`, body); } /** 启用/停用注册(停用后发布校验拦截新引用) */ routerStatus(id: number | string, enabled: boolean) { return post(`${ROOT}/admin/router/status/${id}?enabled=${enabled}`); } /** * 重跑路由(判断失败挂起的恢复入口:重新调判断,成功即按出口续走)。 * useLatestDef=true(F5-4 僵尸逃生门):按该流程当前已发布最高版本重跑并刷新办件定义快照。 */ instanceReroute(instanceId: number | string, useLatestDef?: boolean) { const suffix = useLatestDef ? "?useLatestDef=true" : ""; return post(`${ROOT}/admin/instance/${instanceId}/reroute${suffix}`); } /** 表达式调试求值(2026-10-10:与运行时同一求值核心;不落库不走流程) */ routerEval(body: { expression: string; variablesJson?: string }) { return post(`${ROOT}/admin/router/eval`, body); } // ==================== 管理面:办件查询 ==================== adminInstances(params: { status?: number; keyword?: string; page?: number; size?: number }) { return get(`${ROOT}/admin/instance/page`, params); } /** * 发起时指派预览(F6 共享选择器数据源;与 oapi /oapi/flow/apply/preview 同形: * {flowGuid, defVersion, nodes:[{nodeId,nodeName,countersign,selection,candidates}]})。 * 纯预置:后端 /api 代理端点属 F6 正式接入批次,接线时同批点亮(FlowAssignSelector 当前为备用组件)。 */ applyPreview(flowGuid: string) { return get(`${ROOT}/apply/preview`, { flowGuid }); } } export const flowApi = new FlowApi();