| | |
| | | nodeSignModeLabel, |
| | | } from "../approve-template/approveTemplateConstants.js"; |
| | | import { buildFormPayloadFromFields, parseFormConfigToData } from "../approve-template/formConfigUtils.js"; |
| | | import { isDynamicOptionSource, selectOptionSourceLabel } from "../approve-template/selectOptionSource.js"; |
| | | import { |
| | | isDynamicOptionSource, |
| | | resolveSelectDisplayLabel, |
| | | } from "../approve-template/selectOptionSource.js"; |
| | | |
| | | /** 审批类型(与后端字段 approvalType 对齐,后期可同步) */ |
| | | export const APPROVAL_TYPE_OPTIONS = [ |
| | |
| | | { 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"; |
| | | } |
| | | |
| | | /** 提交弹窗:模板卡片(来自后端列表) */ |
| | |
| | | } |
| | | |
| | | 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 分组,供流程编辑/展示) */ |
| | |
| | | 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)) { |
| | | return `${selectOptionSourceLabel(field.optionSource)}:${String(val)}`; |
| | | 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 dto; |
| | | } |
| | | |
| | | /** @deprecated 使用 buildInstanceDto */ |
| | | export function buildSaveInstanceDto(params) { |
| | | return buildInstanceDto(params); |
| | | } |
| | | |
| | | /** 校验提交审批流程(与模板页规则一致) */ |
| | | export function validateSubmitFlowNodes(flowNodes) { |
| | | const nodes = normalizeFlowNodes(flowNodes); |
| | |
| | | |
| | | /** 后端 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) { |
| | |
| | | }; |
| | | } |
| | | |
| | | 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; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | 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"; |
| | | } |
| | | |
| | | /** 列表行 → 编辑表单(仅用行数据回显) */ |