add base service
This commit is contained in:
parent
6f581ad383
commit
3fa9ecc33a
@ -60,6 +60,6 @@ export class CategoryController {
|
||||
@Delete(':id')
|
||||
@SerializeOptions({ groups: ['category-detail'] })
|
||||
async delete(@Param('id', new ParseUUIDPipe()) id: string) {
|
||||
return this.service.delete(id);
|
||||
return this.service.delete([id]);
|
||||
}
|
||||
}
|
||||
|
@ -2,33 +2,23 @@ import { Injectable } from '@nestjs/common';
|
||||
import { isNil, omit } from 'lodash';
|
||||
import { EntityNotFoundError } from 'typeorm';
|
||||
|
||||
import {
|
||||
CreateCategoryDto,
|
||||
QueryCategoryDto,
|
||||
UpdateCategoryDto,
|
||||
} from '@/modules/content/dtos/category.dto';
|
||||
import { CreateCategoryDto, UpdateCategoryDto } from '@/modules/content/dtos/category.dto';
|
||||
import { CategoryEntity } from '@/modules/content/entities/category.entity';
|
||||
import { CategoryRepository } from '@/modules/content/repositories/category.repository';
|
||||
import { treePaginate } from '@/modules/database/utils';
|
||||
import { BaseService } from '@/modules/database/base/service';
|
||||
|
||||
@Injectable()
|
||||
export class CategoryService {
|
||||
constructor(protected repository: CategoryRepository) {}
|
||||
export class CategoryService extends BaseService<CategoryEntity, CategoryRepository> {
|
||||
protected enableTrash = true;
|
||||
|
||||
constructor(protected repository: CategoryRepository) {
|
||||
super(repository);
|
||||
}
|
||||
|
||||
async findTrees() {
|
||||
return this.repository.findTrees();
|
||||
}
|
||||
|
||||
async paginate(options?: QueryCategoryDto) {
|
||||
const tree = await this.findTrees();
|
||||
const data = await this.repository.toFlatTrees(tree);
|
||||
return treePaginate(options, data);
|
||||
}
|
||||
|
||||
async detail(id: string) {
|
||||
return this.repository.findOneOrFail({ where: { id }, relations: ['parent', 'children'] });
|
||||
}
|
||||
|
||||
async create(data: CreateCategoryDto) {
|
||||
const item = await this.repository.save({
|
||||
...data,
|
||||
@ -56,21 +46,6 @@ export class CategoryService {
|
||||
return item;
|
||||
}
|
||||
|
||||
async delete(id: string) {
|
||||
const item = await this.repository.findOneOrFail({
|
||||
where: { id },
|
||||
relations: ['parent', 'children'],
|
||||
});
|
||||
if (!isNil(item.children) && item.children.length > 0) {
|
||||
const childrenCategories = [...item.children].map((c) => {
|
||||
c.parent = item.parent;
|
||||
return item;
|
||||
});
|
||||
await this.repository.save(childrenCategories, { reload: true });
|
||||
}
|
||||
return this.repository.remove(item);
|
||||
}
|
||||
|
||||
async getParent(current?: string, parentId?: string) {
|
||||
if (current === parentId) {
|
||||
return undefined;
|
||||
|
@ -11,14 +11,14 @@ import {
|
||||
} from '@/modules/content/dtos/comment.dto';
|
||||
import { CommentEntity } from '@/modules/content/entities/comment.entity';
|
||||
import { CommentRepository, PostRepository } from '@/modules/content/repositories';
|
||||
import { BaseService } from '@/modules/database/base/service';
|
||||
import { treePaginate } from '@/modules/database/utils';
|
||||
|
||||
@Injectable()
|
||||
export class CommentService {
|
||||
constructor(
|
||||
protected repository: CommentRepository,
|
||||
protected postRepository: PostRepository,
|
||||
) {}
|
||||
export class CommentService extends BaseService<CommentEntity, CommentRepository> {
|
||||
constructor(protected repository: CommentRepository, protected postRepository: PostRepository) {
|
||||
super(repository);
|
||||
}
|
||||
|
||||
async findTrees(options: QueryCommentTreeDto = {}) {
|
||||
return this.repository.findTrees({
|
||||
@ -91,4 +91,8 @@ export class CommentService {
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
update(data: any, ...others: any[]): Promise<CommentEntity> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import { CategoryRepository } from '@/modules/content/repositories';
|
||||
import { PostRepository } from '@/modules/content/repositories/post.repository';
|
||||
import { SearchService } from '@/modules/content/services/search.service';
|
||||
import { SearchType } from '@/modules/content/types';
|
||||
import { BaseService } from '@/modules/database/base/service';
|
||||
import { SelectTrashMode } from '@/modules/database/constants';
|
||||
import { QueryHook } from '@/modules/database/types';
|
||||
import { paginate } from '@/modules/database/utils';
|
||||
@ -24,7 +25,9 @@ type FindParams = {
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class PostService {
|
||||
export class PostService extends BaseService<PostEntity, PostRepository, FindParams> {
|
||||
protected enableTrash = true;
|
||||
|
||||
constructor(
|
||||
protected repository: PostRepository,
|
||||
protected categoryRepository: CategoryRepository,
|
||||
@ -32,13 +35,15 @@ export class PostService {
|
||||
protected tagRepository: TagRepository,
|
||||
protected searchService?: SearchService,
|
||||
protected searchType: SearchType = 'mysql',
|
||||
) {}
|
||||
) {
|
||||
super(repository);
|
||||
}
|
||||
|
||||
async paginate(options: QueryPostDto, callback?: QueryHook<PostEntity>) {
|
||||
if (!isNil(this.searchService) && !isNil(options.search) && this.searchType === 'meili') {
|
||||
return this.searchService.search(
|
||||
options.search,
|
||||
pick(options, ['trashed', 'page', 'limit']),
|
||||
pick(options, ['trashed', 'page', 'limit', 'isPublished']),
|
||||
);
|
||||
}
|
||||
const qb = await this.buildListQuery(this.repository.buildBaseQB(), options, callback);
|
||||
|
@ -47,7 +47,7 @@ export class SearchService implements OnModuleInit {
|
||||
return this.client;
|
||||
}
|
||||
|
||||
async search(text: string, param: SearchOption = {}) {
|
||||
async search(text: string, param: SearchOption = {}): Promise<any> {
|
||||
const option = { page: 1, limit: 10, trashed: SelectTrashMode.ONLY, ...param };
|
||||
const limit = isNil(option.limit) || option.limit < 1 ? 1 : option.limit;
|
||||
const page = isNil(option.page) || option.page < 1 ? 1 : option.page;
|
||||
|
@ -1,19 +1,18 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { omit } from 'lodash';
|
||||
|
||||
import { In } from 'typeorm';
|
||||
|
||||
import { CreateTagDto, QueryTagDto, UpdateTagDto } from '@/modules/content/dtos/tag.dto';
|
||||
import { CreateTagDto, UpdateTagDto } from '@/modules/content/dtos/tag.dto';
|
||||
import { TagRepository } from '@/modules/content/repositories/tag.repository';
|
||||
import { paginate } from '@/modules/database/utils';
|
||||
import { BaseService } from '@/modules/database/base/service';
|
||||
|
||||
import { TagEntity } from '../entities';
|
||||
|
||||
@Injectable()
|
||||
export class TagService {
|
||||
constructor(protected repository: TagRepository) {}
|
||||
export class TagService extends BaseService<TagEntity, TagRepository> {
|
||||
protected enableTrash = true;
|
||||
|
||||
async paginate(options: QueryTagDto) {
|
||||
const qb = this.repository.buildBaseQB();
|
||||
return paginate(qb, options);
|
||||
constructor(protected repository: TagRepository) {
|
||||
super(repository);
|
||||
}
|
||||
|
||||
async detail(id: string) {
|
||||
@ -31,11 +30,4 @@ export class TagService {
|
||||
await this.repository.update(data.id, omit(data, ['id']));
|
||||
return this.detail(data.id);
|
||||
}
|
||||
|
||||
async delete(ids: string[]) {
|
||||
const items = await this.repository.find({
|
||||
where: { id: In(ids) },
|
||||
});
|
||||
return this.repository.remove(items);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { NotFoundException } from '@nestjs/common';
|
||||
import { ForbiddenException, NotFoundException } from '@nestjs/common';
|
||||
import { isNil } from 'lodash';
|
||||
import { In, ObjectLiteral, SelectQueryBuilder } from 'typeorm';
|
||||
|
||||
@ -127,4 +127,29 @@ export abstract class BaseService<
|
||||
}
|
||||
return this.repository.remove(items);
|
||||
}
|
||||
|
||||
async restore(ids: string[]) {
|
||||
if (!this.enableTrash) {
|
||||
throw new ForbiddenException(
|
||||
`Can not to retore ${this.repository.qbName},because trash not enabled!`,
|
||||
);
|
||||
}
|
||||
const items = await this.repository.find({
|
||||
where: { id: In(ids) as any },
|
||||
withDeleted: true,
|
||||
});
|
||||
const trashIds = items.filter((o) => !isNil(o.deletedAt)).map((o) => o.id);
|
||||
if (trashIds.length < 1) {
|
||||
return [];
|
||||
}
|
||||
await this.repository.restore(trashIds);
|
||||
const qb = await this.buildListQB(this.repository.buildBaseQB(), undefined, async (_) =>
|
||||
_.andWhereInIds(trashIds),
|
||||
);
|
||||
return qb.getMany();
|
||||
}
|
||||
|
||||
abstract create(data: any, ...others: any[]): Promise<T>;
|
||||
|
||||
abstract update(data: any, ...others: any[]): Promise<T>;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user