78 lines
2.1 KiB
TypeScript
78 lines
2.1 KiB
TypeScript
import _ from 'lodash';
|
|
|
|
export function filterByFields(data: any, fields: any = {}): any {
|
|
if (data == null) {
|
|
return data;
|
|
}
|
|
|
|
const {
|
|
only = Array.isArray(fields) ? fields : null,
|
|
except = []
|
|
} = fields;
|
|
|
|
// ['user.profile.age', 'user.status', 'user', 'title', 'status']
|
|
// to
|
|
// {
|
|
// user: {
|
|
// profile: { age: true },
|
|
// status: true
|
|
// },
|
|
// title: true,
|
|
// status: true
|
|
// }
|
|
//
|
|
function makeMap(array: string[]) {
|
|
const map = {};
|
|
array.forEach(key => {
|
|
_.set(map, key, true);
|
|
});
|
|
|
|
return map;
|
|
}
|
|
|
|
const onlyMap = only ? makeMap(only) : null;
|
|
const exceptMap = makeMap(except);
|
|
|
|
function filter(value, { onlyMap, exceptMap }: { onlyMap?: any, exceptMap?: any }) {
|
|
const isArray = Array.isArray(value);
|
|
const values = isArray ? value : [value];
|
|
|
|
const results = values.map(v => {
|
|
const result = {};
|
|
Object.keys(v).forEach(key => {
|
|
// 未定义 except 时继续判断 only
|
|
if (!exceptMap || typeof exceptMap[key] === 'undefined') {
|
|
if (onlyMap) {
|
|
if (typeof onlyMap[key] !== 'undefined') {
|
|
// 防止 fields 参数和传入类型不匹配时的报错
|
|
if (onlyMap[key] === true || typeof v[key] !== 'object') {
|
|
result[key] = v[key];
|
|
} else {
|
|
result[key] = filter(v[key], { onlyMap: onlyMap[key] });
|
|
}
|
|
}
|
|
} else {
|
|
result[key] = v[key];
|
|
}
|
|
} else {
|
|
// 定义了 except 子级
|
|
if (typeof exceptMap[key] === 'object' && typeof v[key] === 'object') {
|
|
result[key] = filter(v[key], {
|
|
// onlyMap[key] === true 或不存在时,对子级只考虑 except
|
|
onlyMap: onlyMap && typeof onlyMap[key] === 'object' ? onlyMap[key] : null,
|
|
exceptMap: exceptMap[key]
|
|
});
|
|
}
|
|
// 其他情况直接跳过
|
|
}
|
|
});
|
|
|
|
return result;
|
|
});
|
|
|
|
return isArray ? results : results[0];
|
|
}
|
|
|
|
return filter(data, { onlyMap, exceptMap });
|
|
}
|