gaoluyang
2026-06-16 2f58128ac3b1c025a32f64016328992bf9bf5b48
src/pages/oa/ReimburseManage/_utils/finReimbursementDetailExtras.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,159 @@
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,
  };
}