插件后端开发
1. 后端入口
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会在主程序加载插件时被动态注册。2. 标准模块结构
src/api/modules/{module-name}/
├── {module-name}.module.ts
├── controllers/
│ ├── console/
│ └── web/
├── services/
└── dto/3. 扩展实体:@ExtensionEntity
@ExtensionEntity
export class Article {}@Entity来写插件表,原因是:@ExtensionEntity会自动把表挂到插件自己的 schemapublicschema4. 扩展控制器装饰器
@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 {}5. 插件 Service 写法
BaseService<T>。@Injectable
export class ArticleService extends BaseService<Article> { constructor( @InjectRepository(Article) private readonly articleRepository: Repository<Article>, ) { super(articleRepository); }
}1.
2.
super.create / super.updateById / super.paginate3.
async 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, }, );
}6. 插件常用公共能力
BaseServiceBaseControllerPlaygroundPublicBuildFileUrlUUIDValidationPipeDictServiceHttpErrorFactory共 319 篇文档 · 内容同步自官方帮助中心