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:
parent
9331bf3c6d
commit
38c3e3db8d
5
.changeset/spotty-meals-jump.md
Normal file
5
.changeset/spotty-meals-jump.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"@hera/plugin-rental": patch
|
||||
---
|
||||
|
||||
树形结构筛选
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user