| | |
| | | getApprovalModuleConfig, |
| | | getModuleMatchingBusinessTypes, |
| | | } from "./approvalModuleRegistry.js"; |
| | | import { parseApprovalFormConfig } from "./approvalFormField.js"; |
| | | import { |
| | | parseApprovalFormConfig, |
| | | parseDatetimerangeValue, |
| | | } from "./approvalFormField.js"; |
| | | import { matchBusinessTypeValue } from "./approvalTemplateType.js"; |
| | | |
| | | /** 与 Web leave-apply LEAVE_TYPE_OPTIONS 一致 */ |
| | |
| | | return payload; |
| | | } |
| | | |
| | | function guessFieldTypeFromValue(val) { |
| | | if (Array.isArray(val)) return "datetimerange"; |
| | | if (typeof val === "number") return "number"; |
| | | return "text"; |
| | | } |
| | | |
| | | /** 解析实例 formConfig / formPayload(与 Web resolveInstanceFormFields 对齐) */ |
| | | export function resolveInstanceFormPayload(row) { |
| | | const cfg = parseApprovalFormConfig(row?.formConfig); |
| | | const fields = (row?.formFieldDefs?.length ? row.formFieldDefs : cfg.fields) || []; |
| | | let fields = (row?.formFieldDefs?.length ? row.formFieldDefs : cfg.fields) || []; |
| | | const formPayload = { |
| | | ...(fields.length ? buildFormPayloadFromFields(fields) : {}), |
| | | ...cfg.formPayload, |
| | | ...(row?.formPayload || {}), |
| | | }; |
| | | if (!fields.length && Object.keys(formPayload).length) { |
| | | fields = Object.keys(formPayload) |
| | | .filter(k => k && k !== "summary") |
| | | .map(k => ({ |
| | | key: k, |
| | | label: k, |
| | | type: guessFieldTypeFromValue(formPayload[k]), |
| | | required: false, |
| | | options: [], |
| | | })); |
| | | } |
| | | fields = fields.map(field => ({ |
| | | ...field, |
| | | value: |
| | | formPayload[field.key] ?? field.value ?? field.defaultValue ?? "", |
| | | })); |
| | | return { fields, formPayload }; |
| | | } |
| | | |
| | | /** 已知下拉字段 value → 展示文案(模板未带 options 时兜底) */ |
| | | export function formatKnownSelectLabel(prop, val) { |
| | | if (val === undefined || val === null || val === "") return ""; |
| | | const maps = { |
| | | leaveType: LEAVE_TYPE_OPTIONS, |
| | | overtimeType: OVERTIME_TYPE_OPTIONS, |
| | | handoverStatus: HANDOVER_STATUS_OPTIONS, |
| | | handoverType: HANDOVER_TYPE_OPTIONS, |
| | | }; |
| | | const options = maps[prop]; |
| | | if (!options) return ""; |
| | | const hit = options.find(o => String(o.value) === String(val)); |
| | | return hit?.label || ""; |
| | | } |
| | | |
| | | export function getRowPayloadValue(row, keys) { |
| | |
| | | if (formPayload[k] != null && formPayload[k] !== "") return formPayload[k]; |
| | | } |
| | | return ""; |
| | | } |
| | | |
| | | const DATETIME_RANGE_KEYS = [ |
| | | "dateRange", |
| | | "leaveTime", |
| | | "overtimeTime", |
| | | "timeRange", |
| | | ]; |
| | | |
| | | function pickDatetimerangeRaw(formPayload, fields = []) { |
| | | for (const key of DATETIME_RANGE_KEYS) { |
| | | const v = formPayload?.[key]; |
| | | if (v != null && v !== "") return v; |
| | | const field = (fields || []).find(f => f?.key === key); |
| | | const fv = field?.value ?? field?.defaultValue; |
| | | if (fv != null && fv !== "") return fv; |
| | | } |
| | | const rangeField = (fields || []).find( |
| | | f => String(f?.type || "").toLowerCase() === "datetimerange" |
| | | ); |
| | | if (rangeField?.key) { |
| | | const v = |
| | | formPayload?.[rangeField.key] ?? rangeField.value ?? rangeField.defaultValue; |
| | | if (v != null && v !== "") return v; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | function splitRangeValue(val) { |
| | | if (val === undefined || val === null || val === "") { |
| | | return { start: "", end: "" }; |
| | | } |
| | | if (Array.isArray(val)) { |
| | | return { start: val[0] || "", end: val[1] || "" }; |
| | | } |
| | | return parseDatetimerangeValue(val); |
| | | } |
| | | |
| | | /** |
| | | * 列表列 prop 与 formPayload 对齐(请假 startTime/endTime 来自 dateRange) |
| | | */ |
| | | export function resolveListFieldRawValue(prop, row, fields = [], formPayload = {}) { |
| | | const payload = formPayload || {}; |
| | | const direct = payload[prop] ?? row?.[prop]; |
| | | |
| | | if (prop === "startTime" || prop === "endTime") { |
| | | if (direct != null && direct !== "") return direct; |
| | | const altStart = |
| | | payload.start ?? payload.startDate ?? payload.beginTime ?? row?.startTime; |
| | | const altEnd = |
| | | payload.end ?? payload.endDate ?? payload.finishTime ?? row?.endTime; |
| | | if (prop === "startTime" && altStart) return altStart; |
| | | if (prop === "endTime" && altEnd) return altEnd; |
| | | const { start, end } = splitRangeValue(pickDatetimerangeRaw(payload, fields)); |
| | | return prop === "startTime" ? start : end; |
| | | } |
| | | |
| | | if (prop === "overtimeDate") { |
| | | const d = payload.overtimeDate ?? payload.date ?? direct; |
| | | if (d != null && d !== "") return Array.isArray(d) ? d[0] || "" : d; |
| | | const { start } = splitRangeValue(pickDatetimerangeRaw(payload, fields)); |
| | | return start || ""; |
| | | } |
| | | |
| | | if (direct != null && direct !== "") return direct; |
| | | const hit = (fields || []).find(f => f?.key === prop); |
| | | return hit?.value ?? hit?.defaultValue ?? ""; |
| | | } |
| | | |
| | | function pickDateRange(searchForm) { |
| | |
| | | return { applicantKeyword: "", leaveType: "" }; |
| | | case APPROVAL_MODULE_KEYS.OVERTIME: |
| | | return { applicantKeyword: "", overtimeType: "" }; |
| | | case APPROVAL_MODULE_KEYS.TRAVEL_REIMBURSE: |
| | | case APPROVAL_MODULE_KEYS.COST_REIMBURSE: |
| | | case APPROVAL_MODULE_KEYS.ENTERPRISE_NEWS: |
| | | return { applicantKeyword: "" }; |
| | | default: |
| | | return {}; |
| | | } |
| | |
| | | matchApplicantKeyword(row, sf.applicantKeyword) && |
| | | matchSelectValue(row, ["overtimeType", "加班类型"], sf.overtimeType) |
| | | ); |
| | | case APPROVAL_MODULE_KEYS.TRAVEL_REIMBURSE: |
| | | case APPROVAL_MODULE_KEYS.COST_REIMBURSE: |
| | | case APPROVAL_MODULE_KEYS.ENTERPRISE_NEWS: |
| | | return list.filter(row => matchApplicantKeyword(row, sf.applicantKeyword)); |
| | | default: |
| | | return list; |
| | | } |
| | |
| | | }, |
| | | ], |
| | | }; |
| | | case APPROVAL_MODULE_KEYS.TRAVEL_REIMBURSE: |
| | | case APPROVAL_MODULE_KEYS.COST_REIMBURSE: |
| | | case APPROVAL_MODULE_KEYS.ENTERPRISE_NEWS: |
| | | return { |
| | | fields: [ |
| | | { |
| | | key: "applicantKeyword", |
| | | type: "input", |
| | | label: "申请人", |
| | | placeholder: "姓名或编号", |
| | | }, |
| | | ], |
| | | }; |
| | | default: |
| | | return { fields: [] }; |
| | | } |