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 { Context } from '..';
|
||||||
import { getRepositoryFromParams, pageArgsToLimitArgs } from '../utils';
|
import { getRepositoryFromParams, pageArgsToLimitArgs } from '../utils';
|
||||||
import { DEFAULT_PAGE, DEFAULT_PER_PAGE } from '../constants';
|
import { DEFAULT_PAGE, DEFAULT_PER_PAGE } from '../constants';
|
||||||
|
import { QueryTypes } from 'sequelize';
|
||||||
|
|
||||||
function totalPage(total, pageSize): number {
|
function totalPage(total, pageSize): number {
|
||||||
return Math.ceil(total / pageSize);
|
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 { page = DEFAULT_PAGE, pageSize = DEFAULT_PER_PAGE } = ctx.action.params;
|
||||||
|
|
||||||
const repository = getRepositoryFromParams(ctx);
|
const repository = getRepositoryFromParams(ctx);
|
||||||
|
const resourceName = ctx.action.resourceName;
|
||||||
|
const collection = ctx.db.getCollection(resourceName);
|
||||||
const options = {
|
const options = {
|
||||||
context: ctx,
|
context: ctx,
|
||||||
...findArgs(ctx),
|
...findArgs(ctx),
|
||||||
@ -40,12 +42,89 @@ async function listWithPagination(ctx: Context) {
|
|||||||
delete options[key];
|
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);
|
const [rows, count] = await repository.findAndCount(options);
|
||||||
|
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
count,
|
count,
|
||||||
rows,
|
rows: filterTreeData.length ? filterTreeData : rows,
|
||||||
page: Number(page),
|
page: Number(page),
|
||||||
pageSize: Number(pageSize),
|
pageSize: Number(pageSize),
|
||||||
totalPage: totalPage(count, pageSize),
|
totalPage: totalPage(count, pageSize),
|
||||||
|
Loading…
Reference in New Issue
Block a user