From a9d97b150701e634bdb751eab277696abd136cca Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 16 六月 2026 14:39:47 +0800
Subject: [PATCH] 君歌app 1.依照web端功能修改
---
src/pages/oa/_utils/approvalModuleApplyExtras.js | 293 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 293 insertions(+), 0 deletions(-)
diff --git a/src/pages/oa/_utils/approvalModuleApplyExtras.js b/src/pages/oa/_utils/approvalModuleApplyExtras.js
new file mode 100644
index 0000000..820d584
--- /dev/null
+++ b/src/pages/oa/_utils/approvalModuleApplyExtras.js
@@ -0,0 +1,293 @@
+import dayjs from "dayjs";
+import {
+ APPROVAL_MODULE_KEYS,
+ APPROVAL_MODULE_REGISTRY,
+ getModuleMatchingBusinessTypes,
+} from "./approvalModuleRegistry.js";
+import { matchBusinessTypeValue } from "./approvalTemplateType.js";
+import { parseDatetimerangeValue } from "./approvalFormField.js";
+
+/** 浜哄憳涓嬫媺瀛楁璇嗗埆锛堜笌 Web SELECT_OPTION_SOURCE.USER 绛変环锛� */
+export function isUserSelectField(field) {
+ const src = String(field?.optionSource ?? "").toLowerCase();
+ return (
+ src === "user" ||
+ src === "personnel" ||
+ src === "userlist" ||
+ (field?.type === "select" && String(field?.label || "").includes("鐢宠浜�"))
+ );
+}
+
+export function findApplicantTemplateField(fields = []) {
+ return (
+ fields.find(f => String(f?.label || "").includes("鐢宠浜�")) ||
+ fields.find(f => isUserSelectField(f)) ||
+ null
+ );
+}
+
+/* ---------- 璇峰亣 ---------- */
+
+export function isLeaveBalanceField(field) {
+ const label = String(field?.label || "");
+ return label.includes("鍋囨湡浣欓") || field?.key === "leaveBalanceDays";
+}
+
+export function isLeaveDurationField(field) {
+ const label = String(field?.label || "");
+ return label.includes("璇峰亣鏃堕暱") || field?.key === "leaveDurationDays";
+}
+
+export function displayLeaveTemplateFields(fields = []) {
+ return (fields || []).filter(
+ f => !isLeaveBalanceField(f) && !isLeaveDurationField(f)
+ );
+}
+
+export function findLeaveTimeTemplateField(fields = []) {
+ return (
+ fields.find(
+ f => f?.type === "datetimerange" && String(f?.label || "").includes("璇峰亣鏃堕棿")
+ ) ||
+ fields.find(f => f?.type === "datetimerange" && f?.key === "dateRange") ||
+ fields.find(f => f?.type === "datetimerange") ||
+ null
+ );
+}
+
+export function resolveTimeRangeFromPayload(payload, timeField) {
+ if (!timeField?.key) return { start: "", end: "" };
+ const val = payload?.[timeField.key];
+ if (Array.isArray(val) && val.length >= 2) {
+ return { start: val[0] || "", end: val[1] || "" };
+ }
+ return parseDatetimerangeValue(val);
+}
+
+export function computeLeaveDays(startStr, endStr) {
+ if (!startStr || !endStr) return null;
+ const t0 = dayjs(startStr);
+ const t1 = dayjs(endStr);
+ if (!t0.isValid() || !t1.isValid() || !t1.isAfter(t0)) return null;
+ const days = t1.diff(t0, "millisecond") / (24 * 60 * 60 * 1000);
+ return Math.round(days * 100) / 100;
+}
+
+export function computeLeaveDurationDisplay(fields, formPayload) {
+ const timeField = findLeaveTimeTemplateField(fields);
+ const { start, end } = resolveTimeRangeFromPayload(formPayload, timeField);
+ const d = computeLeaveDays(start, end);
+ return d == null ? "" : String(d);
+}
+
+export function validateLeaveBeforeSubmit(fields, formPayload) {
+ const timeField = findLeaveTimeTemplateField(fields);
+ const { start, end } = resolveTimeRangeFromPayload(formPayload, timeField);
+ if (computeLeaveDays(start, end) == null) {
+ return "璇锋鏌ユā鏉夸腑鐨勮鍋囨椂闂达紝缁撴潫鏃堕棿椤绘櫄浜庡紑濮嬫椂闂�";
+ }
+ return "";
+}
+
+/* ---------- 鍔犵彮 ---------- */
+
+export function isOvertimeDurationField(field) {
+ const label = String(field?.label || "");
+ return label.includes("鍔犵彮鏃堕暱") || field?.key === "overtimeHours";
+}
+
+export function displayOvertimeTemplateFields(fields = []) {
+ return (fields || []).filter(f => !isOvertimeDurationField(f));
+}
+
+export function findOvertimeTimeTemplateField(fields = []) {
+ return (
+ fields.find(
+ f => f?.type === "datetimerange" && String(f?.label || "").includes("鍔犵彮鏃堕棿")
+ ) ||
+ fields.find(f => f?.type === "datetimerange") ||
+ null
+ );
+}
+
+export function computeOvertimeHours(startStr, endStr) {
+ if (!startStr || !endStr) return null;
+ const t0 = dayjs(startStr);
+ const t1 = dayjs(endStr);
+ if (!t0.isValid() || !t1.isValid() || !t1.isAfter(t0)) return null;
+ return Math.round((t1.diff(t0, "millisecond") / 3600000) * 100) / 100;
+}
+
+export function computeOvertimeHoursDisplay(fields, formPayload) {
+ const field = findOvertimeTimeTemplateField(fields);
+ const { start, end } = resolveTimeRangeFromPayload(formPayload, field);
+ const h = computeOvertimeHours(start, end);
+ return h == null ? "" : String(h);
+}
+
+export function validateOvertimeBeforeSubmit(fields, formPayload) {
+ const field = findOvertimeTimeTemplateField(fields);
+ const { start, end } = resolveTimeRangeFromPayload(formPayload, field);
+ if (computeOvertimeHours(start, end) == null) {
+ return "璇锋鏌ユā鏉夸腑鐨勫姞鐝椂闂达紝缁撴潫鏃堕棿椤绘櫄浜庡紑濮嬫椂闂�";
+ }
+ return "";
+}
+
+/* ---------- 璋冨矖 ---------- */
+
+export function isOriginalPostField(field) {
+ const label = String(field?.label || "");
+ return (
+ label.includes("鍘熷矖浣�") ||
+ field?.key === "originalPost" ||
+ field?.key === "originalPostName" ||
+ field?.key === "originalPostId"
+ );
+}
+
+export function displayTransferTemplateFields(fields = []) {
+ return (fields || []).filter(f => !isOriginalPostField(f));
+}
+
+export function unwrapUserArray(payload) {
+ if (Array.isArray(payload)) return payload;
+ if (payload?.data && Array.isArray(payload.data)) return payload.data;
+ if (payload?.rows && Array.isArray(payload.rows)) return payload.rows;
+ return [];
+}
+
+export function isActiveUser(u) {
+ if (u?.delFlag === "2" || u?.delFlag === 2) return false;
+ if (u?.status == null) return true;
+ return String(u.status) === "0";
+}
+
+export function firstPostId(user) {
+ if (!user) return undefined;
+ if (Array.isArray(user.postIds) && user.postIds.length) return user.postIds[0];
+ if (user.postId != null && user.postId !== "") return user.postId;
+ return undefined;
+}
+
+export function buildPostIdToNameMap(postRows = []) {
+ const m = {};
+ for (const p of postRows) {
+ const id = p.postId ?? p.value ?? p.id;
+ if (id != null && id !== "") {
+ m[String(id)] = p.postName ?? p.label ?? p.name ?? "";
+ }
+ }
+ return m;
+}
+
+export function resolveOriginalPostName(user, postIdToName = {}) {
+ if (!user) return "";
+ const nameStr = (user.postName ?? user.postname ?? "").toString().trim();
+ if (nameStr) return nameStr;
+ if (Array.isArray(user.posts) && user.posts.length) {
+ return (user.posts[0].postName ?? "").toString() || "鏈懡鍚嶅矖浣�";
+ }
+ const pid = firstPostId(user);
+ if (pid != null && pid !== "") {
+ const n = postIdToName[String(pid)] || "";
+ return n || "褰撳墠宀椾綅锛堟湭鍦ㄥ矖浣嶅瓧鍏镐腑锛�";
+ }
+ return "鏈垎閰嶅矖浣�";
+}
+
+export function userById(users, id) {
+ if (id == null || id === "") return undefined;
+ return (users || []).find(u => String(u.userId ?? u.id) === String(id));
+}
+
+/** 鎸� moduleKey 杩囨护妯℃澘濉姤椤� */
+export function displayTemplateFieldsByModule(moduleKey, fields = []) {
+ if (moduleKey === APPROVAL_MODULE_KEYS.LEAVE) {
+ return displayLeaveTemplateFields(fields);
+ }
+ if (moduleKey === APPROVAL_MODULE_KEYS.OVERTIME) {
+ return displayOvertimeTemplateFields(fields);
+ }
+ if (moduleKey === APPROVAL_MODULE_KEYS.TRANSFER) {
+ return displayTransferTemplateFields(fields);
+ }
+ return fields || [];
+}
+
+/** 淇濆瓨鍓嶅皢涓氬姟鎵╁睍瀛楁鍐欏叆 formValues */
+export function syncModuleExtrasToFormValues(moduleKey, formValues, extras, fields) {
+ if (!moduleKey || !formValues) return;
+ if (moduleKey === APPROVAL_MODULE_KEYS.LEAVE) {
+ if (extras.leaveBalanceDays != null && extras.leaveBalanceDays !== "") {
+ formValues.leaveBalanceDays = extras.leaveBalanceDays;
+ }
+ const days = computeLeaveDurationDisplay(fields, formValues);
+ if (days) formValues.leaveDurationDays = days;
+ }
+ if (moduleKey === APPROVAL_MODULE_KEYS.OVERTIME) {
+ const hours = computeOvertimeHoursDisplay(fields, formValues);
+ if (hours) formValues.overtimeHours = hours;
+ }
+ if (moduleKey === APPROVAL_MODULE_KEYS.TRANSFER && extras.originalPostName) {
+ formValues.originalPostName = extras.originalPostName;
+ formValues.originalPost = extras.originalPostName;
+ }
+}
+
+/** 涓氬姟鎵╁睍鏍¢獙 */
+export function validateModuleExtras(moduleKey, fields, formPayload, extras) {
+ if (moduleKey === APPROVAL_MODULE_KEYS.LEAVE) {
+ if (
+ extras.leaveBalanceDays == null ||
+ extras.leaveBalanceDays === "" ||
+ Number.isNaN(Number(extras.leaveBalanceDays))
+ ) {
+ return "璇峰~鍐欏亣鏈熶綑棰�";
+ }
+ const msg = validateLeaveBeforeSubmit(fields, formPayload);
+ if (msg) return msg;
+ }
+ if (moduleKey === APPROVAL_MODULE_KEYS.OVERTIME) {
+ const msg = validateOvertimeBeforeSubmit(fields, formPayload);
+ if (msg) return msg;
+ }
+ return "";
+}
+
+/** 浠庡疄渚� businessType 鎺ㄦ柇 moduleKey锛堢紪杈戝叆鍙f湭甯� moduleKey 鏃讹級 */
+export function inferModuleKeyFromRow(row, typeOptions = []) {
+ const bt = row?.businessType;
+ if (bt == null || bt === "") return "";
+ for (const key of Object.values(APPROVAL_MODULE_KEYS)) {
+ const types = getModuleMatchingBusinessTypes(key, typeOptions);
+ if (types.some(t => matchBusinessTypeValue(t, bt))) return key;
+ const cfg = APPROVAL_MODULE_REGISTRY[key];
+ if (cfg && matchBusinessTypeValue(cfg.approvalType, bt)) return key;
+ }
+ return "";
+}
+
+/** 缂栬緫鍥炴樉锛氫粠瀹炰緥琛屾仮澶嶆墿灞曞瓧娈� */
+export function loadModuleExtrasFromRow(moduleKey, row, formPayload) {
+ const extras = {
+ leaveBalanceDays: undefined,
+ originalPostName: "",
+ };
+ if (!moduleKey || !row) return extras;
+
+ const payload = formPayload || {};
+ if (moduleKey === APPROVAL_MODULE_KEYS.LEAVE) {
+ const v = payload.leaveBalanceDays ?? row.leaveBalanceDays;
+ extras.leaveBalanceDays =
+ v != null && v !== "" ? Number(v) : undefined;
+ }
+ if (moduleKey === APPROVAL_MODULE_KEYS.TRANSFER) {
+ extras.originalPostName =
+ payload.originalPostName ||
+ payload.originalPost ||
+ row.originalPostName ||
+ "";
+ }
+ return extras;
+}
--
Gitblit v1.9.3