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