Files
springboot-shop-sysadmin/src/iview/listRowPatch.js
iqudoo eb4e8f1a04 init
2026-06-05 17:22:32 +08:00

102 lines
3.1 KiB
JavaScript

import { emit as emitEvent } from "@/iview/utils/emitter.js";
export const LIST_ROW_PATCH_EVENT = "iview:list-row-patch";
export function getValueByPath(obj, path) {
if (!obj || !path) return null;
return path.split(".").reduce((acc, key) => acc?.[key], obj);
}
export function resolvePatchRowKeyValue(detail, rowKeyField = "guid") {
if (!detail) return null;
return (
detail.rowKeyValue ??
detail.patch?.[rowKeyField] ??
detail.patch?.guid ??
detail.row?.[rowKeyField] ??
detail.row?.guid ??
null
);
}
/**
* @param {Record<string, unknown>} record
* @param {{ rowPatchKey?: string, rowKeyField?: string }} [options]
*/
export function resolveRowMatchKey(record, { rowPatchKey, rowKeyField = "guid" } = {}) {
if (!record || typeof record !== "object") return null;
if (rowPatchKey) {
const nested = getValueByPath(record, rowPatchKey);
if (nested != null && nested !== "") return nested;
}
const row = record;
return row[rowKeyField] ?? row.guid ?? row.rowKey ?? null;
}
/**
* 就地合并 dataSource 中匹配的行(保持行对象引用,便于嵌套 skuInfo 与抽屉联动)
* @param {unknown[]} dataSource
* @param {object} detail
* @param {{ rowPatchKey?: string, rowKeyField?: string, rowPatchMergePath?: string }} [options]
* @returns {boolean}
*/
export function applyRowPatchToDataSource(dataSource, detail, options = {}) {
if (!Array.isArray(dataSource) || !detail) return false;
const rowKeyField = options.rowKeyField || "guid";
const rowKeyValue = resolvePatchRowKeyValue(detail, rowKeyField);
if (rowKeyValue == null) return false;
const idx = dataSource.findIndex(
(row) => String(resolveRowMatchKey(row, options)) === String(rowKeyValue),
);
if (idx < 0) return false;
const row = dataSource[idx];
if (!row || typeof row !== "object") return false;
if (detail.type === "replace" && detail.row && typeof detail.row === "object") {
Object.assign(row, detail.row);
const mergePath = options.rowPatchMergePath;
if (mergePath) {
const nested = getValueByPath(row, mergePath);
const nestedFromRow = getValueByPath(detail.row, mergePath);
if (nested && nestedFromRow && typeof nested === "object" && typeof nestedFromRow === "object") {
Object.assign(nested, nestedFromRow);
}
}
return true;
}
const patch = detail.patch;
if (!patch || typeof patch !== "object") return false;
const mergePath = options.rowPatchMergePath;
if (mergePath) {
const parts = mergePath.split(".");
let target = row;
for (let i = 0; i < parts.length - 1; i++) {
const key = parts[i];
if (!target[key] || typeof target[key] !== "object") {
target[key] = {};
}
target = target[key];
}
const leafKey = parts[parts.length - 1];
if (!target[leafKey] || typeof target[leafKey] !== "object") {
target[leafKey] = {};
}
Object.assign(target[leafKey], patch);
}
Object.keys(patch).forEach((key) => {
if (key in row) row[key] = patch[key];
});
return true;
}
export function emitListRowPatch(detail) {
emitEvent(LIST_ROW_PATCH_EVENT, detail);
}