yyb
10 小时以前 97081b89ee45da49b8dbb4173ab45df031fe3c0d
src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js
@@ -8,6 +8,10 @@
  nodeSignModeLabel,
} from "../approve-template/approveTemplateConstants.js";
import { buildFormPayloadFromFields, parseFormConfigToData } from "../approve-template/formConfigUtils.js";
import {
  isDynamicOptionSource,
  resolveSelectDisplayLabel,
} from "../approve-template/selectOptionSource.js";
/** 审批类型(与后端字段 approvalType 对齐,后期可同步) */
export const APPROVAL_TYPE_OPTIONS = [
@@ -24,24 +28,46 @@
  { value: "procurement", label: "采购审批", cellBg: "#f4f4f5", cellColor: "#909399" },
  { value: "quotation", label: "报价审批", cellBg: "#f4ecfc", cellColor: "#9b59b6" },
  { value: "shipment", label: "发货审批", cellBg: "#e8faf6", cellColor: "#1abc9c" },
  { value: "enterprise_news", label: "企业新闻", cellBg: "#ecf5ff", cellColor: "#409eff" },
];
/** 审批状态 approvalStatus */
/** 列表查询:审批状态(与后端 status 枚举一致) */
export const APPROVAL_STATUS_SEARCH_OPTIONS = [
  { value: "PENDING", label: "待审批" },
  { value: "APPROVED", label: "已通过" },
  { value: "REJECTED", label: "已驳回" },
];
/**
 * 审批状态展示(与后端 status 枚举一致)
 * PENDING → 待审批/进行中  APPROVED → 已通过/已完成  REJECTED → 已驳回
 */
