add base service
This commit is contained in:
parent
6f581ad383
commit
3fa9ecc33a
@ -60,6 +60,6 @@ export class CategoryController {
|
|||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@SerializeOptions({ groups: ['category-detail'] })
|
@SerializeOptions({ groups: ['category-detail'] })
|
||||||
async delete(@Param('id', new ParseUUIDPipe()) id: string) {
|
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 { isNil, omit } from 'lodash';
|
||||||
import { EntityNotFoundError } from 'typeorm';
|
import { EntityNotFoundError } from 'typeorm';
|
||||||
|
|
||||||
import {
|
import { CreateCategoryDto, UpdateCategoryDto } from '@/modules/content/dtos/category.dto';
|
||||||
CreateCategoryDto,
|
|
||||||
QueryCategoryDto,
|
|
||||||
UpdateCategoryDto,
|
|
||||||
} from '@/modules/content/dtos/category.dto';
|
|
||||||
import { CategoryEntity } from '@/modules/content/entities/category.entity';
|
import { CategoryEntity } from '@/modules/content/entities/category.entity';
|
||||||
import { CategoryRepository } from '@/modules/content/repositories/category.repository';
|
import { CategoryRepository } from '@/modules/content/repositories/category.repository';
|
||||||
import { treePaginate } from '@/modules/database/utils';
|
import { BaseService } from '@/modules/database/base/service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CategoryService {
|
export class CategoryService extends BaseService<CategoryEntity, CategoryRepository> {
|
||||||
constructor(protected repository: CategoryRepository) {}
|
protected enableTrash = true;
|
||||||
|
|
||||||
|
constructor(protected repository: CategoryRepository) {
|
||||||
|
super(repository);
|
||||||
|
}
|
||||||
|
|
||||||
async findTrees() {
|
async findTrees() {
|
||||||
return this.repository.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) {
|
async create(data: CreateCategoryDto) {
|
||||||
const item = await this.repository.save({
|
const item = await this.repository.save({
|
||||||
...data,
|
...data,
|
||||||
@ -56,21 +46,6 @@ export class CategoryService {
|
|||||||
return item;
|
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) {
|
async getParent(current?: string, parentId?: string) {
|
||||||
if (current === parentId) {
|
if (current === parentId) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -11,14 +11,14 @@ import {
|
|||||||
} from '@/modules/content/dtos/comment.dto';
|
} from '@/modules/content/dtos/comment.dto';
|
||||||
import { CommentEntity } from '@/modules/content/entities/comment.entity';
|
import { CommentEntity } from '@/modules/content/entities/comment.entity';
|
||||||
import { CommentRepository, PostRepository } from '@/modules/content/repositories';
|
import { CommentRepository, PostRepository } from '@/modules/content/repositories';
|
||||||
|
import { BaseService } from '@/modules/database/base/service';
|
||||||
import { treePaginate } from '@/modules/database/utils';
|
import { treePaginate } from '@/modules/database/utils';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CommentService {
|
export class CommentService extends BaseService<CommentEntity, CommentRepository> {
|
||||||
constructor(
|
constructor(protected repository: CommentRepository, protected postRepository: PostRepository) {
|
||||||
protected repository: CommentRepository,
|
super(repository);
|
||||||
protected postRepository: PostRepository,
|
}
|
||||||
) {}
|
|
||||||
|
|
||||||
async findTrees(options: QueryCommentTreeDto = {}) {
|
async findTrees(options: QueryCommentTreeDto = {}) {
|
||||||
return this.repository.findTrees({
|
return this.repository.findTrees({
|
||||||
@ -91,4 +91,8 @@ export class CommentService {
|
|||||||
}
|
}
|
||||||
return parent;
|
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 { PostRepository } from '@/modules/content/repositories/post.repository';
|
||||||
import { SearchService } from '@/modules/content/services/search.service';
|
import { SearchService } from '@/modules/content/services/search.service';
|
||||||
import { SearchType } from '@/modules/content/types';
|
import { SearchType } from '@/modules/content/types';
|
||||||
|
import { BaseService } from '@/modules/database/base/service';
|
||||||
import { SelectTrashMode } from '@/modules/database/constants';
|
import { SelectTrashMode } from '@/modules/database/constants';
|
||||||
import { QueryHook } from '@/modules/database/types';
|
import { QueryHook } from '@/modules/database/types';
|
||||||
import { paginate } from '@/modules/database/utils';
|
import { paginate } from '@/modules/database/utils';
|
||||||
@ -24,7 +25,9 @@ type FindParams = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PostService {
|
export class PostService extends BaseService<PostEntity, PostRepository, FindParams> {
|
||||||
|
protected enableTrash = true;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected repository: PostRepository,
|
protected repository: PostRepository,
|
||||||
protected categoryRepository: CategoryRepository,
|
protected categoryRepository: CategoryRepository,
|
||||||
@ -32,13 +35,15 @@ export class PostService {
|
|||||||
protected tagRepository: TagRepository,
|
protected tagRepository: TagRepository,
|
||||||
protected searchService?: SearchService,
|
protected searchService?: SearchService,
|
||||||
protected searchType: SearchType = 'mysql',
|
protected searchType: SearchType = 'mysql',
|
||||||
) {}
|
) {
|
||||||
|
super(repository);
|
||||||
|
}
|
||||||
|
|
||||||
async paginate(options: QueryPostDto, callback?: QueryHook<PostEntity>) {
|
async paginate(options: QueryPostDto, callback?: QueryHook<PostEntity>) {
|
||||||
if (!isNil(this.searchService) && !isNil(options.search) && this.searchType === 'meili') {
|
if (!isNil(this.searchService) && !isNil(options.search) && this.searchType === 'meili') {
|
||||||
return this.searchService.search(
|
return this.searchService.search(
|
||||||
options.search,
|
options.search,
|
||||||
pick(options, ['trashed', 'page', 'limit']),
|
pick(options, ['trashed', 'page', 'limit', 'isPublished']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const qb = await this.buildListQuery(this.repository.buildBaseQB(), options, callback);
|
const qb = await this.buildListQuery(this.repository.buildBaseQB(), options, callback);
|
||||||
|
@ -47,7 +47,7 @@ export class SearchService implements OnModuleInit {
|
|||||||
return this.client;
|
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 option = { page: 1, limit: 10, trashed: SelectTrashMode.ONLY, ...param };
|
||||||
const limit = isNil(option.limit) || option.limit < 1 ? 1 : option.limit;
|
const limit = isNil(option.limit) || option.limit < 1 ? 1 : option.limit;
|
||||||
const page = isNil(option.page) || option.page < 1 ? 1 : option.page;
|
const page = isNil(option.page) || option.page < 1 ? 1 : option.page;
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { omit } from 'lodash';
|
import { omit } from 'lodash';
|
||||||
|
|
||||||
import { In } from 'typeorm';
|
import { CreateTagDto, UpdateTagDto } from '@/modules/content/dtos/tag.dto';
|
||||||
|
|
||||||
import { CreateTagDto, QueryTagDto, UpdateTagDto } from '@/modules/content/dtos/tag.dto';
|
|
||||||
import { TagRepository } from '@/modules/content/repositories/tag.repository';
|
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()
|
@Injectable()
|
||||||
export class TagService {
|
export class TagService extends BaseService<TagEntity, TagRepository> {
|
||||||
constructor(protected repository: TagRepository) {}
|
protected enableTrash = true;
|
||||||
|
|
||||||
async paginate(options: QueryTagDto) {
|
constructor(protected repository: TagRepository) {
|
||||||
const qb = this.repository.buildBaseQB();
|
super(repository);
|
||||||
return paginate(qb, options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async detail(id: string) {
|
async detail(id: string) {
|
||||||
@ -31,11 +30,4 @@ export class TagService {
|
|||||||
await this.repository.update(data.id, omit(data, ['id']));
|
await this.repository.update(data.id, omit(data, ['id']));
|
||||||
return this.detail(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 { isNil } from 'lodash';
|
||||||
import { In, ObjectLiteral, SelectQueryBuilder } from 'typeorm';
|
import { In, ObjectLiteral, SelectQueryBuilder } from 'typeorm';
|
||||||
|
|
||||||
@ -127,4 +127,29 @@ export abstract class BaseService<
|
|||||||
}
|
}
|
||||||
return this.repository.remove(items);
|
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