diff --git a/docs/guide/application.md b/docs/guide/application.md
deleted file mode 100644
index 57d719bbf..000000000
--- a/docs/guide/application.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: 应用 - Application
-nav:
- title: 教程
----
-
-# 进阶教程
-
-NocoBase 的 Application 的继承关系
-
-```ts
-class Application extends Koa {
-
-}
-
-class Koa extends EventEmitter {
-
-}
-```
-
-Koa 和 EventEmitter 详细 API 可以查阅相关文档,就不多说了。这里主要列一些重点:
-
-实例属性:
-
-- app.db:数据库实例,每个 app 都有自己的 db,完全隔离。
-- app.resources,数据资源实例,为数据提供 API 操作
-- app.cli,commander 实例,提供命令行操作
-- app.context,上下文
-- app.plugins 插件
-
-实例方法:
-
-- app.constructor()
-- app.collection()
-- app.resource()
-- app.command()
-- app.plugin()
-- app.load()
-- app.start()
-- app.use() 添加中间件的方法,由 Koa 提供
-- app.on() 添加事件监听,由 EventEmitter 提供
-- app.emit() 触发事件,由 EventEmitter 提供
-- app.emitSync() 触发异步事件
diff --git a/docs/guide/cli.md b/docs/guide/cli.md
deleted file mode 100644
index 800970f5d..000000000
--- a/docs/guide/cli.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: 命令行 - CLI
-nav:
- title: 教程
----
-
-# 命令行 - CLI
diff --git a/docs/guide/client.md b/docs/guide/client.md
deleted file mode 100644
index 02ff4ece0..000000000
--- a/docs/guide/client.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: 客户端 - Client
-nav:
- title: 教程
----
-
-# 客户端 - Client
\ No newline at end of file
diff --git a/docs/guide/collection.md b/docs/guide/collection.md
deleted file mode 100644
index cd6f997c1..000000000
--- a/docs/guide/collection.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: 数据集 - Collection
-nav:
- title: 教程
----
-
-# 数据集 - Collection
\ No newline at end of file
diff --git a/docs/guide/event.md b/docs/guide/event.md
deleted file mode 100644
index c824cfd91..000000000
--- a/docs/guide/event.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: 事件 - Event
-nav:
- title: 教程
----
-
-# 事件 - Event
diff --git a/docs/guide/installation.md b/docs/guide/installation.md
deleted file mode 100644
index 83159f49a..000000000
--- a/docs/guide/installation.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: 安装 - Installation
-nav:
- title: 教程
----
-
-# 安装 - Installation
diff --git a/docs/guide/middleware.md b/docs/guide/middleware.md
deleted file mode 100644
index 6a2576f7e..000000000
--- a/docs/guide/middleware.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: 中间件 - Middleware
-nav:
- title: 教程
----
-
-# 中间件 - Middleware
-
diff --git a/docs/guide/plugin.md b/docs/guide/plugin.md
deleted file mode 100644
index 562064787..000000000
--- a/docs/guide/plugin.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: 插件 - Plugin
-nav:
- title: 教程
----
-
-# 插件 - Plugin
-
diff --git a/docs/guide/resource.md b/docs/guide/resource.md
deleted file mode 100644
index aa095aca9..000000000
--- a/docs/guide/resource.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: 资源 & 操作 - Resource & Action
-nav:
- title: 教程
----
-
-# 资源 & 操作 - Resource & Action
\ No newline at end of file
diff --git a/docs/guide/test.md b/docs/guide/test.md
deleted file mode 100644
index 79116e0a3..000000000
--- a/docs/guide/test.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: 测试 - Testing
-nav:
- title: 教程
----
-
-# 测试 - Testing
\ No newline at end of file
diff --git a/docs/index.md b/docs/index.md
index b6ae2e753..7e4a58d0f 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -5,7 +5,7 @@ toc: menu
# NocoBase
-考虑到大家是初次接触 NocoBase,开发文档的第一篇,从宏观的角度,带大家了解 NocoBase 的基础概念。NocoBase 采用微内核架构,框架只保留核心,各类功能以插件形式扩展。
+考虑到大家是初次接触 NocoBase,开发文档的第一篇,先带大家了解基础概念。NocoBase 采用微内核架构,框架只保留核心,各类功能以插件形式扩展。
@@ -16,17 +16,21 @@ toc: menu
```ts
const { Application } = require('@nocobase/server');
-const app = new Application();
-
-app.collection({
- name: 'users',
- fields: [
- { type: 'string', name: 'username' },
- { type: 'password', name: 'password' },
- ],
+const app = new Application({
+ // 省略配置信息
});
-app.start(process.argv);
+// 配置一张 users 表
+app.collection({
+ name: 'users',
+ schema: {
+ username: 'string',
+ password: 'password',
+ },
+});
+
+// 解析 argv 参数,终端通过命令行进行不同操作
+app.parse(process.argv);
```
终端运行
@@ -48,19 +52,19 @@ PUT http://localhost:3000/api/users/1
DELETE http://localhost:3000/api/users/1
```
-除了内置的 REST API 以外,还可以自定义其他操作,如登录、注册、注销等。
+以上示例,只用了 10 行左右的代码就创建了真实可用的 REST API 服务。除了内置的 REST API 以外,还可以通过 `app.actions()` 自定义其他操作,如登录、注册、注销等。
```ts
-app.registerActions({
+app.actions({
async login(ctx, next) {},
async register(ctx, next) {},
async logout(ctx, next) {},
}, {
- resourceName: 'users',
+ resourceName: 'users', // 属于 users 资源
});
```
-以上操作的 HTTP API 为:
+以上自定义操作的 HTTP API 为:
```bash
POST http://localhost:3000/api/users:login
@@ -68,22 +72,31 @@ POST http://localhost:3000/api/users:register
POST http://localhost:3000/api/users:logout
```
-自定义的 HTTP API 依旧保持 REST API 的风格,以 `:` 格式表示。REST API 也可以显式指定 actionName,当指定了 actionName 时,无所谓使用什么 Request Method,如:
+自定义的 HTTP API 依旧保持 REST API 的风格,以 `:` 格式表示。实际上 REST API 也可以显式指定 `actionName`,当指定了 `actionName`,无所谓使用什么请求方法,如:
```bash
-GET http://localhost:3000/api/users:list
-POST http://localhost:3000/api/users:create
-GET http://localhost:3000/api/users:get/1
+# 更新操作
+PUT http://localhost:3000/api/users/1
+# 等同于
POST http://localhost:3000/api/users:update/1
+
+# 删除操作
+DELETE http://localhost:3000/api/users/1
+# 等同于
+GET http://localhost:3000/api/users:destroy/1
+# 等同于
POST http://localhost:3000/api/users:destroy/1
```
-结合客户端 SDK 是这样的:
+NocoBase 的路由(Resourcer)基于资源(Resource)和操作(Action)设计,将 REST 和 RPC 结合起来,提供更为灵活且统一的 Resource Action API。结合客户端 SDK 是这样的:
```ts
-const { ClientSDK } = require('@nocobase/client');
+const { ClientSDK } = require('@nocobase/sdk');
-const api = new ClientSDK();
+const api = new ClientSDK({
+ // 可以适配不同 request
+ request(params) => Promise.resolve({}),
+});
await api.resource('users').list();
await api.resource('users').create();
@@ -95,9 +108,39 @@ await api.resource('users').register();
await api.resource('users').logout();
```
+## 应用 - Application
+
+NocoBase 的 Application 继承了 Koa,集成了 DB 和 CLI,添加了一些必要的 API,这里列一些重点:
+
+- `app.db`:数据库实例,每个 app 都有自己的 db。
+ - `db.getTable()` 数据表/数据集配置
+ - `db.getRepository()` 数据仓库
+ - `db.getModel()` 数据模型
+ - `db.on()` 添加事件监听,由 EventEmitter 提供
+ - `db.emit()` 触发事件,由 EventEmitter 提供
+ - `db.emitAsync()` 触发异步事件
+- `app.cli`,commander 实例,提供命令行操作
+- `app.context`,上下文
+ - `ctx.db`
+ - `ctx.action`
+- `app.constructor()` 初始化
+- `app.collection()` 定义数据 Schema,等同于 `app.db.table()`
+- `app.resource()` 定义资源
+- `app.actions()` 定义资源的操作方法
+- `app.on()` 添加事件监听,由 EventEmitter 提供
+- `app.emit()` 触发事件,由 EventEmitter 提供
+- `app.emitAsync()` 触发异步事件
+- `app.use()` 添加中间件,由 Koa 提供
+- `app.command()` 自定义命令行,等同于 `app.cli.command()`
+- `app.plugin()` 添加插件
+- `app.load()` 载入配置,主要用于载入插件
+- `app.parse()` 解析 argv 参数,写在最后,等同于 `app.cli.parseAsync()`
+
+经过几次改进,以上罗列的 API 趋近于稳定,但也可能有所变动。
+
## 数据集 - Collection
-上述例子,通过 `app.collection()` 方法定义数据的 Schema,Schema 的核心为字段配置,字段类型包括:
+NocoBase 通过 `app.collection()` 方法定义数据的 Schema,Schema 的类型包括:
属性 Attribute
@@ -131,29 +174,40 @@ await api.resource('users').logout();
// 用户
app.collection({
name: 'users',
- fields: [
- { type: 'string', name: 'username', unique: true },
- { type: 'password', name: 'password', unique: true },
- { type: 'hasMany', name: 'posts' },
- ],
+ schema: {
+ username: {
+ type: 'string',
+ unique: true,
+ },
+ password: {
+ type: 'password',
+ unique: true,
+ },
+ posts: {
+ type: 'hasMany',
+ },
+ },
});
// 文章
app.collection({
name: 'posts',
- fields: [
- { type: 'string', name: 'title' },
- { type: 'text', name: 'content' },
- { type: 'belongsToMany', name: 'tags' },
- { type: 'hasMany', name: 'comments' },
- { type: 'belongsTo', name: 'author', target: 'users' },
- ],
+ schema: {
+ title: 'string',
+ content: 'text',
+ tags: 'belongsToMany',
+ comments: 'hasMany',
+ author: {
+ type: 'belongsTo',
+ target: 'users',
+ },
+ },
});
// 标签
app.collection({
name: 'tags',
- fields: [
+ schema: [
{ type: 'string', name: 'name' },
{ type: 'belongsToMany', name: 'posts' },
],
@@ -162,22 +216,206 @@ app.collection({
// 评论
app.collection({
name: 'comments',
- fields: [
+ schema: [
{ type: 'text', name: 'content' },
{ type: 'belongsTo', name: 'user' },
],
});
```
-存在外键关联时,也无需顾虑建表和字段的顺序,`db sync` 时会自动处理。为了方便开发,提供了一些有用的属性或方法:
+除了通过 `app.collection()` 配置 schema,也可以直接调用 api 插入或修改 schema,collection 的核心 API 有:
-- `app.db` 数据库实例
-- `app.db.getModel()` 获取 Model
-- `app.db.getTable()` 获取 Schema Table
+- `collection.model` 当前 collection 的数据模型
+- `collection.repository` 当前 collection 的数据仓库
+ - `repository.findAll()`
+ - `repository.findOne()`
+ - `repository.create()`
+ - `repository.update()`
+ - `repository.destroy()`
+- `collection.schema` 当前 collection 的数据结构
+ - `schema.has()` 判断是否存在
+ - `schema.get()` 获取
+ - `schema.set()` 添加或更新
+ - `schema.merge()` 添加、或指定 key path 替换
+ - `schema.replace()` 替换
+ - `schema.delete()` 删除
+
+如:
+
+```ts
+const collection = app.db.getCollection('posts');
+
+collection.schema.has('title');
+
+collection.schema.get('title');
+
+// 添加或更新
+collection.schema.set('content', {
+ type: 'string',
+});
+
+// 移除
+collection.schema.delete('content');
+
+// 添加、或指定 key path 替换
+collection.schema.merge({
+ content: {
+ type: 'content',
+ },
+});
+
+除了全局的 `db.sync()`,也有 `collection.sync()` 方法。
+
+await collection.sync();
+```
+
+存在外键关联时,也无需顾虑建表和字段的顺序,`db sync` 时会自动处理。`db sync` 之后,就可以往表里写入数据了。可以使用 Repository 或 Model 操作。
+
+- Repository 初步提供了 findAll、findOne、create、update、destroy 核心操作方法。
+- Model 为 Sequelize.Model,详细使用说明可以查看 Sequelize 文档。
+- Model 取决于适配的 ORM,Repository 基于 Model 提供统一的接口。
+
+通过 Repository 创建数据
+
+```ts
+const repository = app.db.getRepository('users');
+
+const user = await repository.create({
+ title: 't1',
+ content: 'c1',
+ author: 1,
+ tags: [1,2,3],
+}, {
+ whitelist: [],
+ blacklist: [],
+});
+
+await repository.findAll({
+ filter: {
+ title: 't1',
+ },
+ fields: ['id', 'title', 'content'],
+ sort: '-created_at',
+ page: 1,
+ perPage: 20,
+});
+
+await repository.findOne({
+ filter: {
+ title: 't1',
+ },
+ fields: ['id', 'title', 'content'],
+ sort: '-created_at',
+ page: 1,
+ perPage: 20,
+});
+
+await repository.update({
+ title: 't1',
+ content: 'c1',
+ author: 1,
+ tags: [1,2,3],
+}, {
+ filter: {},
+ whitelist: [],
+ blacklist: [],
+});
+
+await repository.destroy({
+ filter: {},
+});
+```
+
+通过 Model 创建数据
+
+```ts
+const User = db.getModel('users');
+const user = await User.create({
+ title: 't1',
+ content: 'c1',
+});
+await user.updateAssociations({
+ author: 1,
+ tags: [1,2,3],
+});
+```
## 资源 & 操作 - Resource & Action
-不同于常规的 MVC + Router,NocoBase 的路由(Resourcer)基于资源(Resource)和操作(Action)设计,将 REST 和 RPC 结合起来,提供更为灵活且统一的 Resource Action API,Action 不局限于增删改查。资源可以通过 `app.resource()` 方法定义,如:
+Resource 是互联网资源,互联网资源都对应一个地址。客户端请求资源地址,服务器响应请求,在这里「请求」就是一种「操作」,在 REST 里通过判断请求方法(GET/POST/PUT/DELETE)来识别具体的操作,但是请求方法局限性比较大,如上文提到的登录、注册、注销就无法用 REST API 的方式表示。为了解决这类问题,NocoBase 以 `:` 格式表示资源的操作。在关系模型的世界里,关系无处不在,基于关系,NocoBase 又延伸了关系资源的概念,对应关系资源的操作的格式为 `.:`。
+
+Collection 会自动同步给 Resource,上文 Collection 章节定义的 Schema,提炼的资源有:
+
+- `users`
+- `users.posts`
+- `posts`
+- `posts.tags`
+- `posts.comments`
+- `posts.author`
+- `tags`
+- `tags.posts`
+- `comments`
+- `comments.user`
+
+
+
+- Collection 定义数据的 schema(结构和关系)
+- Resource 定义数据的 action(操作方法)
+- Resource 请求和响应的数据结构由 Collection 定义
+- Collection 默认自动同步给 Resource
+- Resource 的概念更大,除了对接 Collection 以外,也可以对接外部数据或其他自定义
+
+
+
+资源相关 API 有:
+
+- `app.resource()`
+- `app.actions()`
+- `ctx.action`
+
+一个资源可以有多个操作。
+
+```ts
+// 数据类
+app.resource({
+ name: 'users',
+ actions: {
+ async list(ctx, next) {},
+ async get(ctx, next) {},
+ async create(ctx, next) {},
+ async update(ctx, next) {},
+ async destroy(ctx, next) {},
+ },
+});
+
+// 非数据类
+app.resource({
+ name: 'server',
+ actions: {
+ // 获取服务器时间
+ getTime(ctx, next) {},
+ // 健康检测
+ healthCheck(ctx, next) {},
+ },
+});
+```
+
+常规操作可以用于不同资源
+
+```ts
+app.actions({
+ async list(ctx, next) {},
+ async get(ctx, next) {},
+ async create(ctx, next) {},
+ async update(ctx, next) {},
+ async destroy(ctx, next) {},
+}, {
+ // 不指定 resourceName 时,全局共享
+ resourceNames: ['posts', 'comments', 'users'],
+});
+```
+
+在资源内部定义的 action 不会共享,常规类似增删改查的操作建议设置为全局,`app.resource()` 只设置参数,如:
```ts
app.resource({
@@ -210,14 +448,100 @@ app.resource({
},
},
});
+
+// app 默认已经内置了 list, get, create, update, destroy 操作
+app.actions({
+ async list(ctx, next) {},
+ async get(ctx, next) {},
+ async create(ctx, next) {},
+ async update(ctx, next) {},
+ async destroy(ctx, next) {},
+});
```
-`app.collection()` 和 `app.resource()` 的区别?
+在 Middleware Handler 和 Action Handler 里,都可以通过 `ctx.action` 获取到当前 action 实例,提供了两个非常有用的 API:
-- `app.collection()` 定义数据的 Schema(结构和关系)
-- `app.resource()` 定义数据的 Action(操作方法)
+- `ctx.action.params`:获取操作对应的参数
+- `ctx.action.mergeParams()`:处理多来源参数合并
-一般情况无需显式声明 collection 的 resource,因为已定义的 collection 会自动同步给 resource。
+`ctx.action.params` 有:
+
+- 定位资源和操作
+ - `actionName`
+ - `resourceName`
+ - `associatedName`
+- 定位资源 ID
+ - `resourceId`
+ - `associatedId`
+- request query
+ - `filter`
+ - `fields`
+ - `sort`
+ - `page`
+ - `perPage`
+ - 其他 query 值
+- request body
+ - `values`
+
+示例:
+
+```ts
+async function (ctx, next) {
+ const { resourceName, resourceId, filter, fields } = ctx.action.params;
+ // ...
+}
+```
+
+多来源参数合并,以 `filter` 参数为例。如:客户端请求日期 2021-09-15 创建的文章
+
+```bash
+GET /api/posts:list?filter={"created_at": "2021-09-15"}
+```
+
+资源设置锁定只能查看已发布的文章
+
+```ts
+app.resource({
+ name: 'posts',
+ actions: {
+ list: {
+ filter: { status: 'publish' }, // 只能查看已发布文章
+ },
+ },
+})
+```
+
+权限设定,只能查看自己创建的文章
+
+```ts
+app.use(async (ctx, next) => {
+ const { resourceName, actionName } = ctx.action.params;
+ if (resourceName === 'posts' && actionName === 'list') {
+ ctx.action.mergeParams({
+ filter: {
+ created_by_id: ctx.state.currentUser.id,
+ },
+ });
+ }
+ await next();
+});
+```
+
+以上客户端、资源配置、中间件内我们都指定了 filter 参数,三个来源的参数最终会合并在一起作为最终的过滤条件:
+
+```ts
+async function list(ctx, next) {
+ // list 操作中获取到的 filter
+ console.log(ctx.params.filter);
+ // {
+ // and: [
+ // { created_at: '2021-09-15' },
+ // { status: 'publish' },
+ // { created_by_id: 1, }
+ // ]
+ // }
+}
+```
## 事件 - Event
@@ -230,13 +554,13 @@ app.resource({
```ts
// 创建数据时,执行 User.create() 时触发
-app.db.on('users:beforeCreate', async (model) => {});
+app.db.on('users.beforeCreate', async (model) => {});
// 客户端 `POST /api/users:login` 时触发
-app.on('users:beforeLogin', async (ctx, next) => {});
+app.on('users.beforeLogin', async (ctx, next) => {});
// 客户端 `POST /api/users` 时触发
-app.on('users:beforeCreate', async (ctx, next) => {});
+app.on('users.beforeCreate', async (ctx, next) => {});
```
## 中间件 - Middleware
@@ -288,10 +612,10 @@ app.command('foo').action(async () => {
- Database/Collection
- `app.db` database 实例
- - `app.collection()` 等同于 `app.db.table()`
+ - `app.collection()` 等同于 `app.db.collection()`
- Resource/Action
- `app.resource()` 等同于 `app.resourcer.define()`
- - `app.registerActions()` 等同于 `app.resourcer.registerActions()`
+ - `app.actions()` 等同于 `app.resourcer.registerActions()`
- Hook/Event
- `app.on()` 添加服务器监听器
- `app.db.on()` 添加数据库监听器
@@ -301,12 +625,9 @@ app.command('foo').action(async () => {
- `app.cli` commander 实例
- `app.command()` 等同于 `app.cli.command()`
- Plugin
- - `app.pluginManager` 插件管理器
- - `app.plugin` 等同于 `app.pluginManager.add()`
+ - `app.plugin` 添加插件
-基于以上扩展接口,提供了模块化、可插拔的插件,可以通过 `app.plugin()` 添加。
-
-完整的插件包括安装、升级、激活、载入、禁用、卸载流程,但是并不是所有插件都要这完整的流程。比如:
+基于以上扩展接口,进一步提供了模块化、可插拔的插件,可以通过 `app.plugin()` 添加。完整的插件包括安装、升级、激活、载入、禁用、卸载流程,但是并不是所有插件都要这完整的流程。比如:
**最简单的插件**
@@ -316,7 +637,7 @@ app.plugin(function pluginName1() {
});
```
-这种方式添加的插件会直接载入。
+这种方式添加的插件会直接载入,无需安装。
**JSON 风格**
@@ -329,7 +650,7 @@ const plugin = app.plugin({
async deactivate() {},
async unstall() {},
}, {
- activate: false, // 默认为 true,不需要启用时可以禁用。
+ enable: false, // 默认为 true,不需要启用时可以禁用。
name: 'plugin-name1',
displayName: '插件名称',
version: '1.2.3',
@@ -423,7 +744,7 @@ describe('mock server', () => {
api = mockServer({
dataWrapping: false,
});
- api.registerActions({
+ api.actions({
list: async (ctx, next) => {
ctx.body = [1, 2];
await next();
@@ -548,7 +869,7 @@ ReactDOM.render(
);
-更多细节,可以通过 create-nocobase-app 初始化项目脚手架并体验。
+更多细节,可以通过 `create-nocobase-app` 初始化项目脚手架并体验。
```bash
yarn create nocobase-app my-nocobase-project
@@ -565,34 +886,24 @@ nocobase-app 默认使用 umijs 作为项目构建工具,并集成了 Server
|- package.json
```
-## 应用场景
-
-### 小型管理信息系统
+## 场景 - Cases
小型管理信息系统,具备完整的前后端。
-### API 服务
-
-无客户端,提供纯后端接口。
+API 服务,无客户端,提供纯后端接口。
-### 小程序 + 后台管理
-
-只需要一套数据库,但有两套用户和权限,一套用于后台用户,一套用于小程序用户。
+小程序 + 后台管理,只需要一套数据库,但有两套用户和权限,一套用于后台用户,一套用于小程序用户。
-### SaaS 服务(共享用户)
-
-每个应用有自己配套的数据库,各应用数据完全隔离。应用不需要用户和权限模块,SaaS 主站全局共享了。
+SaaS 服务(共享用户),每个应用有自己配套的数据库,各应用数据完全隔离。应用不需要用户和权限模块,SaaS 主站全局共享了。
-### SaaS 服务(独立用户)
-
-每个应用有自己的独立用户模块和权限,应用可以绑定自己的域名。
+SaaS 服务(独立用户),每个应用有自己的独立用户模块和权限,应用可以绑定自己的域名。
diff --git a/docs/plugins/action-logs.md b/docs/plugins/action-logs.md
deleted file mode 100644
index eb37defdd..000000000
--- a/docs/plugins/action-logs.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: '@nocobase/plugin-action-logs'
-nav:
- title: 插件
----
-
-# @nocobase/plugin-action-logs
diff --git a/docs/plugins/automations.md b/docs/plugins/automations.md
deleted file mode 100644
index 8b18267f3..000000000
--- a/docs/plugins/automations.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: '@nocobase/plugin-automations'
-nav:
- title: 插件
----
-
-# @nocobase/plugin-automations
diff --git a/docs/plugins/client.md b/docs/plugins/client.md
deleted file mode 100644
index 7030d6a0b..000000000
--- a/docs/plugins/client.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: '@nocobase/plugin-client'
-nav:
- title: 插件
----
-
-# @nocobase/plugin-client
diff --git a/docs/plugins/collections.md b/docs/plugins/collections.md
deleted file mode 100644
index 7dc05b50c..000000000
--- a/docs/plugins/collections.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: '@nocobase/plugin-collections'
-nav:
- title: 插件
----
-
-# @nocobase/plugin-collections
diff --git a/docs/plugins/export.md b/docs/plugins/export.md
deleted file mode 100644
index 314633699..000000000
--- a/docs/plugins/export.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: '@nocobase/plugin-export'
-nav:
- title: 插件
----
-
-# @nocobase/plugin-export
diff --git a/docs/plugins/file-manager.md b/docs/plugins/file-manager.md
deleted file mode 100644
index 6fb5fff0d..000000000
--- a/docs/plugins/file-manager.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: '@nocobase/plugin-file-manager'
-nav:
- title: 插件
----
-
-# @nocobase/plugin-file-manager
diff --git a/docs/plugins/permissions.md b/docs/plugins/permissions.md
deleted file mode 100644
index 33822a660..000000000
--- a/docs/plugins/permissions.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: '@nocobase/plugin-permissions'
-nav:
- title: 插件
----
-
-# @nocobase/plugin-permissions
diff --git a/docs/plugins/saas.md b/docs/plugins/saas.md
deleted file mode 100644
index c9bf69345..000000000
--- a/docs/plugins/saas.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: '@nocobase/plugin-saas'
-nav:
- title: 插件
----
-
-# @nocobase/plugin-saas
diff --git a/docs/plugins/system-settings.md b/docs/plugins/system-settings.md
deleted file mode 100644
index 9d3577286..000000000
--- a/docs/plugins/system-settings.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: '@nocobase/plugin-system-settings'
-nav:
- title: 插件
----
-
-# @nocobase/plugin-system-settings
diff --git a/docs/plugins/users.md b/docs/plugins/users.md
deleted file mode 100644
index f570794e9..000000000
--- a/docs/plugins/users.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: '@nocobase/plugin-users'
-nav:
- title: 插件
----
-
-# @nocobase/plugin-users