src/api/index.ts:export * from "./modules/app.module";src/api/modules/app.module.ts:@Module({
imports: [CategoryModule, ArticleModule],
exports: [CategoryModule, ArticleModule],
})
export class AppModule {}AppModule 会在主程序加载插件时被动态注册。src/api/modules/{module-name}/
├── {module-name}.module.ts
├── controllers/
│ ├── console/
│ └── web/
├── services/
└── dto/@ExtensionEntity()@ExtensionEntity()
export class Article {}@Entity() 来写插件表,原因是:@ExtensionEntity() 会自动把表挂到插件自己的 schemapublic schema@ExtensionConsoleController(path, groupName)/{extensionIdentifier}/consoleapi/{path}@ExtensionConsoleController("article", "文章管理")
export class ArticleController {}@ExtensionWebController(path | options)/{extensionIdentifier}/api/{path}@ExtensionWebController("article")
export class ArticleWebController {}@Public()
@Get()
findAll() {}BaseService<T>。@Injectable()
export class ArticleService extends BaseService<Article> {
constructor(
@InjectRepository(Article)
private readonly articleRepository: Repository<Article>,
) {
super(articleRepository);
}
}super.create / super.updateById / super.paginateasync createArticle(dto: CreateArticleDto, authorId: string) {
if (dto.categoryId) {
const category = await this.categoryService.findOneById(dto.categoryId);
if (!category) {
throw HttpErrorFactory.badRequest("Category does not exist");
}
}
const author = await this.userService.findUserById(authorId);
if (!author) {
throw HttpErrorFactory.notFound("Author not found");
}
return super.create(
{
...dto,
author,
viewCount: 0,
},
{
includeFields: ["author.id", "author.avatar", "author.nickname"] as const,
},
);
}BaseServiceBaseControllerPlaygroundPublicBuildFileUrlUUIDValidationPipeDictServiceHttpErrorFactory