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/approveListUtils.js | 358 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 358 insertions(+), 0 deletions(-)
diff --git a/src/pages/oa/_utils/approveListUtils.js b/src/pages/oa/_utils/approveListUtils.js
new file mode 100644
index 0000000..538fec9
--- /dev/null
+++ b/src/pages/oa/_utils/approveListUtils.js
@@ -0,0 +1,358 @@
+import { parseTime } from "@/utils/ruoyi";
+import {
+ formatFieldDisplayValue,
+ getFieldOptionLabel,
+ isSelectField,
+ mergeFormConfigForEdit,
+} from "./approvalFormField.js";
+import {
+ appendDotNotationQuery,
+ buildApprovalInstanceSearchDto,
+ formatKnownSelectLabel,
+ resolveInstanceFormPayload,
+ resolveListFieldRawValue,
+} from "./approvalModuleListSearch.js";
+
+export const DETAIL_STORAGE_KEY = "oa_approve_instance_detail_row";
+
+export const INSTANCE_STATUS_TEXT = {
+ PENDING: "杩涜涓�",
+ APPROVED: "宸查�氳繃",
+ REJECTED: "宸查┏鍥�",
+ DRAFT: "鑽夌",
+};
+
+export const INSTANCE_STATUS_TAG = {
+ PENDING: "warning",
+ APPROVED: "success",
+ REJECTED: "error",
+ DRAFT: "info",
+};
+
+export const TASK_STATUS_TEXT = {
+ PENDING: "寰呭鐞�",
+ APPROVED: "宸查�氳繃",
+ REJECTED: "宸查┏鍥�",
+};
+
+export const TASK_STATUS_TAG = {
+ PENDING: "warning",
+ APPROVED: "success",
+ REJECTED: "error",
+};
+
+export function instanceStatusText(status) {
+ return INSTANCE_STATUS_TEXT[status] || status || "-";
+}
+
+export function instanceStatusTagType(status) {
+ return INSTANCE_STATUS_TAG[status] || "info";
+}
+
+export function taskStatusText(status) {
+ const key = String(status || "").toUpperCase();
+ return TASK_STATUS_TEXT[key] || status || "寰呭鐞�";
+}
+
+export function taskStatusTagType(status) {
+ const key = String(status || "").toUpperCase();
+ return TASK_STATUS_TAG[key] || "info";
+}
+
+export function formatDateTime(val) {
+ if (!val) return "-";
+ return parseTime(val, "{y}-{m}-{d} {h}:{i}:{s}") || String(val);
+}
+
+/** 瑙f瀽瀹炰緥涓哄彧璇诲睍绀哄瓧娈碉紙鍚堝苟 formPayload锛屾敮鎸佷紶鏁磋鎴栦粎 formConfig锛� */
+export function resolveInstanceDisplayFields(formConfigOrRow) {
+ const row =
+ formConfigOrRow &&
+ typeof formConfigOrRow === "object" &&
+ (formConfigOrRow.formConfig != null ||
+ formConfigOrRow.formPayload != null ||
+ formConfigOrRow.formFieldDefs != null)
+ ? formConfigOrRow
+ : { formConfig: formConfigOrRow };
+ const { fields } = resolveInstanceFormPayload(row);
+ if (fields.length) return fields.filter(f => f?.key);
+ const merged = mergeFormConfigForEdit("", row.formConfig);
+ return (merged.fields || []).filter(f => f?.key);
+}
+
+export function displayFieldValue(field) {
+ const val = field.value ?? field.defaultValue;
+ if (val === undefined || val === null || val === "") return "-";
+ if (isSelectField(field)) {
+ const fromOptions = getFieldOptionLabel(field, val);
+ if (fromOptions && fromOptions !== "-") return fromOptions;
+ const known = formatKnownSelectLabel(field.key, val);
+ if (known) return known;
+ return String(val);
+ }
+ const known = formatKnownSelectLabel(field?.key, val);
+ if (known) return known;
+ const shown = formatFieldDisplayValue(field, val);
+ return shown || String(val);
+}
+
+const DATETIME_LIST_PROPS = new Set([
+ "startTime",
+ "endTime",
+ "overtimeDate",
+ "applyTime",
+]);
+
+function formatListFieldDisplay(prop, val, field) {
+ if (val === undefined || val === null || val === "") return "-";
+ if (DATETIME_LIST_PROPS.has(prop)) {
+ const shown = formatDateTime(val);
+ if (shown && shown !== "-") return shown;
+ }
+ if (field?.type === "datetimerange") {
+ const shown = formatFieldDisplayValue(field, val);
+ if (shown) return shown;
+ }
+ if (field) return displayFieldValue({ ...field, value: val });
+ const known = formatKnownSelectLabel(prop, val);
+ if (known) return known;
+ return String(val);
+}
+
+/** 瀹℃壒璁板綍 result锛歛pproved | rejected | pending */
+export function mapRecordResult(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";
+}
+
+export function recordActionLabel(result) {
+ if (result === "approved") return "閫氳繃";
+ if (result === "rejected") return "椹冲洖";
+ return "寰呭鐞�";
+}
+
+export function mapApprovalRecords(records) {
+ const list = Array.isArray(records) ? records : [];
+ return list.map((r, index) => ({
+ id: r.id ?? index,
+ operatorName: r.approverName || r.operatorName || r.createUserName || "鈥�",
+ result: mapRecordResult(r.approveAction ?? r.action ?? r.status),
+ opinion: r.approveComment || r.comment || r.opinion || "",
+ time: formatDateTime(r.approveTime || r.createTime || r.time),
+ }));
+}
+
+export function getRejectReasonFromRecords(records) {
+ const mapped = mapApprovalRecords(records);
+ const hit = mapped.find(r => r.result === "rejected");
+ return hit?.opinion || "";
+}
+
+/** 鍒楄〃 tasks 鈫� 娴佺▼鑺傜偣锛堜笌 apply 椤佃妭鐐圭粨鏋勬帴杩戯級 */
+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, {
+ levelNo: level,
+ approveType: t.approveType || "AND",
+ approvers: [],
+ });
+ }
+ const node = byLevel.get(level);
+ node.approvers.push({
+ approverName: t.approverName || "鈥�",
+ taskStatus: t.taskStatus ?? t.status,
+ approveComment: t.approveComment,
+ approveTime: t.approveTime,
+ });
+ if (t.approveType) node.approveType = t.approveType;
+ });
+
+ return [...byLevel.entries()]
+ .sort(([a], [b]) => a - b)
+ .map(([, node]) => node);
+}
+
+/** 缁勮瀹℃壒鎻愪氦 DTO锛堜笌 Web buildApproveInstanceDto 涓�鑷达級 */
+export function buildApproveInstanceDto(id, uiResult, comment) {
+ const opinion = (comment || "").trim();
+ return {
+ id,
+ approveAction: uiResult === "rejected" ? "REJECTED" : "APPROVED",
+ approveComment: opinion || (uiResult === "approved" ? "鍚屾剰" : ""),
+ };
+}
+
+/** 鏄惁鏈汉鍙戣捣鐨勫鎵� */
+export function isOwnApplication(item, userStore) {
+ const uid = userStore?.id;
+ if (item?.applicantId != null && uid != null && uid !== "") {
+ return String(item.applicantId) === String(uid);
+ }
+ const loginName = userStore?.nickName || userStore?.name;
+ if (loginName && item?.applicantName) {
+ return String(item.applicantName).trim() === String(loginName).trim();
+ }
+ return false;
+}
+
+/** 浠呰繘琛屼腑涓旀湰浜哄彂璧锋椂鍙紪杈� */
+export function canModifyInstance(item, userStore) {
+ return item?.status === "PENDING" && isOwnApplication(item, userStore);
+}
+
+/** 寰呭綋鍓嶇敤鎴峰鎵� */
+export function canApproveInstance(item) {
+ return Boolean(item?.isApprove) && item?.status === "PENDING";
+}
+
+export function stashInstanceRow(item) {
+ if (item) {
+ uni.setStorageSync(DETAIL_STORAGE_KEY, item);
+ }
+}
+
+export function loadInstanceRow(id) {
+ const row = uni.getStorageSync(DETAIL_STORAGE_KEY);
+ if (!row || String(row.id) !== String(id)) return null;
+ return row;
+}
+
+export const EDIT_STORAGE_KEY = "oa_approve_instance_edit_row";
+
+/** 涓氬姟鐢宠椤电姸鎬侊細杩涜涓�/宸插畬鎴愪笉鍙慨鏀癸紙涓� Web canEditBusinessInstanceRow 涓�鑷达級 */
+export function normalizeApprovalStatusKey(v) {
+ if (v == null || v === "") return "pending";
+ const upper = String(v).trim().toUpperCase();
+ if (upper === "DRAFT") return "draft";
+ if (upper === "APPROVED" || 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") return "pending";
+ const lower = String(v).trim().toLowerCase();
+ if (["draft", "pending", "approved", "rejected", "cancelled"].includes(lower)) {
+ return lower;
+ }
+ return "pending";
+}
+
+export function canEditBusinessInstanceRow(row) {
+ const key = normalizeApprovalStatusKey(row?.status ?? row?.approvalStatus);
+ return key !== "pending" && key !== "approved";
+}
+
+export function businessStatusText(status) {
+ const key = normalizeApprovalStatusKey(status);
+ if (key === "draft") return "鑽夌";
+ if (key === "pending") return "杩涜涓�";
+ if (key === "approved") return "宸插畬鎴�";
+ if (key === "rejected") return "宸查┏鍥�";
+ if (key === "cancelled") return "宸叉挙閿�";
+ return instanceStatusText(status);
+}
+
+export function businessStatusTagType(status) {
+ const key = normalizeApprovalStatusKey(status);
+ if (key === "approved") return "success";
+ if (key === "rejected") return "error";
+ if (key === "draft" || key === "cancelled") return "info";
+ return "warning";
+}
+
+/** OA 鍒楄〃鑷畾涔夌姸鎬佽鏍� class */
+export function businessStatusClass(status) {
+ return `status-${normalizeApprovalStatusKey(status)}`;
+}
+
+/**
+ * 涓� Web buildApprovalInstanceListParams 涓�鑷�
+ */
+export function buildInstanceListParams({
+ page,
+ businessType,
+ extraDto = {},
+ searchForm,
+}) {
+ const dto = buildApprovalInstanceSearchDto(searchForm, extraDto);
+ const bizType = businessType ?? searchForm?.businessType;
+ if (bizType != null && bizType !== "") {
+ dto.businessType = bizType;
+ }
+
+ const params = {
+ current: page.current,
+ size: page.size,
+ "page.current": page.current,
+ "page.size": page.size,
+ ...dto,
+ };
+ appendDotNotationQuery(params, "approvalInstanceDto", dto);
+ return params;
+}
+
+export function unwrapInstancePage(res) {
+ const data = res?.data ?? res;
+ return {
+ records: Array.isArray(data?.records) ? data.records : [],
+ total: Number(data?.total ?? 0),
+ };
+}
+
+/** 浠庡疄渚嬭鎻愬彇鍒楄〃灞曠ず瀛楁锛坙abel + value锛屽惈 formPayload锛� */
+export function buildFormDisplayRows(row, listFields = []) {
+ const { fields, formPayload } = resolveInstanceFormPayload(row);
+ const fieldByKey = new Map((fields || []).map(f => [f.key, f]));
+ const rows = [];
+ const defs = listFields || [];
+
+ if (defs.length) {
+ defs.forEach(def => {
+ if (!def?.prop) return;
+ const prop = def.prop;
+ const hit = fieldByKey.get(prop);
+ const raw = resolveListFieldRawValue(prop, row, fields, formPayload);
+ rows.push({
+ label: def.label || hit?.label || prop,
+ value: formatListFieldDisplay(prop, raw, hit),
+ });
+ });
+ } else {
+ fields.slice(0, 3).forEach(f => {
+ rows.push({ label: f.label, value: displayFieldValue(f) });
+ });
+ }
+ return rows;
+}
+
+/** 鍒楄〃琛屽寮猴紙淇濈暀鍘熷瀛楁渚涜鎯�/缂栬緫锛� */
+export function mapInstanceListRow(row, listFields = []) {
+ if (!row) return {};
+ const displayRows = buildFormDisplayRows(row, listFields);
+ const extra = {};
+ const { fields, formPayload } = resolveInstanceFormPayload(row);
+ (listFields || []).forEach(def => {
+ if (!def?.prop) return;
+ const hit = fields.find(f => f.key === def.prop);
+ const raw = resolveListFieldRawValue(def.prop, row, fields, formPayload);
+ extra[def.prop] = formatListFieldDisplay(def.prop, raw, hit);
+ });
+ return {
+ ...row,
+ approvalStatus: normalizeApprovalStatusKey(row.status),
+ summary: row.title || row.templateName || "",
+ createTime: formatDateTime(row.applyTime || row.createTime),
+ displayRows,
+ formPayload,
+ formFieldDefs: fields,
+ ...extra,
+ };
+}
--
Gitblit v1.9.3