import { get, postJ, putJ } from "@/utils/request"; import Vue from "vue"; // BPM 任务结果枚举(后端 bpm_task.result:1 通过 / 2 不通过 / 3 取消 / 4 退回) const TASK_RESULT_LABEL = { 1: "已同意", 2: "已驳回", 3: "已取消", 4: "已退回", }; // 兼容后端返回 { list } / { records } / 直接数组 三种分页结构 function asList(data) { if (Array.isArray(data)) return data; if (data && Array.isArray(data.list)) return data.list; if (data && Array.isArray(data.records)) return data.records; return []; } // 去掉空串 / null / undefined,避免后端把空值当成有效查询条件 function compact(object = {}) { return Object.keys(object).reduce((result, key) => { const value = object[key]; if (value !== "" && value !== null && value !== undefined) result[key] = value; return result; }, {}); } function normalizePage(res) { const data = res.data || {}; const list = asList(data); const total = Number( data.count !== undefined ? data.count : data.total !== undefined ? data.total : list.length ); return { list, total }; } /** * 待办任务分页 * POST /bpm/task/todo-page */ export async function getTodoTaskPage(params = {}, loding = true) { const res = await postJ( Vue.prototype.apiUrl + "/bpm/task/todo-page", compact({ pageNo: params.pageNo || 1, pageSize: params.pageSize || 20, name: params.name, processType: params.processType, }), loding ); if (res.code == 0) { return normalizePage(res); } return Promise.reject(new Error(res.message)); } /** * 已办任务分页 * POST /bpm/task/done-page */ export async function getDoneTaskPage(params = {}, loding = true) { const res = await postJ( Vue.prototype.apiUrl + "/bpm/task/done-page", compact({ pageNo: params.pageNo || 1, pageSize: params.pageSize || 20, name: params.name, result: params.result, keyword: params.keyword, startUserName: params.startUserName, }), loding ); if (res.code == 0) { return normalizePage(res); } return Promise.reject(new Error(res.message)); } /** * 抄送我的流程分页 * GET /bpm/process-instance/cc/my-page */ export async function getCcProcessPage(params = {}, loding = true) { const res = await get( Vue.prototype.apiUrl + "/bpm/process-instance/cc/my-page", compact({ pageNo: params.pageNo || 1, pageSize: params.pageSize || 20, processInstanceName: params.processInstanceName, }), loding ); if (res.code == 0) { return normalizePage(res); } return Promise.reject(new Error(res.message)); } /** * 流程实例详情 * GET /bpm/process-instance/get?id= */ export async function getProcessInstance(id, loding = true) { if (!id) return null; const res = await get( Vue.prototype.apiUrl + `/bpm/process-instance/get?id=${encodeURIComponent(String(id))}`, {}, loding ); if (res.code == 0) { return res.data || null; } return Promise.reject(new Error(res.message)); } /** * 流程实例下的全部任务(审批记录) * GET /bpm/task/list-by-process-instance-id */ export async function getTaskListByProcessInstanceId(processInstanceId, loding = true) { if (!processInstanceId) return []; const res = await get( Vue.prototype.apiUrl + `/bpm/task/list-by-process-instance-id?processInstanceId=${encodeURIComponent(String(processInstanceId))}`, {}, loding ); if (res.code == 0) { return asList(res.data); } return Promise.reject(new Error(res.message)); } /** * 审批通过 * PUT /bpm/task/approve */ export async function approveTask({ id, reason = "" } = {}) { if (!id) throw new Error("缺少任务主键"); const res = await putJ( Vue.prototype.apiUrl + "/bpm/task/approve", compact({ id, reason }), true ); if (res.code == 0) { return res.data; } return Promise.reject(new Error(res.message)); } /** * 审批驳回(原因必填) * PUT /bpm/task/reject */ export async function rejectTask({ id, reason } = {}) { if (!id) throw new Error("缺少任务主键"); const res = await putJ( Vue.prototype.apiUrl + "/bpm/task/reject", compact({ id, reason }), true ); if (res.code == 0) { return res.data; } return Promise.reject(new Error(res.message)); } /** * 归一化 BPM 任务,兼容不同字段命名 */ export function adaptBpmTask(vo = {}) { const instance = vo.processInstance || {}; const resultCode = Number(vo.result); return { taskId: vo.id, processInstanceId: instance.id || vo.processInstanceId || "", processName: instance.name || "", startUserId: instance.startUserId, businessId: vo.businessId || "", businessCode: vo.businessCode || "", businessName: vo.businessName || "", businessType: vo.businessType || "", applicant: instance.startUserNickname || "", department: "", position: "", name: vo.name || "", viewRouter: vo.miniViewRouter || vo.pcViewRouter || "", handleRouter: vo.miniHandleRouter || vo.pcHandleRouter || "", reason: vo.reason || "", createTime: vo.createTime || "", handledAt: vo.endTime || vo.updateTime || "", resultLabel: TASK_RESULT_LABEL[resultCode] || "", raw: vo, }; } /** * 我的流程实例分页(我发起的申请) * POST /bpm/process-instance/my-page * 入参:pageNo/pageSize + keyword/status/result/createTimeBegin/createTimeEnd(均为可选) */ export async function getMyProcessInstancePage(params = {}, loding = true) { const res = await postJ( Vue.prototype.apiUrl + "/bpm/process-instance/my-page", compact({ pageNo: params.pageNo || 1, pageSize: params.pageSize || 50, keyword: params.keyword, status: params.status, result: params.result, createTimeBegin: params.createTimeBegin, createTimeEnd: params.createTimeEnd, }), loding ); if (res.code == 0) { return normalizePage(res); } return Promise.reject(new Error(res.message || "查询我的申请失败")); } // 流程实例结果枚举(BpmProcessInstanceResultEnum) const INSTANCE_RESULT_LABEL = { 1: "审批中", // 处理中 2: "已通过", 3: "已驳回", // 不通过 4: "已取消", 5: "已驳回", // 驳回(退回发起人) 6: "审批中", // 委派 7: "审批中", // 待后加签 8: "审批中", // 待前加签 9: "审批中", // 待前置任务完成 10: "已通过", // 任务被其他人审批完成 }; // 已知业务类型码 → 中文名(后端 businessType 为英文码;未识别的码原样透出) const BUSINESS_TYPE_LABELS = { ATTENDANCE_LEAVE: "请假申请", ATTENDANCE_OVERTIME: "加班申请", ATTENDANCE_TRIP: "出差申请", ATTENDANCE_OUTING: "外勤申请", ATTENDANCE_CARD_REPAIR: "补卡申请", RESIGNATION: "离职申请", PROFILE_CHANGE: "资料变更", }; /** * 归一化「我发起的流程实例」为列表条目。 * status:1 进行中 / 2 已完成 / 3 已取消(BpmProcessInstanceStatusEnum) */ export function adaptMyProcess(vo = {}) { const statusCode = Number(vo.status); const resultCode = Number(vo.result); let statusLabel; if (statusCode === 1) statusLabel = "审批中"; else if (statusCode === 3) statusLabel = "已取消"; else statusLabel = INSTANCE_RESULT_LABEL[resultCode] || "已完成"; const title = vo.businessName || vo.name || ""; const code = vo.businessCode || vo.processInstanceNo || ""; const type = BUSINESS_TYPE_LABELS[vo.businessType] || vo.formName || vo.categoryName || vo.name || "流程申请"; return { id: vo.id, processInstanceId: vo.id, processNo: vo.processInstanceNo || "", type, title, summary: [title, code].filter(Boolean).join(" · ") || "—", businessId: vo.businessId || "", businessCode: code, createdAt: formatInstanceTime(vo.createTime), endTime: formatInstanceTime(vo.endTime), statusLabel, viewRouter: vo.pcViewRouter || "", raw: vo, }; } function formatInstanceTime(value) { if (!value) return ""; // 兼容 "2026-10-12 09:30:00" / ISO / 时间戳 if (typeof value === "number") { const d = new Date(value); return isNaN(d.getTime()) ? "" : formatDateTimeLocal(d); } return String(value).replace("T", " ").slice(0, 16); } function formatDateTimeLocal(d) { const pad = (n) => String(n).padStart(2, "0"); return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`; } /** * 抄送流程 VO → 列表条目(抄送只读,不参与审批操作) */ export function adaptCcProcess(vo = {}) { return { id: vo.id, processInstanceId: vo.processInstanceId || "", processName: vo.processInstanceName || "", applicant: vo.startUserNickname || "", creatorName: vo.creatorNickname || "", reason: vo.reason || "", taskName: vo.taskName || "", createTime: vo.createTime || "", raw: vo, }; }