From 930d38ed2a3c2131be3305a585602c7a5a275fe3 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期二, 19 五月 2026 17:09:12 +0800
Subject: [PATCH] Merge branch 'dev-new_pro_OA' of http://114.132.189.42:9002/r/product-inventory-management into dev-new_pro_OA
---
src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js | 686 ++++++++++++++++++++++++++++++++++++--------------------
1 files changed, 439 insertions(+), 247 deletions(-)
diff --git a/src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js b/src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js
index 447627a..80af992 100644
--- a/src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js
+++ b/src/views/officeProcessAutomation/ApproveManage/approve-list/approveListConstants.js
@@ -1,4 +1,13 @@
-import dayjs from "dayjs";
+import {
+ createEmptyNode,
+ formatDisplayTime,
+ mapNodesFromApi,
+ mapSignModeFromApi,
+ mapSignModeToApi,
+ normalizeFlowNodes,
+ nodeSignModeLabel,
+} from "../approve-template/approveTemplateConstants.js";
+import { buildFormPayloadFromFields, parseFormConfigToData } from "../approve-template/formConfigUtils.js";
/** 瀹℃壒绫诲瀷锛堜笌鍚庣瀛楁 approvalType 瀵归綈锛屽悗鏈熷彲鍚屾锛� */
export const APPROVAL_TYPE_OPTIONS = [
@@ -25,105 +34,401 @@
{ value: "cancelled", label: "宸叉挙閿�" },
];
-/** 瀹℃壒鏂瑰紡 approvalMode */
-export const APPROVAL_MODE_OPTIONS = [
- { value: "parallel", label: "涓庣" },
- { value: "or_sign", 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 */
+ }
+}
+
+/** 鎻愪氦寮圭獥锛氭ā鏉垮崱鐗囷紙鏉ヨ嚜鍚庣鍒楄〃锛� */
+export function mapSubmitTemplateCard(row) {
+ const cfg = parseFormConfigToData(row?.formConfig);
+ return {
+ id: row?.id,
+ key: String(row?.id ?? ""),
+ approvalType: cfg.approvalType || row?.approvalType || "",
+ label: row?.templateName || "鈥�",
+ summaryPlaceholder: (row?.description || "").trim() || cfg.summaryPlaceholder || "鐐瑰嚮濉啓骞舵彁浜�",
+ };
+}
+
+/** 瀹℃壒璁板綍 approveAction 鈫� 椤甸潰 result */
+export function mapRecordResultFromApi(action) {
+ const s = String(action || "").toUpperCase();
+ if (s === "APPROVED" || s === "APPROVE" || s === "PASS") return "approved";
+ if (s === "REJECTED" || s === "REJECT" || s === "REFUSE") return "rejected";
+ return "pending";
+}
+
+/** 鍚庣 records 鈫� 鏃堕棿绾垮睍绀虹粨鏋� */
+export function mapRecordsFromApi(records) {
+ const list = Array.isArray(records) ? records : [];
+ return list.map((r) => ({
+ id: r.id,
+ operatorName: r.approverName || r.operatorName || r.createUserName || "",
+ result: mapRecordResultFromApi(r.approveAction ?? r.action ?? r.status),
+ opinion: r.approveComment || r.comment || r.opinion || "",
+ time: formatDisplayTime(r.approveTime || r.createTime || r.time || ""),
+ raw: r,
+ }));
+}
+
+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 || "鈥�";
+}
+
+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";
+}
+
+/** 鍚庣 tasks 鈫� 椤甸潰 flowNodes锛堟寜 levelNo 鍒嗙粍锛屼緵娴佺▼缂栬緫/灞曠ず锛� */
+export function mapTasksToFlowNodes(tasks) {
+ const list = Array.isArray(tasks) ? tasks : [];
+ if (!list.length) return [];
+ const byLevel = new Map();
+ list.forEach((t) => {
+ const level = Number(t.levelNo ?? t.taskLevel ?? t.nodeOrder ?? 1);
+ if (!byLevel.has(level)) {
+ byLevel.set(level, {
+ id: t.nodeId,
+ templateId: t.templateId,
+ nodeOrder: level,
+ signMode: mapSignModeFromApi(t.approveType),
+ approvers: [],
+ tasks: [],
+ });
+ }
+ const node = byLevel.get(level);
+ node.approvers.push({
+ id: t.id,
+ nodeId: t.nodeId,
+ templateId: t.templateId,
+ approverId: t.approverId,
+ approverName: t.approverName || "",
+ status: t.status,
+ approveComment: t.approveComment,
+ approveTime: t.approveTime,
+ });
+ node.tasks.push(t);
+ if (t.approveType != null) {
+ node.signMode = mapSignModeFromApi(t.approveType);
+ }
+ });
+ return [...byLevel.entries()]
+ .sort(([a], [b]) => a - b)
+ .map(([, node]) => node);
+}
+
+/** 椤甸潰 flowNodes 鈫� 鍚庣 tasks */
+export function mapFlowNodesToTasks(flowNodes, { instanceId, templateId } = {}) {
+ const nodes = normalizeFlowNodes(flowNodes);
+ const tasks = [];
+ nodes.forEach((n) => {
+ const levelNo = n.nodeOrder ?? 1;
+ const approveType = mapSignModeToApi(n.signMode);
+ n.approvers.forEach((a, idx) => {
+ const task = {
+ levelNo,
+ approveType,
+ approverId: a.approverId,
+ approverName: a.approverName || "",
+ sortNo: a.sortNo ?? idx + 1,
+ };
+ if (a.id != null) task.id = a.id;
+ if (a.nodeId != null) task.nodeId = a.nodeId;
+ if (a.templateId != null) task.templateId = a.templateId;
+ else if (templateId) task.templateId = templateId;
+ if (instanceId) task.instanceId = instanceId;
+ if (a.status != null) task.status = a.status;
+ tasks.push(task);
+ });
+ });
+ return tasks;
+}
+
+function guessFieldTypeFromValue(val) {
+ if (Array.isArray(val) && val.length === 2) return "datetimerange";
+ if (typeof val === "number") return "number";
+ if (typeof val === "string" && /^\d{4}-\d{2}-\d{2}$/.test(val)) return "date";
+ if (typeof val === "string" && val.length > 100) return "textarea";
+ return "text";
+}
+
+/** 鍗曞瓧娈靛睍绀哄�硷紙璇︽儏鍙锛� */
+export function formatFieldDisplayValue(field, val) {
+ if (val == null || val === "" || (Array.isArray(val) && !val.length)) return "鈥�";
+ if (field?.type === "select" && field.options?.length) {
+ const hit = field.options.find((o) => String(o.value) === String(val));
+ return hit?.label || String(val);
+ }
+ if (Array.isArray(val)) return val.join(" 鑷� ");
+ return String(val);
+}
/**
- * 鎻愪氦瀹℃壒妯℃澘锛堟寜绫诲瀷涓�閿~鎶ワ紝瀛楁鍚庢湡涓庡悗绔ā鏉垮悓姝ワ級
+ * 浠庤鏁版嵁 / formConfig 瑙f瀽濉姤瀛楁瀹氫箟涓� formPayload锛堜笌鏂板鎻愪氦缁撴瀯涓�鑷达級
*/
-export const SUBMIT_TEMPLATES = {
- cost_reimburse: {
- approvalType: "cost_reimburse",
- label: "璐圭敤鎶ラ攢",
- summaryPlaceholder: "璇峰~鍐欐姤閿�浜嬬敱銆侀噾棰濈瓑",
- fields: [
- { key: "summary", label: "鐢宠浜嬬敱", type: "textarea", required: true, rows: 3 },
- { key: "amount", label: "鎶ラ攢閲戦(鍏�)", type: "number", required: true, min: 0, precision: 2 },
- ],
- approvalMode: "parallel",
- },
- travel_reimburse: {
- approvalType: "travel_reimburse",
- label: "宸梾鎶ラ攢",
- summaryPlaceholder: "鍑哄樊琛岀▼涓庤垂鐢ㄨ鏄�",
- fields: [
- { key: "summary", label: "宸梾璇存槑", type: "textarea", required: true, rows: 3 },
- { key: "amount", label: "鎶ラ攢閲戦(鍏�)", type: "number", required: true, min: 0, precision: 2 },
- { key: "tripDays", label: "鍑哄樊澶╂暟", type: "number", required: false, min: 0, precision: 0 },
- ],
- approvalMode: "parallel",
- },
- overtime: {
- approvalType: "overtime",
- label: "鍔犵彮鐢宠",
- fields: [
- { key: "summary", label: "鍔犵彮浜嬬敱", type: "textarea", required: true, rows: 3 },
- { key: "overtimeDate", label: "鍔犵彮鏃ユ湡", type: "date", required: true },
- { key: "hours", label: "鍔犵彮鏃堕暱(灏忔椂)", type: "number", required: true, min: 0.5, precision: 1 },
- ],
- approvalMode: "parallel",
- },
- leave: {
- approvalType: "leave",
- label: "璇峰亣鐢宠",
- fields: [
- { key: "leaveType", label: "璇峰亣绫诲瀷", type: "select", required: true, options: [
- { label: "骞村亣", value: "annual" },
- { label: "鐥呭亣", value: "sick" },
- { label: "浜嬪亣", value: "personal" },
- { label: "璋冧紤", value: "compensatory" },
- ] },
- { key: "summary", label: "璇峰亣浜嬬敱", type: "textarea", required: true, rows: 2 },
- { key: "dateRange", label: "璇峰亣鏃堕棿", type: "datetimerange", required: true },
- ],
- approvalMode: "parallel",
- },
- work_handover: {
- approvalType: "work_handover",
- label: "宸ヤ綔浜ゆ帴",
- fields: [
- { key: "summary", label: "浜ゆ帴璇存槑", type: "textarea", required: true, rows: 3 },
- { key: "handoverTo", label: "浜ゆ帴瀵硅薄", type: "text", required: true },
- ],
- approvalMode: "parallel",
- },
- regular: {
- approvalType: "regular",
- label: "杞鐢宠",
- fields: [
- { key: "summary", label: "杞璇存槑", type: "textarea", required: true, rows: 3 },
- { key: "regularDate", label: "鎷熻浆姝f棩鏈�", type: "date", required: true },
- ],
- approvalMode: "parallel",
- },
- resign: {
- approvalType: "resign",
- label: "绂昏亴鐢宠",
- fields: [
- { key: "summary", label: "绂昏亴鍘熷洜", type: "textarea", required: true, rows: 3 },
- { key: "lastWorkDay", label: "鏈�鍚庡伐浣滄棩", type: "date", required: true },
- ],
- approvalMode: "or_sign",
- },
- transfer: {
- approvalType: "transfer",
- label: "璋冨矖鐢宠",
- fields: [
- { key: "summary", label: "璋冨矖璇存槑", type: "textarea", required: true, rows: 2 },
- { key: "targetDept", label: "鐩爣閮ㄩ棬", type: "text", required: true },
- { key: "targetPost", label: "鐩爣宀椾綅", type: "text", required: true },
- ],
- approvalMode: "parallel",
- },
-};
+export function resolveInstanceFormFields(row) {
+ const cfg = parseInstanceFormConfig(row?.formConfig);
+ 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,
+ rows: 3,
+ min: 0,
+ precision: 0,
+ options: [],
+ }));
+ }
+ const templateSnapshot = {
+ label: row?.templateName || row?.title || "瀹℃壒",
+ approvalType: cfg.approvalType || row?.approvalType || "",
+ summaryPlaceholder: cfg.summaryPlaceholder || "",
+ templateId: row?.templateId,
+ fields,
+ };
+ return { fields, formPayload, templateSnapshot, formConfigData: cfg };
+}
-export const STORAGE_KEY = "oa_unified_approve_list_v1";
+/** 瑙f瀽瀹炰緥 formConfig */
+export function parseInstanceFormConfig(formConfig) {
+ let raw = {};
+ if (formConfig) {
+ if (typeof formConfig === "object") raw = formConfig;
+ else {
+ try {
+ raw = JSON.parse(formConfig);
+ } catch {
+ raw = {};
+ }
+ }
+ }
+ const data = parseFormConfigToData(formConfig);
+ const payload = raw.formPayload;
+ return {
+ summaryPlaceholder: raw.summaryPlaceholder || data.summaryPlaceholder || "",
+ approvalType: raw.approvalType || "",
+ fields: data.fields || [],
+ formPayload: payload && typeof payload === "object" ? payload : {},
+ };
+}
+
+export function unwrapInstanceDetail(res) {
+ const data = res?.data ?? res;
+ if (!data || typeof data !== "object") return {};
+ if (data.id != null || data.instanceNo) return data;
+ if (data.approvalInstanceVo) return data.approvalInstanceVo;
+ return data;
+}
+
+/** 濉姤鍐呭 + 妯℃澘瀛楁瀹氫箟 鈫� formConfig JSON */
+export function buildInstanceFormConfigJson(templateSnapshot, formPayload) {
+ const payload = formPayload || {};
+ return JSON.stringify({
+ summaryPlaceholder: templateSnapshot?.summaryPlaceholder || "",
+ approvalType: templateSnapshot?.approvalType || "",
+ fields: templateSnapshot?.fields || [],
+ formPayload: payload,
+ });
+}
+
+/** 缁勮淇濆瓨/鏇存柊瀹℃壒 DTO */
+export function buildInstanceDto({ submitForm, activeTemplate, userStore, flowNodes, existingRow }) {
+ const payload = submitForm?.formPayload || {};
+ const tpl = activeTemplate || {};
+ const title =
+ String(payload.summary || payload.title || "").trim() ||
+ tpl.label ||
+ submitForm?.templateName ||
+ "瀹℃壒鐢宠";
+ const templateId = submitForm?.templateId || tpl.templateId;
+ const instanceId = existingRow?.id ?? submitForm?.instanceId;
+ const taskList = mapFlowNodesToTasks(flowNodes || submitForm?.flowNodes, {
+ instanceId,
+ templateId,
+ });
+ const isUpdate = Boolean(instanceId);
+
+ const dto = {
+ templateId,
+ templateName: submitForm?.templateName || tpl.label || "",
+ title,
+ formConfig: buildInstanceFormConfigJson({ ...tpl, fields: tpl.fields || submitForm?.formFieldDefs }, payload),
+ tasks: taskList,
+ };
+
+ if (isUpdate) {
+ dto.id = existingRow?.id ?? submitForm?.instanceId;
+ dto.instanceNo = existingRow?.instanceNo ?? submitForm?.instanceNo ?? "";
+ dto.status =
+ existingRow?.statusRaw || mapInstanceStatusToApi(existingRow?.approvalStatus) || "PENDING";
+ dto.currentLevel = existingRow?.currentLevel ?? submitForm?.currentLevel ?? 1;
+ dto.applicantId = existingRow?.applicantId ?? existingRow?.applicantNo;
+ dto.applicantName = existingRow?.applicantName || "";
+ } else {
+ dto.status = "PENDING";
+ dto.currentLevel = 1;
+ dto.applicantId = userStore?.id;
+ dto.applicantName = userStore?.nickName || userStore?.name || "";
+ }
+ return dto;
+}
+
+/** @deprecated 浣跨敤 buildInstanceDto */
+export function buildSaveInstanceDto(params) {
+ return buildInstanceDto(params);
+}
+
+/** 鏍¢獙鎻愪氦瀹℃壒娴佺▼锛堜笌妯℃澘椤佃鍒欎竴鑷达級 */
+export function validateSubmitFlowNodes(flowNodes) {
+ const nodes = normalizeFlowNodes(flowNodes);
+ if (!nodes.length) return { ok: false, message: "璇疯嚦灏戦厤缃竴涓鎵硅妭鐐�" };
+ for (let i = 0; i < nodes.length; i++) {
+ if (!nodes[i].approvers.length) {
+ return { ok: false, message: `璇蜂负绗� ${i + 1} 涓妭鐐归�夋嫨鑷冲皯涓�鍚嶅鎵逛汉` };
+ }
+ }
+ return { ok: true, nodes };
+}
+
+/** 鍚庣 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";
+}
+
+/** 椤甸潰 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";
+}
+
+export function unwrapInstancePage(res) {
+ const data = res?.data ?? res;
+ return {
+ records: Array.isArray(data?.records) ? data.records : [],
+ total: Number(data?.total ?? 0),
+ };
+}
+
+/** 鍒嗛〉鍒楄〃椤� 鈫� 琛ㄦ牸琛� */
+export function mapInstanceFromApi(row) {
+ if (!row) return {};
+ const approvalStatus = mapInstanceStatusFromApi(row.status);
+ const createTime = formatDisplayTime(row.createTime ?? row.applyTime ?? "");
+ const applyTime = formatDisplayTime(row.applyTime ?? "");
+ const finishTime = formatDisplayTime(row.finishTime ?? "");
+ const resolved = resolveInstanceFormFields(row);
+ const { fields, formPayload, templateSnapshot } = resolved;
+ const tasks = Array.isArray(row.tasks) ? row.tasks : [];
+ const flowNodes = tasks.length
+ ? mapTasksToFlowNodes(tasks)
+ : mapNodesFromApi(row.nodes || row.flowNodes);
+ const approvalRecords = mapRecordsFromApi(row.records);
+ return {
+ id: row.id,
+ bizId: row.instanceNo || String(row.id ?? ""),
+ instanceNo: row.instanceNo || "",
+ templateId: row.templateId,
+ 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 || "",
+ approvalType: row.templateName || "",
+ unread: Boolean(row.isApprove) && approvalStatus === "pending",
+ isApprove: Boolean(row.isApprove),
+ approvalStatus,
+ statusRaw: row.status,
+ createTime,
+ applyTime: applyTime === "鈥�" ? "" : applyTime,
+ finishTime: finishTime === "鈥�" ? "" : finishTime,
+ title: row.title || "",
+ summary: row.title || row.templateName || "",
+ currentLevel: row.currentLevel,
+ formConfig: row.formConfig,
+ formPayload,
+ formFieldDefs: fields,
+ templateSnapshot,
+ tasks,
+ records: Array.isArray(row.records) ? row.records : [],
+ flowNodes,
+ approvalFlowNodes: [],
+ currentNodeIndex: 0,
+ approvalRecords,
+ rejectReason:
+ approvalRecords.find((r) => r.result === "rejected")?.opinion || "",
+ };
+}
+
+/** 瀹℃壒鎿嶄綔锛氫笌鍚庣 status 鏋氫妇涓�鑷� */
+export const APPROVE_ACTION_APPROVED = "APPROVED";
+export const APPROVE_ACTION_REJECTED = "REJECTED";
+
+/** 椤甸潰鎿嶄綔 鈫� approveAction */
+export function mapApproveActionToApi(uiResult) {
+ return uiResult === "rejected" ? APPROVE_ACTION_REJECTED : APPROVE_ACTION_APPROVED;
+}
+
+/** 缁勮瀹℃壒鎻愪氦 DTO */
+export function buildApproveInstanceDto(row, uiResult, comment) {
+ const opinion = (comment || "").trim();
+ return {
+ id: row?.id,
+ approveAction: mapApproveActionToApi(uiResult),
+ approveComment: opinion || (uiResult === "approved" ? "鍚屾剰" : ""),
+ };
+}
+
+export function buildApprovalInstanceListParams({ page, searchForm }) {
+ const params = {
+ current: page.current,
+ size: page.size,
+ };
+ 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;
+ }
+ if (Object.keys(dto).length) params.approvalInstanceDto = dto;
+ return params;
+}
export function approvalTypeLabel(v) {
- return APPROVAL_TYPE_OPTIONS.find((x) => x.value === v)?.label || "鈥�";
+ return APPROVAL_TYPE_OPTIONS.find((x) => x.value === v)?.label || v || "鈥�";
}
export function approvalTypeStyle(v) {
@@ -147,170 +452,57 @@
return "primary";
}
-export function approvalModeLabel(v) {
- if (v === "countersign") return "鎴栫";
- return APPROVAL_MODE_OPTIONS.find((x) => x.value === v)?.label || "涓庣";
-}
-
export function unreadLabel(v) {
return v ? "鏄�" : "鍚�";
}
-export function buildDefaultFlowNodes() {
- return [
- {
- approverId: "mock_supervisor",
- approverName: "鐩村睘涓婄骇",
- sortOrder: 1,
- nodeOrder: 1,
- nodeStatus: "process",
- approveOpinion: "",
- approveTime: "",
- },
- {
- approverId: "mock_manager",
- approverName: "閮ㄩ棬缁忕悊",
- sortOrder: 2,
- nodeOrder: 2,
- nodeStatus: "wait",
- approveOpinion: "",
- approveTime: "",
- },
- ];
-}
+/** 鍒楄〃琛� 鈫� 缂栬緫琛ㄥ崟锛堜粎鐢ㄨ鏁版嵁鍥炴樉锛� */
+export function buildEditFormFromInstanceRow(row) {
+ const { fields, formPayload, templateSnapshot } = resolveInstanceFormFields(row);
+ const normalized = normalizeFlowNodes(
+ row?.flowNodes?.length ? row.flowNodes : mapTasksToFlowNodes(row?.tasks)
+ );
+ const flowNodes = normalized.length
+ ? JSON.parse(JSON.stringify(normalized))
+ : [createEmptyNode(1)];
-function demoRow(partial) {
- const now = dayjs().format("YYYY-MM-DD HH:mm:ss");
return {
- id: partial.id,
- bizId: partial.bizId || partial.id,
- applicantNo: partial.applicantNo,
- applicantName: partial.applicantName,
- approvalType: partial.approvalType,
- approvalMode: partial.approvalMode || "parallel",
- unread: partial.unread ?? false,
- approvalStatus: partial.approvalStatus || "pending",
- createTime: partial.createTime || now,
- summary: partial.summary || "",
- formPayload: partial.formPayload || {},
- approvalFlowNodes: partial.approvalFlowNodes || buildDefaultFlowNodes(),
- currentNodeIndex: partial.currentNodeIndex ?? 0,
- approvalRecords: partial.approvalRecords || [],
- rejectReason: partial.rejectReason || "",
- sourceRoute: partial.sourceRoute || "",
+ templateKey: String(row?.templateId || ""),
+ templateId: row?.templateId,
+ templateName: row?.templateName || templateSnapshot.label,
+ instanceId: row?.id,
+ instanceNo: row?.instanceNo || "",
+ statusRaw: row?.statusRaw || row?.status || "PENDING",
+ currentLevel: row?.currentLevel ?? 1,
+ applicantId: row?.applicantId,
+ applicantName: row?.applicantName || "",
+ templateSnapshot,
+ formFieldDefs: fields,
+ formPayload,
+ flowNodes,
};
}
-/** 鍒濆婕旂ず鏁版嵁锛堝叡 22 鏉★紝涓庡師鍨嬫暟閲忎竴鑷达級 */
-export function createInitialMockRows() {
- const types = [
- "cost_reimburse",
- "travel_reimburse",
- "overtime",
- "leave",
- "work_handover",
- "regular",
- "resign",
- "transfer",
- "cost_reimburse",
- "leave",
- "overtime",
- "travel_reimburse",
- "work_handover",
- "regular",
- "cost_reimburse",
- "leave",
- "transfer",
- "resign",
- "overtime",
- "travel_reimburse",
- "cost_reimburse",
- "leave",
- ];
- const applicants = [
- { no: "007", name: "鑻规灉" },
- { no: "Guest001", name: "澶栭儴鐢ㄦ埛" },
- { no: "0056", name: "鐜嬩簲" },
- { no: "0042", name: "鏉庡洓" },
- { no: "0088", name: "鐚尗" },
- { no: "0012", name: "寮犱笁" },
- { no: "0033", name: "璧靛叚" },
- ];
- const summaries = [
- "鍔炲叕鐢ㄥ搧閲囪喘鎶ラ攢",
- "涓婃捣鍑哄樊宸梾璐�",
- "鍛ㄦ湯椤圭洰鍔犵彮",
- "骞村亣 3 澶�",
- "绂昏亴宸ヤ綔浜ゆ帴",
- "璇曠敤鏈熻浆姝g敵璇�",
- "涓汉鍘熷洜绂昏亴",
- "璋冭嚦閿�鍞儴",
- "瀹㈡埛鎺ュ緟椁愯垂",
- "鐥呭亣 1 澶�",
- "鑺傚亣鏃ュ�肩彮鍔犵彮",
- "鍖椾含鍩硅宸梾",
- "椤圭洰鏂囨。浜ゆ帴",
- "鐮斿彂宀楄浆姝�",
- "閫氳璐规姤閿�",
- "浜嬪亣鍗婂ぉ",
- "璋冨矖鑷冲競鍦洪儴",
- "鍗忓晢绂昏亴",
- "宸ヤ綔鏃ュ欢鏃跺姞鐝�",
- "鎴愰兘灞曚細宸梾",
- "浜ら�氳垂鎶ラ攢",
- "璋冧紤 1 澶�",
- ];
- const statuses = ["pending", "pending", "pending", "approved", "pending", "pending", "rejected", "pending"];
- return types.map((approvalType, i) => {
- const ap = applicants[i % applicants.length];
- const daysAgo = i % 14;
- return demoRow({
- id: `mock_${i + 1}`,
- bizId: `BIZ${String(2025031400 + i)}`,
- applicantNo: ap.no,
- applicantName: ap.name,
- approvalType,
- approvalMode: i % 5 === 0 ? "or_sign" : "parallel",
- unread: i % 3 === 0,
- approvalStatus: statuses[i % statuses.length],
- createTime: dayjs().subtract(daysAgo, "day").hour(9 + (i % 8)).minute((i * 7) % 60).second(0).format("YYYY-MM-DD HH:mm:ss"),
- summary: summaries[i],
- formPayload: { summary: summaries[i] },
- });
- });
-}
-
-export function loadStoredRows() {
- try {
- const raw = localStorage.getItem(STORAGE_KEY);
- if (!raw) return null;
- const parsed = JSON.parse(raw);
- return Array.isArray(parsed) ? parsed : null;
- } catch {
- return null;
- }
-}
-
-export function saveStoredRows(rows) {
- try {
- localStorage.setItem(STORAGE_KEY, JSON.stringify(rows));
- } catch {
- /* ignore quota */
- }
-}
-
-export function createEmptySubmitForm(templateKey) {
- const tpl = SUBMIT_TEMPLATES[templateKey];
- const payload = { summary: "" };
- (tpl?.fields || []).forEach((f) => {
- if (f.type === "number") payload[f.key] = undefined;
- else if (f.type === "datetimerange") payload[f.key] = [];
- else payload[f.key] = "";
- });
+export function createEmptySubmitForm(templateKey, templateOverride, flowNodesOverride) {
+ const tpl = templateOverride || null;
+ const payload = tpl?.fields?.length ? buildFormPayloadFromFields(tpl.fields) : { summary: "" };
+ const normalized = normalizeFlowNodes(flowNodesOverride);
+ const flowNodes = normalized.length
+ ? JSON.parse(JSON.stringify(normalized))
+ : [createEmptyNode(1)];
return {
templateKey: templateKey || "",
- approvalMode: tpl?.approvalMode || "parallel",
+ templateId: tpl?.templateId || "",
+ templateName: tpl?.label || "",
+ instanceId: "",
+ instanceNo: "",
+ statusRaw: "",
+ currentLevel: 1,
+ applicantId: null,
+ applicantName: "",
+ templateSnapshot: templateOverride || null,
+ formFieldDefs: tpl?.fields || [],
formPayload: payload,
- approvalFlowNodes: buildDefaultFlowNodes(),
+ flowNodes,
};
}
--
Gitblit v1.9.3