Merge pull request #11221 from 2betop/chore-frontend-fitlter

fix: 修复前端一次性加载前端过滤必须配置 matchFunc 的问题
This commit is contained in:
hsm-lv 2024-11-22 09:53:35 +08:00 committed by GitHub
commit 5abaddf8d8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 44 additions and 102 deletions

View File

@ -209,6 +209,8 @@ export const CRUDStore = ServiceStore.named('CRUDStore')
loadDataMode?: boolean; loadDataMode?: boolean;
syncResponse2Query?: boolean; syncResponse2Query?: boolean;
columns?: Array<any>; columns?: Array<any>;
matchFunc?: MatchFunc;
filterOnAllColumns?: boolean; // 前端是否让所有字段参与过滤
isTable2?: Boolean; // 是否是 CRUD2 isTable2?: Boolean; // 是否是 CRUD2
} }
) => Promise<any> = flow(function* getInitData( ) => Promise<any> = flow(function* getInitData(
@ -222,26 +224,30 @@ export const CRUDStore = ServiceStore.named('CRUDStore')
syncResponse2Query?: boolean; syncResponse2Query?: boolean;
columns?: Array<any>; columns?: Array<any>;
matchFunc?: MatchFunc; matchFunc?: MatchFunc;
filterOnAllColumns?: boolean; // 前端是否让所有字段参与过滤
} = {} } = {}
) { ) {
try { try {
if (!options.forceReload && options.loadDataOnce && self.total) { let rawItems = options.source
? resolveVariableAndFilter(
options.source,
createObject(self.mergedData, {
items: self.data.itemsRaw,
rows: self.data.itemsRaw
}),
'| raw'
)
: self.items.concat();
if (!options.forceReload && options.loadDataOnce && rawItems?.length) {
const matchFunc = options.matchFunc; const matchFunc = options.matchFunc;
let items = options.source let items = rawItems;
? resolveVariableAndFilter(
options.source,
createObject(self.mergedData, {
items: self.data.itemsRaw,
rows: self.data.itemsRaw
}),
'| raw'
)
: self.items.concat();
items = applyFilters(items, { items = applyFilters(items, {
query: self.query, query: self.query,
columns: options.columns, columns: options.columns,
matchFunc: matchFunc matchFunc: matchFunc,
filterOnAllColumns: options.filterOnAllColumns
}); });
if (self.query.orderBy) { if (self.query.orderBy) {
@ -380,43 +386,12 @@ export const CRUDStore = ServiceStore.named('CRUDStore')
* 2. items rows * 2. items rows
*/ */
data.itemsRaw = oItems || oRows || rowsData.concat(); data.itemsRaw = oItems || oRows || rowsData.concat();
let filteredItems = rowsData.concat(); let filteredItems = applyFilters(rowsData, {
query: self.query,
if (Array.isArray(options.columns)) { columns: options.columns,
options.columns.forEach((column: any) => { filterOnAllColumns: false,
let value: any; matchFunc: options.matchFunc
const key = column.name; });
if (
column.searchable &&
key &&
(value = getVariable(self.query, key))
) {
if (Array.isArray(value)) {
if (value.length > 0) {
const arr = [...filteredItems];
let arrItems: Array<any> = [];
value.forEach(item => {
arrItems = [
...arrItems,
...matchSorter(arr, item, {
keys: [key],
threshold: matchSorter.rankings.CONTAINS
})
];
});
filteredItems = filteredItems.filter(item =>
arrItems.find(a => a === item)
);
}
} else {
filteredItems = matchSorter(filteredItems, value, {
keys: [key],
threshold: matchSorter.rankings.CONTAINS
});
}
}
});
}
if (self.query.orderBy) { if (self.query.orderBy) {
const dir = /desc/i.test(self.query.orderDir) ? -1 : 1; const dir = /desc/i.test(self.query.orderDir) ? -1 : 1;
@ -642,65 +617,22 @@ export const CRUDStore = ServiceStore.named('CRUDStore')
matchFunc?: MatchFunc | null; matchFunc?: MatchFunc | null;
} }
) { ) {
const matchFunc = options.matchFunc;
let items: Array<any> = resolveVariableAndFilter(source, scope, '| raw'); let items: Array<any> = resolveVariableAndFilter(source, scope, '| raw');
if (!Array.isArray(items) && !self.items.length) { if (!Array.isArray(items) && !self.items.length) {
return; return;
} }
items = Array.isArray(items) ? items : []; items = applyFilters(Array.isArray(items) ? items : [], {
query: self.query,
/** 字段的格式类型无法穷举,所以支持使用函数过滤 */ columns: options.columns,
if (matchFunc && typeof matchFunc === 'function') { matchFunc: options.matchFunc,
items = matchFunc(items, items.concat(), { filterOnAllColumns: true
query: self.query, });
columns: options.columns,
matchSorter: matchSorter
});
} else {
if (Array.isArray(options.columns)) {
options.columns.forEach((column: any) => {
let value: any =
typeof column.name === 'string'
? getVariable(self.query, column.name)
: undefined;
const key = column.name;
if (value != null && key) {
// value可能为null、undefined、''、0
if (Array.isArray(value)) {
if (value.length > 0) {
const arr = [...items];
let arrItems: Array<any> = [];
/** 搜索 query 值为数组的情况 */
value.forEach(item => {
arrItems = [
...arrItems,
...matchSorter(arr, item, {
keys: [key],
threshold: matchSorter.rankings.CONTAINS
})
];
});
items = items.filter((item: any) =>
arrItems.find(a => a === item)
);
}
} else {
items = matchSorter(items, value, {
keys: [key],
threshold: matchSorter.rankings.CONTAINS
});
}
}
});
}
}
if (self.query.orderBy) { if (self.query.orderBy) {
const dir = /desc/i.test(self.query.orderDir) ? -1 : 1; const dir = /desc/i.test(self.query.orderDir) ? -1 : 1;
items = sortArray(items, self.query.orderBy, dir); items = sortArray(items.concat(), self.query.orderBy, dir);
} }
const data = { const data = {

View File

@ -1503,7 +1503,8 @@ export function applyFilters<T extends any>(
options: { options: {
query: any; query: any;
columns?: Array<any>; columns?: Array<any>;
matchFunc?: Function; matchFunc?: Function | null;
filterOnAllColumns?: boolean;
} }
) { ) {
if (options.matchFunc && typeof options.matchFunc === 'function') { if (options.matchFunc && typeof options.matchFunc === 'function') {
@ -1517,7 +1518,13 @@ export function applyFilters<T extends any>(
: undefined; : undefined;
const key = column.name; const key = column.name;
if (value != null && key) { if (
(options.filterOnAllColumns ||
column.searchable ||
column.filterable) &&
key &&
value != null
) {
// value可能为null、undefined、''、0 // value可能为null、undefined、''、0
if (Array.isArray(value)) { if (Array.isArray(value)) {
if (value.length > 0) { if (value.length > 0) {

View File

@ -1284,6 +1284,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
pickerMode, pickerMode,
env, env,
loadDataOnce, loadDataOnce,
loadDataOnceFetchOnFilter,
source, source,
columns, columns,
dispatchEvent dispatchEvent
@ -1335,7 +1336,8 @@ export default class CRUD extends React.Component<CRUDProps, any> {
loadDataMode, loadDataMode,
syncResponse2Query, syncResponse2Query,
columns: store.columns ?? columns, columns: store.columns ?? columns,
matchFunc matchFunc,
filterOnAllColumns: loadDataOnceFetchOnFilter === false
}); });
if (!isAlive(store)) { if (!isAlive(store)) {
return value; return value;
@ -1362,6 +1364,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
// 空列表 且 页数已经非法超出,则跳转到最后的合法页数 // 空列表 且 页数已经非法超出,则跳转到最后的合法页数
if ( if (
!loadDataOnce &&
!store.data.items.length && !store.data.items.length &&
!interval && !interval &&
page > 1 && page > 1 &&