import { ID, IStoreState } from '../index.data'; import * as R from 'rambda'; import { isPlainObject } from 'valor-app-utils'; import shallowequal from 'shallowequal'; import { RootNodeId } from 'valor-app-utils/dist/tree/interface'; /** * 以最精简的方式设置 state * 亦即: 如果 state.k === props.k, 则不更新 * 例如 ({a:1, b:2, c:3, d:4}, {a:1, b:3}) => {b:3} * @param base 可以理解为state * @param patch 可以理解为 partial * @returns patch里与obj不同的部分, 默认deep */ export function pickPatch( base: Record, patch: Record, ): Record { return Object.keys(patch).reduce( (acc, k) => { return base[k] == patch[k] || (isPlainObject(base[k]) && isPlainObject(patch[k]) && shallowequal(base[k], patch[k])) || R.equals(base[k], patch[k]) ? acc : { ...acc, [k]: patch[k] }; }, {} as Record, ); } /** * 由于 {1: {}}中的1 ,无法判别是 number 还是string , 因此程序统一使用正则匹配 * 1 => number * 'a' => string */ export function getTypedId(id: string) { return /^\d+$/.test(id) ? parseInt(id) : id; } // 根据dataType, 获取cell.value export function getValue(value: string, dataType: string | undefined) { if (dataType === 'number') { return value ? parseFloat(value) : 0; } return value; } export function getAncestors(rowId: ID, treeContext: IStoreState['treeContext']): ID[] { let result: ID[] = []; let parentId = rowId; while (parentId !== RootNodeId) { if (R.isNil(parentId)) throw new Error('parentId 不能是 nil'); parentId = treeContext[parentId].parentId; result.unshift(parentId); } return result; } export function isNumberStr(s: any) { if (s === null || s === undefined) return false; return /^[0-9]+.{0,1}[0-9]*?$/.test(s.toString()); }