feat: 支持级联范围过滤

Reviewed-on: daoyoucloud/tachycode#603
Co-authored-by: hello@lv <2256334253@qq.com>
Co-committed-by: hello@lv <2256334253@qq.com>
This commit is contained in:
hello@lv 2024-04-07 14:59:50 +08:00 committed by sealday
parent 9331bf3c6d
commit 38c3e3db8d
2 changed files with 87 additions and 3 deletions

View File

@ -0,0 +1,5 @@
---
"@hera/plugin-rental": patch
---
树形结构筛选

View File

@ -2,6 +2,7 @@ import { assign } from '@nocobase/utils';
import { Context } from '..';
import { getRepositoryFromParams, pageArgsToLimitArgs } from '../utils';
import { DEFAULT_PAGE, DEFAULT_PER_PAGE } from '../constants';
import { QueryTypes } from 'sequelize';
function totalPage(total, pageSize): number {
return Math.ceil(total / pageSize);
@ -28,7 +29,8 @@ async function listWithPagination(ctx: Context) {
const { page = DEFAULT_PAGE, pageSize = DEFAULT_PER_PAGE } = ctx.action.params;
const repository = getRepositoryFromParams(ctx);
const resourceName = ctx.action.resourceName;
const collection = ctx.db.getCollection(resourceName);
const options = {
context: ctx,
...findArgs(ctx),
@ -40,12 +42,89 @@ async function listWithPagination(ctx: Context) {
delete options[key];
}
});
let filterTreeData = [];
if (ctx.action.params.tree) {
const foreignKey = collection.treeParentField?.foreignKey || 'parentId';
const params = Object.values(options.filter).flat()[0] || {};
let dataId: any;
if (Object.entries(params).length) {
const getParent = async (filter = {}) => {
const data = await repository.findOne({
filter: filter,
});
dataId = data.id;
};
await getParent(params);
const filterTreeDatas = await ctx.db.sequelize.query(
`
WITH RECURSIVE tree1 AS (
SELECT *
FROM ${collection.name}
WHERE id = :dataId
UNION ALL
SELECT p.*
FROM tree1 up
JOIN ${collection.name} p ON up."${foreignKey}" = p.id
),
tree2 AS (
SELECT *
FROM ${collection.name}
WHERE id = :dataId
UNION ALL
SELECT p.*
FROM tree2 down
JOIN ${collection.name} p ON down.id = p."${foreignKey}"
)
SELECT DISTINCT *
FROM (
SELECT *
FROM tree1
UNION ALL
SELECT *
FROM tree2
)
`,
{
replacements: {
dataId,
},
type: QueryTypes.SELECT,
},
);
const newRows: any[] = filterTreeDatas;
const father = newRows.filter((parent) => parent.parentId === null);
const transTreeData = (father, allRows) => {
father.forEach((parent, index) => {
const children = allRows.filter((child) => child.parentId === parent.id);
const i = index.toString();
parent.__index = parent.father || parent.father == '0' ? parent.father + '.children.' + i : i;
if (children?.length) {
const transChild = children.map((child) => {
return {
...child,
father: parent.__index,
};
});
parent.children = transChild;
}
if (parent.children?.length) {
transTreeData(parent.children, allRows);
}
});
};
transTreeData(father, newRows);
filterTreeData = father;
}
}
const [rows, count] = await repository.findAndCount(options);
ctx.body = {
count,
rows,
rows: filterTreeData.length ? filterTreeData : rows,
page: Number(page),
pageSize: Number(pageSize),
totalPage: totalPage(count, pageSize),