forked from tools/tape-springboot-sysadmin
102 lines
3.1 KiB
JavaScript
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);
|
|
}
|