mirror of
https://gitee.com/nocobase/nocobase.git
synced 2024-12-04 05:08:42 +08:00
refactor(linkage-rule): linkage rules condition support toMany association fields (#1924)
* refactor: linkage rule support to many association field * refactor: linkage rule support toMany * fix: support toMany association field * fix: support toMany association field * fix: operator support toMany association field * refactor: useLinkageCollectionFilterOptions
This commit is contained in:
parent
4296db5859
commit
c0f9c8116a
@ -203,7 +203,7 @@ export const useCollectionFilterOptions = (collectionName: string) => {
|
||||
|
||||
export const useLinkageCollectionFilterOptions = (collectionName: string) => {
|
||||
const { getCollectionFields, getInterface } = useCollectionManager();
|
||||
const fields = getCollectionFields(collectionName).filter((v) => !['o2m', 'm2m'].includes(v.interface));
|
||||
const fields = getCollectionFields(collectionName);
|
||||
const field2option = (field, depth) => {
|
||||
if (!field.interface) {
|
||||
return;
|
||||
@ -233,7 +233,12 @@ export const useLinkageCollectionFilterOptions = (collectionName: string) => {
|
||||
option['children'] = children;
|
||||
}
|
||||
if (nested) {
|
||||
const targetFields = getCollectionFields(field.target).filter((v) => !['o2m', 'm2m'].includes(v.interface));
|
||||
const targetFields = getCollectionFields(field.target).filter((v) => {
|
||||
if (['hasMany', 'belongsToMany'].includes(field.type)) {
|
||||
return !['hasOne', 'hasMany', 'belongsTo', 'belongsToMany'].includes(v.type);
|
||||
}
|
||||
return !['hasMany', 'belongsToMany'].includes(v.type);
|
||||
});
|
||||
const options = getOptions(targetFields, depth + 1).filter(Boolean);
|
||||
option['children'] = option['children'] || [];
|
||||
option['children'].push(...options);
|
||||
|
@ -35,6 +35,9 @@ http://ricostacruz.com/cheatsheets/umdjs.html
|
||||
}
|
||||
return a;
|
||||
}
|
||||
function areArraysEqual(arr1, arr2) {
|
||||
return JSON.stringify(arr1) === JSON.stringify(arr2);
|
||||
}
|
||||
|
||||
var jsonLogic = {};
|
||||
var operations = {
|
||||
@ -42,9 +45,18 @@ http://ricostacruz.com/cheatsheets/umdjs.html
|
||||
return a === b;
|
||||
},
|
||||
$match: function (a, b) {
|
||||
if (Array.isArray(a) && Array.isArray(b) && a.some((element) => Array.isArray(element))) {
|
||||
return a.some(
|
||||
(subArray) => subArray?.length === b.length && subArray?.every((element, index) => element === b[index]),
|
||||
);
|
||||
}
|
||||
return JSON.stringify(a) === JSON.stringify(b);
|
||||
},
|
||||
$eq: function (a, b) {
|
||||
if (Array.isArray(a) && Array.isArray(b)) return areArraysEqual(a, b);
|
||||
if (Array.isArray(a)) {
|
||||
return a.includes(b);
|
||||
}
|
||||
return a === b;
|
||||
},
|
||||
$ne: function (a, b) {
|
||||
@ -54,12 +66,14 @@ http://ricostacruz.com/cheatsheets/umdjs.html
|
||||
return a !== b;
|
||||
},
|
||||
$gt: function (a, b) {
|
||||
if (Array.isArray(a)) return a.some((k) => k > b);
|
||||
return a > b;
|
||||
},
|
||||
$gte: function (a, b) {
|
||||
return a >= b;
|
||||
},
|
||||
$lt: function (a, b, c) {
|
||||
if (Array.isArray(a)) return a.some((k) => k < b);
|
||||
return c === undefined ? a < b : a < b && b < c;
|
||||
},
|
||||
$lte: function (a, b, c) {
|
||||
@ -72,6 +86,7 @@ http://ricostacruz.com/cheatsheets/umdjs.html
|
||||
return jsonLogic.truthy(a);
|
||||
},
|
||||
$empty: function (a) {
|
||||
if (Array.isArray(a)) return a.some((k) => !jsonLogic.truthy(k));
|
||||
return !jsonLogic.truthy(a);
|
||||
},
|
||||
$notExists: function (a) {
|
||||
@ -86,6 +101,9 @@ http://ricostacruz.com/cheatsheets/umdjs.html
|
||||
},
|
||||
$in: function (a, b) {
|
||||
if (!b || typeof b.indexOf === 'undefined') return false;
|
||||
if (Array.isArray(a) && Array.isArray(b)) {
|
||||
return b.some((elementB) => a.includes(elementB));
|
||||
}
|
||||
return b.indexOf(a) !== -1;
|
||||
},
|
||||
$notIn: function (a, b) {
|
||||
@ -94,22 +112,30 @@ http://ricostacruz.com/cheatsheets/umdjs.html
|
||||
},
|
||||
$includes: function (a, b) {
|
||||
if (!a || typeof a.indexOf === 'undefined') return false;
|
||||
if (Array.isArray(a)) return a.some((element) => element?.includes(b));
|
||||
return a.indexOf(b) !== -1;
|
||||
},
|
||||
$notIncludes: function (a, b) {
|
||||
if (!a || typeof a.indexOf === 'undefined') return false;
|
||||
if (Array.isArray(a)) return !a.some((element) => element.includes(b));
|
||||
return !(a.indexOf(b) !== -1);
|
||||
},
|
||||
$anyOf: function (a, b) {
|
||||
if (a.length === 0) {
|
||||
return false;
|
||||
}
|
||||
return b.every((item) => a.includes(item));
|
||||
if (Array.isArray(a) && Array.isArray(b) && a.some((element) => Array.isArray(element))) {
|
||||
return a.some((subArray) => subArray.some((element) => b.includes(element)));
|
||||
}
|
||||
return a.some((element) => b.includes(element));
|
||||
},
|
||||
$noneOf: function (a, b) {
|
||||
if (a.length === 0) {
|
||||
return true;
|
||||
}
|
||||
if (Array.isArray(a) && Array.isArray(b) && a.some((element) => Array.isArray(element))) {
|
||||
return a.some((subArray) => subArray.every((element) => !b.some((bElement) => element.includes(bElement))));
|
||||
}
|
||||
return b.some((item) => !a.includes(item));
|
||||
},
|
||||
$notMatch: function (a, b) {
|
||||
@ -125,9 +151,11 @@ http://ricostacruz.com/cheatsheets/umdjs.html
|
||||
return false;
|
||||
},
|
||||
$isTruly: function (a) {
|
||||
if (Array.isArray(a)) return a.some((k) => k === true || k === 1);
|
||||
return a === true || a === 1;
|
||||
},
|
||||
$isFalsy: function (a) {
|
||||
if (Array.isArray(a)) return a.some((k) => !jsonLogic.truthy(k));
|
||||
return !jsonLogic.truthy(a);
|
||||
},
|
||||
cat: function () {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import flat from 'flat';
|
||||
import _, { every, findIndex, some } from 'lodash';
|
||||
import _, { every, findIndex, some, isArray } from 'lodash';
|
||||
import moment from 'moment';
|
||||
import { useCurrentUserContext } from '../../../user';
|
||||
import jsonLogic from '../../common/utils/logic';
|
||||
@ -57,11 +57,25 @@ function getInnermostKeyAndValue(obj) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const getFieldValue = (fieldPath, values) => {
|
||||
const v = fieldPath[0];
|
||||
const h = fieldPath[1];
|
||||
const regex = new RegExp('^' + v + '\\..+\\.' + h + '$'); // 构建匹配的正则表达式
|
||||
const matchedValues = [];
|
||||
const data = flat.flatten(values, { maxDepth: 3 });
|
||||
for (var key in data) {
|
||||
if (regex.test(key)) {
|
||||
matchedValues.push(data[key]);
|
||||
}
|
||||
}
|
||||
return matchedValues;
|
||||
};
|
||||
|
||||
const getValue = (str: string, values) => {
|
||||
const regex = /{{(.*?)}}/;
|
||||
const matches = str?.match?.(regex);
|
||||
if (matches) {
|
||||
return getVariableValue(str, flat(values));
|
||||
return getVariableValue(str, values);
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
@ -69,7 +83,14 @@ const getValue = (str: string, values) => {
|
||||
const getVariableValue = (str, values) => {
|
||||
const regex = /{{[^.]+\.([^}]+)}}/;
|
||||
const match = regex.exec(str);
|
||||
return values[match?.[1]];
|
||||
const targetField = match?.[1]?.split('.') || [];
|
||||
const isArrayField = isArray(values[targetField[0]]);
|
||||
if (isArrayField && targetField.length > 1) {
|
||||
//对多关系字段
|
||||
return getFieldValue(targetField, values);
|
||||
} else {
|
||||
return flat(values)[match?.[1]];
|
||||
}
|
||||
};
|
||||
const getTargetField = (obj) => {
|
||||
const keys = getAllKeys(obj);
|
||||
@ -110,9 +131,17 @@ export const conditionAnalyse = (rules, values) => {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
const currentValue = targetField.length > 1 ? flat(values)?.[targetField.join('.')] : values?.[targetField[0]];
|
||||
const result = jsonLogic.apply({ [operator]: [currentValue, value] });
|
||||
return result;
|
||||
const isArrayField = isArray(values[targetField[0]]);
|
||||
if (isArrayField && targetField.length > 1) {
|
||||
//对多关系字段比较
|
||||
const currentValue = getFieldValue(targetField, values);
|
||||
const result = jsonLogic.apply({ [operator]: [currentValue, value] });
|
||||
return result;
|
||||
} else {
|
||||
const currentValue = targetField.length > 1 ? flat(values)?.[targetField.join('.')] : values?.[targetField[0]];
|
||||
const result = jsonLogic.apply({ [operator]: [currentValue, value] });
|
||||
return result;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user