export const APPROVAL_STATUS_OPTIONS = [
  { value: "pending", label: "审核中" },
  { value: "approved", label: "已通过" },
  { value: "rejected", label: "已驳回" },
  { value: "cancelled", label: "已撤销" },
  { value: "pending", api: "PENDING", label: "待审批" },
  { value: "approved", api: "APPROVED", label: "已通过" },
  { value: "rejected", api: "REJECTED", label: "已驳回" },
  { value: "cancelled", api: "CANCELLED", label: "已撤销" },
];
export const LEGACY_APPROVE_LIST_STORAGE_KEY = "oa_unified_approve_list_v1";
export function clearLegacyApproveListStorage() {
  try {
    localStorage.removeItem(LEGACY_APPROVE_LIST_STORAGE_KEY);
  } catch {
    /* ignore */
/** 后端 status / 页面 approvalStatus → 统一页面 key(pending | approved | rejected | cancelled) */
export function normalizeApprovalStatusKey(v) {
  const s = String(v ?? "").trim();
  if (!s) return "pending";
  const upper = s.toUpperCase();
  if (upper === "APPROVED" || upper === "APPROVE" || upper === "PASS") return "approved";
  if (upper === "REJECTED" || upper === "REJECT" || upper === "REFUSE") return "rejected";
  if (upper === "CANCELLED" || upper === "CANCEL") return "cancelled";
  if (
    upper === "PENDING" ||
    upper === "IN_PROGRESS" ||
    upper === "PROCESSING" ||
    upper === "RUNNING"
  ) {
    return "pending";
  }
  const lower = s.toLowerCase();
  if (["pending", "approved", "rejected", "cancelled"].includes(lower)) return lower;
  return "pending";
}
/** 提交弹窗:模板卡片(来自后端列表) */
@@ -50,10 +76,16 @@
  return {
    id: row?.id,
    key: String(row?.id ?? ""),
    businessType: row?.businessType ?? cfg.approvalType ?? row?.approvalType ?? "",
    approvalType: cfg.approvalType || row?.approvalType || "",
    label: row?.templateName || "—",
    summaryPlaceholder: (row?.description || "").trim() || cfg.summaryPlaceholder || "点击填写并提交",
  };
}
export function matchBusinessTypeValue(a, b) {
  if (a == null || a === "" || b == null || b === "") return false;
  return a === b || a === Number(b) || Number(a) === b || String(a) === String(b);
}
/** 审批记录 approveAction → 页面 result */
@@ -78,20 +110,11 @@
}
export function mapTaskStatusLabel(status) {
  const s = String(status || "").toUpperCase();
  if (s === "APPROVED") return "已通过";
  if (s === "REJECTED") return "已驳回";
  if (s === "PENDING") return "待审批";
  if (s === "CANCELLED") return "已撤销";
  return status || "—";
  return approvalStatusLabel(status);
}
export function mapTaskStatusTagType(status) {
  const s = String(status || "").toUpperCase();
  if (s === "APPROVED") return "success";
  if (s === "REJECTED") return "danger";
  if (s === "CANCELLED") return "info";
  return "warning";
  return approvalStatusTagType(status);
}
/** 后端 tasks → 页面 flowNodes(按 levelNo 分组,供流程编辑/展示) */
@@ -167,9 +190,17 @@
  return "text";
}
/** 单字段展示值(详情只读) */
export function formatFieldDisplayValue(field, val) {
/**
 * 单字段展示值(详情只读、列表主表)
 * @param {object} [caches] 人员/部门下拉缓存,用于解析「人员列表」类字段为姓名
 */
export function formatFieldDisplayValue(field, val, caches) {
  if (val == null || val === "" || (Array.isArray(val) && !val.length)) return "—";
  if (field?.type === "select" && isDynamicOptionSource(field.optionSource)) {
    const label = resolveSelectDisplayLabel(field, val, caches || {});
    if (label && label !== "—") return label;
    return String(val);
  }
  if (field?.type === "select" && field.options?.length) {
    const hit = field.options.find((o) => String(o.value) === String(val));
    return hit?.label || String(val);
@@ -275,10 +306,17 @@
  const dto = {
    templateId,
    templateName: submitForm?.templateName || tpl.label || "",
    businessType: tpl.businessType ?? submitForm?.businessType ?? "",
    title,
    formConfig: buildInstanceFormConfigJson({ ...tpl, fields: tpl.fields || submitForm?.formFieldDefs }, payload),
    tasks: taskList,
  };
  const attachments =
    (Array.isArray(submitForm?.storageBlobDTOs) && submitForm.storageBlobDTOs.length
      ? submitForm.storageBlobDTOs
      : null) || tpl.storageBlobDTOs;
  if (attachments?.length) dto.storageBlobDTOs = attachments;
  if (isUpdate) {
    dto.id = existingRow?.id ?? submitForm?.instanceId;
@@ -297,11 +335,6 @@
  return dto;
}
/** @deprecated 使用 buildInstanceDto */
export function buildSaveInstanceDto(params) {
  return buildInstanceDto(params);
}
/** 校验提交审批流程(与模板页规则一致) */
export function validateSubmitFlowNodes(flowNodes) {
  const nodes = normalizeFlowNodes(flowNodes);
@@ -316,20 +349,14 @@
/** 后端 status → 页面 approvalStatus */
export function mapInstanceStatusFromApi(status) {
  const s = String(status || "").toUpperCase();
  if (s === "APPROVED") return "approved";
  if (s === "REJECTED") return "rejected";
  if (s === "CANCELLED") return "cancelled";
  return "pending";
  return normalizeApprovalStatusKey(status);
}
/** 页面 approvalStatus → 后端 status */
export function mapInstanceStatusToApi(approvalStatus) {
  const s = String(approvalStatus || "").toLowerCase();
  if (s === "approved") return "APPROVED";
  if (s === "rejected") return "REJECTED";
  if (s === "cancelled") return "CANCELLED";
  return "PENDING";
  const key = normalizeApprovalStatusKey(approvalStatus);
  const hit = APPROVAL_STATUS_OPTIONS.find((x) => x.value === key);
  return hit?.api || "PENDING";
}
export function unwrapInstancePage(res) {
@@ -362,6 +389,7 @@
    templateName: row.templateName || "",
    businessId: row.businessId,
    businessType: row.businessType,
    businessName: row.businessName || "",
    applicantId: row.applicantId,
    applicantNo: row.applicantId != null ? String(row.applicantId) : "",
    applicantName: row.applicantName || "",
@@ -410,19 +438,26 @@
  };
}
export function buildApprovalInstanceListParams({ page, searchForm }) {
export function buildApprovalInstanceListParams({ page, searchForm, businessType, extraParams }) {
  const params = {
    current: page.current,
    size: page.size,
    ...(extraParams && typeof extraParams === "object" ? extraParams : {}),
  };
  const dto = {};
  const kw = (searchForm?.applicantKeyword || "").trim();
  if (kw) dto.applicantName = kw;
  if (searchForm?.approvalType) {
    const opt = APPROVAL_TYPE_OPTIONS.find((x) => x.value === searchForm.approvalType);
    if (opt?.label) dto.templateName = opt.label;
  const bizType = businessType ?? searchForm?.businessType;
  if (bizType != null && bizType !== "") {
    params.businessType = bizType;
  }
  if (Object.keys(dto).length) params.approvalInstanceDto = dto;
  if (searchForm?.status) {
    params.status = searchForm.status;
  }
  const range = searchForm?.createTimeRange;
  if (Array.isArray(range) && range[0]) {
    params.createTime = range[0];
  }
  if (Array.isArray(range) && range[1]) {
    params.createTimeEnd = range[1];
  }
  return params;
}
@@ -441,18 +476,45 @@
}
export function approvalStatusLabel(v) {
  return APPROVAL_STATUS_OPTIONS.find((x) => x.value === v)?.label || "—";
  const key = normalizeApprovalStatusKey(v);
  return APPROVAL_STATUS_OPTIONS.find((x) => x.value === key)?.label || "—";
}
/** 业务申请页状态文案:PENDING→进行中 APPROVED→已完成 REJECTED→已驳回 */
export function businessApprovalStatusLabel(v) {
  const key = normalizeApprovalStatusKey(v);
  if (key === "pending") return "进行中";
  if (key === "approved") return "已完成";
  if (key === "rejected") return "已驳回";
  if (key === "cancelled") return "已撤销";
  return "—";
}
/**
 * 业务申请页是否允许修改(五个申请页)
 * 进行中(PENDING)、已完成(APPROVED) 不可修改;已驳回、已撤销等可修改
 */
export function canEditBusinessInstanceRow(row) {
  const key = normalizeApprovalStatusKey(
    row?.approvalStatus ?? row?.statusRaw ?? row?.status
  );
  return key !== "pending" && key !== "approved";
}
export function businessApprovalStatusTagType(v) {
  const key = normalizeApprovalStatusKey(v);
  if (key === "approved") return "success";
  if (key === "rejected") return "danger";
  if (key === "cancelled") return "info";
  return "warning";
}
export function approvalStatusTagType(v) {
  if (v === "approved") return "success";
  if (v === "rejected") return "danger";
  if (v === "cancelled") return "info";
  return "primary";
}
export function unreadLabel(v) {
  return v ? "是" : "否";
  const key = normalizeApprovalStatusKey(v);
  if (key === "approved") return "success";
  if (key === "rejected") return "danger";
  if (key === "cancelled") return "info";
  return "warning";
}
/** 列表行 → 编辑表单(仅用行数据回显) */
@@ -479,6 +541,10 @@
    formFieldDefs: fields,
    formPayload,
    flowNodes,
    templateAttachments: initTemplateAttachmentsFromSnapshot(templateSnapshot),
    storageBlobDTOs: row?.storageBlobDTOs?.length
      ? JSON.parse(JSON.stringify(row.storageBlobDTOs))
      : [],
  };
}
@@ -503,5 +569,14 @@
    formFieldDefs: tpl?.fields || [],
    formPayload: payload,
    flowNodes,
    templateAttachments: tpl?.storageBlobDTOs
      ? JSON.parse(JSON.stringify(tpl.storageBlobDTOs))
      : [],
    storageBlobDTOs: [],
  };
}
export function initTemplateAttachmentsFromSnapshot(templateSnapshot) {
  const list = templateSnapshot?.storageBlobDTOs;
  return list?.length ? JSON.parse(JSON.stringify(list)) : [];
}