| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import { parseTime } from "@/utils/ruoyi"; |
| | | import { |
| | | mapApprovalRecords, |
| | | mapRecordResult, |
| | | mapTasksToFlowNodes, |
| | | } from "../../_utils/approveListUtils.js"; |
| | | |
| | | function formatDisplayTime(val) { |
| | | if (!val) return ""; |
| | | const s = parseTime(val, "{y}-{m}-{d} {h}:{i}"); |
| | | return s || String(val).replace("T", " ").slice(0, 16); |
| | | } |
| | | |
| | | function taskStatusToNodeStatus(taskStatus) { |
| | | const s = String(taskStatus ?? "").toUpperCase(); |
| | | if (["APPROVED", "COMPLETED", "FINISHED", "PASSED", "AGREE"].includes(s)) { |
| | | return "finish"; |
| | | } |
| | | if (["REJECTED", "REJECT", "REFUSE", "REFUSED"].includes(s)) { |
| | | return "error"; |
| | | } |
| | | if (["PENDING", "IN_APPROVAL", "PROCESS", "PROCESSING"].includes(s)) { |
| | | return "process"; |
| | | } |
| | | return "wait"; |
| | | } |
| | | |
| | | /** storageBlobVOList â 页é¢éä»¶ */ |
| | | export function mapReimbursementAttachments(source = {}) { |
| | | const list = |
| | | source.storageBlobVOList || |
| | | source.storageBlobDTOs || |
| | | source.storageBlobDTOS || |
| | | source.attachmentList || |
| | | source.invoiceAttachments || |
| | | []; |
| | | if (!Array.isArray(list)) return []; |
| | | return list.map((b, i) => ({ |
| | | ...b, |
| | | id: b.id ?? b.blobId ?? `att_${i}`, |
| | | name: |
| | | b.fileName || |
| | | b.originalFilename || |
| | | b.originalFileName || |
| | | b.blobName || |
| | | b.name || |
| | | "éä»¶", |
| | | url: |
| | | b.url || |
| | | b.fileUrl || |
| | | b.downloadUrl || |
| | | b.downloadURL || |
| | | b.previewUrl || |
| | | b.previewURL || |
| | | b.link || |
| | | "", |
| | | })); |
| | | } |
| | | |
| | | /** 审æ¹è®°å½å¨ tasks */ |
| | | export function mapTasksToApprovalRecords(tasks) { |
| | | const list = Array.isArray(tasks) ? tasks : []; |
| | | return list |
| | | .map((t, index) => ({ |
| | | id: t.id ?? index, |
| | | operatorName: t.approverName || t.operatorName || t.createUserName || "â", |
| | | result: mapRecordResult(t.approveAction ?? t.taskStatus ?? t.status), |
| | | opinion: t.approveComment || t.comment || t.opinion || "", |
| | | time: formatDisplayTime( |
| | | t.approveTime || t.finishTime || t.updateTime || t.createTime || "" |
| | | ), |
| | | levelNo: t.levelNo ?? t.taskLevel, |
| | | })) |
| | | .sort((a, b) => { |
| | | const la = Number(a.levelNo ?? 0); |
| | | const lb = Number(b.levelNo ?? 0); |
| | | if (la !== lb) return la - lb; |
| | | return String(a.time).localeCompare(String(b.time)); |
| | | }); |
| | | } |
| | | |
| | | export function mapTasksToApprovalFlowNodes(tasks) { |
| | | const grouped = mapTasksToFlowNodes(tasks); |
| | | return grouped.map((node, i) => { |
| | | const approvers = node.approvers || []; |
| | | const statuses = approvers.map(a => |
| | | taskStatusToNodeStatus(a.taskStatus ?? a.status) |
| | | ); |
| | | let nodeStatus = "wait"; |
| | | if (statuses.includes("error")) nodeStatus = "error"; |
| | | else if (statuses.length && statuses.every(s => s === "finish")) { |
| | | nodeStatus = "finish"; |
| | | } else if (statuses.includes("process")) nodeStatus = "process"; |
| | | |
| | | const names = approvers.map(a => a.approverName).filter(Boolean).join("ã"); |
| | | const opinions = approvers |
| | | .map(a => a.approveComment) |
| | | .filter(Boolean) |
| | | .join("ï¼"); |
| | | |
| | | return { |
| | | nodeOrder: node.levelNo ?? i + 1, |
| | | levelNo: node.levelNo ?? i + 1, |
| | | approveType: node.approveType || "AND", |
| | | approveTypeLabel: node.approveType === "OR" ? "æç¾" : "ä¼ç¾", |
| | | approvers, |
| | | approverName: names || "â", |
| | | approveOpinion: opinions, |
| | | nodeStatus, |
| | | }; |
| | | }); |
| | | } |
| | | |
| | | export function computeApprovalFlowCurrentIndex(approvalFlowNodes = []) { |
| | | const list = approvalFlowNodes || []; |
| | | const processing = list.findIndex(n => n.nodeStatus === "process"); |
| | | if (processing >= 0) return processing; |
| | | const errorIdx = list.findIndex(n => n.nodeStatus === "error"); |
| | | if (errorIdx >= 0) return errorIdx; |
| | | return list.filter(n => n.nodeStatus === "finish").length; |
| | | } |
| | | |
| | | export function applyFinReimbursementDetailEnrichment(mapped, raw = {}) { |
| | | if (!mapped || typeof mapped !== "object") return mapped; |
| | | const source = { ...raw, ...mapped }; |
| | | const tasks = Array.isArray(source.tasks) ? source.tasks : []; |
| | | const attachments = mapReimbursementAttachments(source); |
| | | const approvalRecords = tasks.length |
| | | ? mapTasksToApprovalRecords(tasks) |
| | | : mapApprovalRecords(source.records || source.approvalRecords); |
| | | const approvalFlowNodes = Array.isArray(mapped.approvalFlowNodes) |
| | | ? mapped.approvalFlowNodes |
| | | : []; |
| | | const approvalFlowProgressNodes = tasks.length |
| | | ? mapTasksToApprovalFlowNodes(tasks) |
| | | : approvalFlowNodes; |
| | | const flowNodes = tasks.length |
| | | ? mapTasksToFlowNodes(tasks) |
| | | : mapped.flowNodes || mapped.nodes || []; |
| | | |
| | | return { |
| | | ...mapped, |
| | | tasks, |
| | | storageBlobVOList: attachments, |
| | | attachmentList: attachments, |
| | | invoiceAttachments: attachments, |
| | | approvalRecords, |
| | | approvalFlowNodes, |
| | | approvalFlowProgressNodes, |
| | | currentNodeIndex: computeApprovalFlowCurrentIndex( |
| | | approvalFlowProgressNodes.length ? approvalFlowProgressNodes : approvalFlowNodes |
| | | ), |
| | | rejectReason: |
| | | approvalRecords.find(r => r.result === "rejected")?.opinion || |
| | | source.rejectReason || |
| | | "", |
| | | flowNodes, |
| | | }; |
| | | } |