From 3f0a9ca6fb14d272e87092e17032368464c4da9b Mon Sep 17 00:00:00 2001 From: liuyi Date: Tue, 3 Jun 2025 14:29:58 +0800 Subject: [PATCH] add base repository --- .../repositories/category.repository.ts | 59 +++------------ .../repositories/comment.repository.ts | 71 +++---------------- .../content/services/comment.service.ts | 4 +- 3 files changed, 24 insertions(+), 110 deletions(-) diff --git a/src/modules/content/repositories/category.repository.ts b/src/modules/content/repositories/category.repository.ts index 5b7e995..4ae8dac 100644 --- a/src/modules/content/repositories/category.repository.ts +++ b/src/modules/content/repositories/category.repository.ts @@ -1,21 +1,23 @@ -import { isNil, pick, unset } from 'lodash'; -import { FindOptionsUtils, FindTreeOptions, TreeRepository, TreeRepositoryUtils } from 'typeorm'; +import { isNil, unset } from 'lodash'; +import { FindOptionsUtils, FindTreeOptions, TreeRepositoryUtils } from 'typeorm'; import { CategoryEntity } from '@/modules/content/entities/category.entity'; +import { BaseTreeRepository } from '@/modules/database/base/tree.repository'; +import { OrderType, TreeChildrenResolve } from '@/modules/database/constants'; import { CustomRepository } from '@/modules/database/decorators/repository.decorator'; @CustomRepository(CategoryEntity) -export class CategoryRepository extends TreeRepository { +export class CategoryRepository extends BaseTreeRepository { + protected _qbName = 'category'; + + protected orderBy = { name: 'customOrder', order: OrderType.ASC }; + + protected _childrenResolve = TreeChildrenResolve.UP; + buildBaseQB() { return this.createQueryBuilder('category').leftJoinAndSelect('category.parent', 'parent'); } - async findTrees(options?: FindTreeOptions) { - const roots = await this.findRoots(options); - await Promise.all(roots.map((root) => this.findDescendantsTree(root, options))); - return roots; - } - findRoots(options?: FindTreeOptions): Promise { const escape = (val: string) => this.manager.connection.driver.escape(val); const joinColumn = this.metadata.treeParentRelation!.joinColumns[0]; @@ -39,28 +41,6 @@ export class CategoryRepository extends TreeRepository { return qb.getMany(); } - async findDescendantsTree(entity: CategoryEntity, options?: FindTreeOptions) { - const qb = this.createDescendantsQueryBuilder('category', 'treeClosure', entity) - .leftJoinAndSelect('category.parent', 'parent') - .orderBy('category.customOrder', 'ASC'); - FindOptionsUtils.applyOptionsToTreeQueryBuilder(qb, pick(options, ['relations', 'depth'])); - const entities = await qb.getRawAndEntities(); - const relationMaps = TreeRepositoryUtils.createRelationMaps( - this.manager, - this.metadata, - 'category', - entities.raw, - ); - TreeRepositoryUtils.buildChildrenEntityTree( - this.metadata, - entity, - entities.entities, - relationMaps, - { depth: -1, ...pick(options, ['relations']) }, - ); - return entity; - } - async findAncestorsTree( entity: CategoryEntity, options?: FindTreeOptions, @@ -95,23 +75,6 @@ export class CategoryRepository extends TreeRepository { return qb.getCount(); } - async toFlatTrees( - trees: CategoryEntity[], - depth = 0, - parent: CategoryEntity | null = null, - ): Promise { - const data: Omit[] = []; - for (const item of trees) { - item.depth = depth; - item.parent = parent; - const { children } = item; - unset(item, 'children'); - data.push(item); - data.push(...(await this.toFlatTrees(children, depth + 1, item))); - } - return data as CategoryEntity[]; - } - async flatAncestorsTree(item: CategoryEntity) { let data: Omit[] = []; const category = await this.findAncestorsTree(item); diff --git a/src/modules/content/repositories/comment.repository.ts b/src/modules/content/repositories/comment.repository.ts index 4e1acac..de1ce6a 100644 --- a/src/modules/content/repositories/comment.repository.ts +++ b/src/modules/content/repositories/comment.repository.ts @@ -1,20 +1,17 @@ -import { pick, unset } from 'lodash'; -import { - FindOptionsUtils, - FindTreeOptions, - SelectQueryBuilder, - TreeRepository, - TreeRepositoryUtils, -} from 'typeorm'; +import { FindOptionsUtils, FindTreeOptions, SelectQueryBuilder } from 'typeorm'; import { CommentEntity } from '@/modules/content/entities/comment.entity'; +import { BaseTreeRepository } from '@/modules/database/base/tree.repository'; import { CustomRepository } from '@/modules/database/decorators/repository.decorator'; +import { QueryHook } from '@/modules/database/types'; type FindCommentTreeOptions = FindTreeOptions & { - addQuery?: (query: SelectQueryBuilder) => SelectQueryBuilder; + addQuery?: QueryHook; }; @CustomRepository(CommentEntity) -export class CommentRepository extends TreeRepository { +export class CommentRepository extends BaseTreeRepository { + protected _qbName = 'comment'; + buildBaseQB(qb: SelectQueryBuilder): SelectQueryBuilder { return qb .leftJoinAndSelect(`comment.parent`, 'parent') @@ -22,14 +19,7 @@ export class CommentRepository extends TreeRepository { .orderBy('comment.createdAt', 'DESC'); } - async findTrees(options: FindCommentTreeOptions): Promise { - options.relations = ['parent', 'children']; - const roots = await this.findRoots(options); - await Promise.all(roots.map((root) => this.findDescendantsTree(root, options))); - return roots; - } - - findRoots(options?: FindCommentTreeOptions): Promise { + async findRoots(options?: FindCommentTreeOptions): Promise { const { addQuery, ...rest } = options; const escape = (val: string) => this.manager.connection.driver.escape(val); const joinColumn = this.metadata.treeParentRelation!.joinColumns[0]; @@ -38,58 +28,19 @@ export class CommentRepository extends TreeRepository { let qb = this.buildBaseQB(this.createQueryBuilder('comment')); FindOptionsUtils.applyOptionsToTreeQueryBuilder(qb, rest); qb.where(`${escape('comment')}.${escape(parentPropertyName)} IS NULL`); - qb = addQuery ? addQuery(qb) : qb; + qb = addQuery ? await addQuery(qb) : qb; return qb.getMany(); } - createDtsQueryBuilder( + async createDtsQueryBuilder( closureTable: string, entity: CommentEntity, options: FindCommentTreeOptions = {}, - ): SelectQueryBuilder { + ): Promise> { const { addQuery } = options; const qb = this.buildBaseQB( super.createDescendantsQueryBuilder('comment', closureTable, entity), ); return addQuery ? addQuery(qb) : qb; } - - async findDescendantsTree( - entity: CommentEntity, - options: FindCommentTreeOptions = {}, - ): Promise { - const qb: SelectQueryBuilder = this.createDtsQueryBuilder( - 'treeClosure', - entity, - options, - ); - FindOptionsUtils.applyOptionsToTreeQueryBuilder(qb, pick(options, ['relations', 'depth'])); - const entities = await qb.getRawAndEntities(); - const relationMaps = TreeRepositoryUtils.createRelationMaps( - this.manager, - this.metadata, - 'comment', - entities.raw, - ); - TreeRepositoryUtils.buildChildrenEntityTree( - this.metadata, - entity, - entities.entities, - relationMaps, - { depth: -1, ...pick(options, ['relations']) }, - ); - return entity; - } - - async toFlatTrees(trees: CommentEntity[], depth = 0): Promise { - const data: Omit[] = []; - for (const item of trees) { - item.depth = depth; - const { children } = item; - unset(item, 'children'); - data.push(item); - data.push(...(await this.toFlatTrees(children, depth + 1))); - } - return data as CommentEntity[]; - } } diff --git a/src/modules/content/services/comment.service.ts b/src/modules/content/services/comment.service.ts index c17fec8..a131c8d 100644 --- a/src/modules/content/services/comment.service.ts +++ b/src/modules/content/services/comment.service.ts @@ -22,7 +22,7 @@ export class CommentService { async findTrees(options: QueryCommentTreeDto = {}) { return this.repository.findTrees({ - addQuery: (qb) => { + addQuery: async (qb) => { return isNil(options.post) ? qb : qb.where('post.id = :id', { id: options.post }); }, }); @@ -30,7 +30,7 @@ export class CommentService { async paginate(options: QueryCommentDto) { const { post, ...query } = options; - const addQuery = (qb: SelectQueryBuilder) => { + const addQuery = async (qb: SelectQueryBuilder) => { const condition: RecordString = {}; if (!isNil(post)) { condition.post = post;