| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import { formatDisplayTime } from "../../ApproveManage/approve-template/approveTemplateConstants.js"; |
| | | import { |
| | | mapRecordResultFromApi, |
| | | mapRecordsFromApi, |
| | | mapTasksToFlowNodes, |
| | | } from "../../ApproveManage/approve-list/approveListConstants.js"; |
| | | |
| | | 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.storageBlobVOS || |
| | | 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: mapRecordResultFromApi( |
| | | 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, |
| | | raw: t, |
| | | })) |
| | | .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)); |
| | | }); |
| | | } |
| | | |
| | | /** tasks â ApprovalFlowProgress èç¹ */ |
| | | 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.nodeOrder ?? node.levelNo ?? i + 1, |
| | | sortOrder: node.nodeOrder ?? node.levelNo ?? i + 1, |
| | | approverName: names || "â", |
| | | approveOpinion: opinions, |
| | | approveTime: approvers.find(a => a.approveTime)?.approveTime || "", |
| | | nodeStatus, |
| | | signMode: node.signMode, |
| | | }; |
| | | }); |
| | | } |
| | | |
| | | 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; |
| | | } |
| | | |
| | | /** 详æ
DTO è¡¥å
tasks / éä»¶ / 审æ¹è®°å½ */ |
| | | 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) |
| | | : mapRecordsFromApi(source.records || source.approvalRecords); |
| | | /** 表åç¼è¾åæ¾ï¼ä¿ç nodes æ å°ï¼å« approverIdï¼ï¼å¿ç¨ tasks è¦ç */ |
| | | const approvalFlowNodes = Array.isArray(mapped.approvalFlowNodes) |
| | | ? mapped.approvalFlowNodes |
| | | : []; |
| | | /** 详æ
/è¿åº¦æ¡å±ç¤ºï¼æ tasks æ¶ç¨ä»»å¡ç¶æèç¹ */ |
| | | const approvalFlowProgressNodes = tasks.length |
| | | ? mapTasksToApprovalFlowNodes(tasks) |
| | | : approvalFlowNodes; |
| | | const currentNodeIndex = computeApprovalFlowCurrentIndex( |
| | | approvalFlowProgressNodes.length ? approvalFlowProgressNodes : approvalFlowNodes |
| | | ); |
| | | const rejectReason = |
| | | approvalRecords.find(r => r.result === "rejected")?.opinion || |
| | | source.rejectReason || |
| | | ""; |
| | | |
| | | return { |
| | | ...mapped, |
| | | tasks, |
| | | storageBlobVOList: attachments, |
| | | attachmentList: attachments, |
| | | invoiceAttachments: attachments, |
| | | approvalRecords, |
| | | records: tasks.length ? tasks : source.records, |
| | | approvalFlowNodes, |
| | | approvalFlowProgressNodes, |
| | | currentNodeIndex, |
| | | rejectReason, |
| | | flowNodes: tasks.length ? mapTasksToFlowNodes(tasks) : mapped.flowNodes, |
| | | }; |
| | | } |