diff --git a/docs/en-US/development/server/collections/association-fields.md b/docs/en-US/development/server/collections/association-fields.md new file mode 100644 index 000000000..a2e1fa260 --- /dev/null +++ b/docs/en-US/development/server/collections/association-fields.md @@ -0,0 +1,153 @@ +# 关系字段配置 + +在关系数据库里,标准的建表关系的方式是添加一个外键字段,然后设置上个外键约束。例如 Knex 建表的例子: + +```ts +knex.schema.table('posts', function (table) { + table.integer('userId').unsigned(); + table.foreign('userId').references('users.id'); +}); +``` + +这个过程会在 posts 表里创建一个 userId 字段,并且设置上外键约束 posts.userId 引用 users.id。而在 NocoBase 的 Collection 中,是通过配置关系字段来建立上这样一种关系约束,如: + +```ts +{ + name: 'posts', + fields: [ + { + type: 'belongsTo', + name: 'user', + target: 'users', + foreignKey: 'userId', + }, + ], +} +``` + +## 关系参数说明 + +### BelongsTo + +```ts +interface BelongsTo { + type: 'belongsTo'; + name: string; + // 默认值为 name 复数 + target?: string; + // 默认值为 target model 的主键,一般为 'id' + targetKey?: any; + // 默认值为 target + 'Id' + foreignKey?: any; +} + +// authors 表主键 id 和 books 表外键 authorId 相连 +{ + name: 'books', + fields: [ + { + type: 'belongsTo', + name: 'author', + target: 'authors', + targetKey: 'id', // authors 表主键 + foreignKey: 'authorId', // 外键在 books 表 + } + ], +} +``` + +### HasOne + +```ts +interface HasOne { + type: 'hasOne'; + name: string; + // 默认值为 name 复数 + target?: string; + // 默认值为 source model 的主键,一般为 'id' + sourceKey?: string; + // 默认值为 source collection name 的单数形态 + 'Id' + foreignKey?: string; +} + +// users 表主键 id 和 profiles 外键 userId 相连 +{ + name: 'users', + fields: [ + { + type: 'hasOne', + name: 'profile', + target: 'profiles', + sourceKey: 'id', // users 表主键 + foreignKey: 'userId', // 外键在 profiles 表 + } + ], +} +``` + +### HasMany + +```ts +interface HasMany { + type: 'hasMany'; + name: string; + // 默认值为 name + target?: string; + // 默认值为 source model 的主键,一般为 'id' + sourceKey?: string; + // 默认值为 source collection name 的单数形态 + 'Id' + foreignKey?: string; +} + +// posts 表主键 id 和 comments 表 postId 相连 +{ + name: 'posts', + fields: [ + { + type: 'hasMany', + name: 'comments', + target: 'comments', + sourceKey: 'id', // posts 表主键 + foreignKey: 'postId', // 外键在 comments 表 + } + ], +} +``` + +### BelongsToMany + +```ts +interface BelongsToMany { + type: 'belongsToMany'; + name: string; + // 默认值为 name + target?: string; + // 默认值为 source collection name 和 target 的首字母自然顺序拼接的字符串 + through?: string; + //默认值为 source collection name 的单数形态 + 'Id' + foreignKey?: string; + // 默认值为 source model 的主键,一般为 id + sourceKey?: string; + //默认值为 target 的单数形态 + 'Id' + otherKey?: string; + // 默认值为 target model 的主键,一般为 id + targetKey?: string; +} + +// tags 表主键、posts 表主键和 posts_tags 两个外键相连 +{ + name: 'posts', + fields: [ + { + type: 'belongsToMany', + name: 'tags', + target: 'tags', + through: 'posts_tags', // 中间表 + foreignKey: 'tagId', // 外键1,在 posts_tags 表里 + otherKey: 'postId', // 外键2,在 posts_tags 表里 + targetKey: 'id', // tags 表主键 + sourceKey: 'id', // posts 表主键 + } + ], +} +``` diff --git a/docs/en-US/development/server/collections/cm.svg b/docs/en-US/development/server/collections/cm.svg new file mode 100644 index 000000000..9be5cbf5f --- /dev/null +++ b/docs/en-US/development/server/collections/cm.svg @@ -0,0 +1 @@ +
Collection Manager Plugin

Provide rest api to manage collections
REST API
Plugin A
db.collection()
Collections
UI: Collections & Fields
UI: Graphical interface
Plugin B
db.collection()
Third party
\ No newline at end of file diff --git a/docs/en-US/development/server/collections/collection-field.svg b/docs/en-US/development/server/collections/collection-field.svg new file mode 100644 index 000000000..77c6d5f6f --- /dev/null +++ b/docs/en-US/development/server/collections/collection-field.svg @@ -0,0 +1 @@ +
Field Type
Field Component
Field Interface
Collection Field
\ No newline at end of file diff --git a/docs/en-US/development/server/collections/collection-template.md b/docs/en-US/development/server/collections/collection-template.md new file mode 100644 index 000000000..93389bf82 --- /dev/null +++ b/docs/en-US/development/server/collections/collection-template.md @@ -0,0 +1,82 @@ +# Collection 模板 + + +📢 Collection 模板计划在 2022 年第四季度提供。 + + +在实际的业务场景中,不同的 collection 可能有自己的初始化规则和业务逻辑,NocoBase 通过提供 Collection 模板来解决这类问题。 + +## 常规表 + +```ts +db.collection({ + name: 'posts', + fields: [ + { + type: 'string', + name: 'title', + } + ], +}); +``` + +## 树结构表 + +```ts +db.collection({ + name: 'categories', + tree: 'adjacency-list', + fields: [ + { + type: 'string', + name: 'name', + }, + { + type: 'string', + name: 'description', + }, + { + type: 'belongsTo', + name: 'parent', + target: 'categories', + foreignKey: 'parentId', + }, + { + type: 'hasMany', + name: 'children', + target: 'categories', + foreignKey: 'parentId', + }, + ], +}); +``` + +## 父子继承表 + +```ts +db.collection({ + name: 'a', + fields: [ + + ], +}); + +db.collection({ + name: 'b', + inherits: 'a', + fields: [ + + ], +}); +``` + +## 更多模板 + +如日历表,每个初始化的表都需要初始化特殊的 cron 和 exclude 字段,而这种字段的定义就由模板来完成 + +```ts +db.collection({ + name: 'events', + template: 'calendar', +}); +``` diff --git a/docs/en-US/development/server/collections/configure.md b/docs/en-US/development/server/collections/configure.md new file mode 100644 index 000000000..c6824ea41 --- /dev/null +++ b/docs/en-US/development/server/collections/configure.md @@ -0,0 +1,62 @@ +# 如何配置数据表? + +NocoBase 有三种方式配置数据表: + + + +## 通过界面配置数据表 + +业务数据一般建议使用界面配置,NocoBase 平台提供了两种界面配置数据表 + +### 常规的表格界面 + + + +### 图形化配置界面 + + + +## 在插件代码里定义 + +一般用于配置插件功能表或系统配置表,用户可以读写数据,但不能修改表结构。 + +```ts +export class MyPlugin extends Plugin { + load() { + this.db.collection(); + this.db.import(); + } +} +``` + +相关 API 参考 + +- [db.collection()](/api/database#collection) +- [db.import()](/api/database#import) + +在插件里配置的 collection,插件激活时自动与数据库同步,生相对应的数据表和字段。 + +## 通过 REST API 管理数据表 + +第三方还可以通过 HTTP 接口管理数据表(需要开放权限) + +### Collections + +```bash +GET /api/collections +POST /api/collections +GET /api/collections/ +PUT /api/collections/ +DELETE /api/collections/ +``` + +### Collection fields + +```bash +GET /api/collections//fields +POST /api/collections//fields +GET /api/collections//fields/ +PUT /api/collections//fields/ +DELETE /api/collections//fields/ +``` + diff --git a/docs/en-US/development/server/collections/field-extension.md b/docs/en-US/development/server/collections/field-extension.md new file mode 100644 index 000000000..4ab6216c9 --- /dev/null +++ b/docs/en-US/development/server/collections/field-extension.md @@ -0,0 +1,39 @@ +# 字段扩展 + +在 NocoBase 中 Collection Field 的构成包括: + + + +## Field Type 扩展 + +例如扩展密码类型字段 `type: 'password'` + +```ts +export class MyPlugin extends Plugin { + beforeLoad() { + this.db.registerFieldTypes({ + password: PasswordField + }); + } +} + +export class PasswordField extends Field { + get dataType() { + return DataTypes.STRING; + } +} +``` + +- [更多内置 field types 的实现点此查看](https://github.com/nocobase/nocobase/tree/main/packages/core/database/src/fields) +- 也可以查看完整的 samples 插件 [packages/samples/shop-modeling](https://github.com/nocobase/nocobase/tree/main/packages/samples/shop-modeling) + +## Field Component 扩展 + +相关扩展文档查看: + +- [扩展 Schema 组件](/development/client/ui-schema-designer/extending-schema-components) +- [Schema 组件库](/development/client/ui-schema-designer/component-library) + +## Field Interface 扩展 + +- [内置 field interfaces 点此查看](https://github.com/nocobase/nocobase/tree/main/packages/core/client/src/collection-manager/interfaces) \ No newline at end of file diff --git a/docs/en-US/development/server/collections/graph.jpg b/docs/en-US/development/server/collections/graph.jpg new file mode 100644 index 000000000..16c2f95d1 Binary files /dev/null and b/docs/en-US/development/server/collections/graph.jpg differ diff --git a/docs/en-US/development/server/collections/index.md b/docs/en-US/development/server/collections/index.md new file mode 100644 index 000000000..0dd1914ec --- /dev/null +++ b/docs/en-US/development/server/collections/index.md @@ -0,0 +1,194 @@ +# 核心概念 + +## Collection + +Collection 是所有种类数据的集合,中文翻译为「数据表」,如订单、商品、用户、评论等都是 Collection,不同 Collection 通过 name 区分,如: + +```ts +// 订单 +{ + name: 'orders', +} +// 商品 +{ + name: 'products', +} +// 用户 +{ + name: 'users', +} +// 评论 +{ + name: 'comments', +} +``` + +## Collection Field + +每个 Collection 都有若干 Fields。 + +```ts +// Collection 配置 +{ + name: 'users', + fields: [ + { type: 'string', name: 'name' }, + { type: 'integer', name: 'age' }, + // 其他字段 + ], +} +// 示例数据 +[ + { + name: '张三', + age: 20, + }, + { + name: '李四', + age: 18, + } +]; +``` + +在 NocoBase 中 Collection Field 的构成包括: + + + +### Field Type + +不同字段通过 name 区分,type 表示字段的数据类型,分为 Attribute Type 和 Association Type,如: + +**属性 - Attribute Type** + +- string +- text +- date +- boolean +- time +- float +- json +- location +- password +- virtual +- ... + +**关系 - Association Type** + +- hasOne +- hasMany +- belongsTo +- belongsToMany +- ... + +### Field Component + +只有数据类型的字段,字段值的 IO 没问题了,但是还不够,如果需要将字段展示在界面上,还需要另一个维度的配置 —— `uiSchema`,如: + +```tsx | pure +// 邮箱字段,用 Input 组件展示,使用 email 校验规则 +{ + type: 'string', + name: 'email', + uiSchema: { + 'x-component': 'Input', + 'x-component-props': { size: 'large' }, + 'x-validator': 'email', + 'x-pattern': 'editable', // 可编辑状态,还有 readonly 不可编辑状态、read-pretty 阅读态 + }, +} + +// 数据示例 +{ + email: 'admin@nocobase.com', +} + +// 组件示例 + +``` + +uiSchema 用于配置字段展示在界面上的组件,每个字段组件都会对应一个 value,包括几个维护的配置: + +- 字段的组件 +- 组件的参数 +- 字段的校验规则 +- 字段的模式(editable、readonly、read-pretty) +- 字段的默认值 +- 其他 + +[更多信息查看 UI Schema 章节](/development/client/ui-schema-designer/what-is-ui-schema)。 + +NocoBase 内置的字段组件有: + +- Input +- InputNumber +- Select +- Radio +- Checkbox +- ... + +### Field Interface + +有了 Field Type 和 Field Component 就可以自由组合出若干字段,我们将这种组合之后的模板称之为 Field Interface,如: + +```ts +// 邮箱字段 string + input,email 校验规则 +{ + type: 'string', + name: 'email', + uiSchema: { + 'x-component': 'Input', + 'x-component-props': {}, + 'x-validator': 'email', + }, +} + +// 手机字段 string + input,phone 校验规则 +{ + type: 'string', + name: 'phone', + uiSchema: { + 'x-component': 'Input', + 'x-component-props': {}, + 'x-validator': 'phone', + }, +} +``` + +上面 email 和 phone 每次都需要配置完整的 uiSchema 非常繁琐,为了简化配置,又引申出另一个概念 Field interface,可以将一些参数模板化,如: + +```ts +// email 字段的模板 +interface email { + type: 'string'; + uiSchema: { + 'x-component': 'Input', + 'x-component-props': {}, + 'x-validator': 'email', + }; +} + +// phone 字段的模板 +interface phone { + type: 'string'; + uiSchema: { + 'x-component': 'Input', + 'x-component-props': {}, + 'x-validator': 'phone', + }; +} + +// 简化之后的字段配置 +// email +{ + interface: 'email', + name: 'email', +} + +// phone +{ + interface: 'phone', + name: 'phone', +} +``` + +[更多 Field Interface 点此查看](https://github.com/nocobase/nocobase/tree/main/packages/core/client/src/collection-manager/interfaces) \ No newline at end of file diff --git a/docs/en-US/development/server/collections/options.md b/docs/en-US/development/server/collections/options.md new file mode 100644 index 000000000..d94a44eb7 --- /dev/null +++ b/docs/en-US/development/server/collections/options.md @@ -0,0 +1,137 @@ +# Collection 协议 + +Collection 是 NocoBase 的中枢,是一种用于描述数据结构(数据表和字段)的协议,和关系型数据库的概念非常接近,但不仅限于关系型数据库,也可以是 NoSQL 数据库、HTTP API 等数据源。 + + + +现阶段基于 Collection 协议实现了关系型数据库的对接(db.collections),NoSQL 数据库、HTTP API 等数据源在未来也会逐步实现。 + +Collection 协议主要包括 CollectionOptions 和 FieldOptions 两部分,因为 Field 是可扩展的,所以 FieldOptions 的参数非常灵活。 + +## CollectionOptions + +```ts +interface CollectionOptions { + name: string; + title?: string; + // 树结构表,TreeRepository + tree?: 'adjacency-list' | 'closure-table' | 'materialized-path' | 'nested-set'; + // 父子继承 + inherits?: string | string[]; + fields?: FieldOptions[]; + timestamps?: boolean; + paranoid?: boolean; + sortable?: CollectionSortable; + model?: string; + repository?: string; + [key: string]: any; +} + +type CollectionSortable = string | boolean | { name?: string; scopeKey?: string }; +``` + +## FieldOptions + +通用的字段参数 + +```ts +interface FieldOptions { + name: string; + type: string; + hidden?: boolean; + index?: boolean; + interface?: string; + uiSchema?: ISchema; +``` + +[UI Schema 的介绍点此查看](/development/client/ui-schema-designer/what-is-ui-schema) + +### Field Type + +Field Type 包括 Attribute Type 和 Association Type 两类: + +**Attribute Type** + +- 'boolean' +- 'integer' +- 'bigInt' +- 'double' +- 'real' +- 'decimal' +- 'string' +- 'text' +- 'password' +- 'date' +- 'time' +- 'array' +- 'json' +- 'jsonb' +- 'uuid' +- 'uid' +- 'formula' +- 'radio' +- 'sort' +- 'virtual' + +**Association Type** + +- 'belongsTo' +- 'hasOne' +- 'hasMany' +- 'belongsToMany' + +### Field Interface + +**Basic** + +- input +- textarea +- phone +- email +- integer +- number +- percent +- password +- icon + +**Choices** + +- checkbox +- select +- multipleSelect +- radioGroup +- checkboxGroup +- chinaRegion + +**Media** + +- attachment +- markdown +- richText + +**Date & Time** + +- datetime +- time + +**Relation** + +- linkTo - `type: 'belongsToMany'` +- oho - `type: 'hasOne'` +- obo - `type: 'belongsTo'` +- o2m - `type: 'hasMany'` +- m2o - `type: 'belongsTo'` +- m2m - `type: 'belongsToMany'` + +**Advanced** + +- formula +- sequence + +**System info** + +- id +- createdAt +- createdBy +- updatedAt +- updatedBy diff --git a/docs/en-US/development/server/collections/schema.svg b/docs/en-US/development/server/collections/schema.svg new file mode 100644 index 000000000..230a9bbca --- /dev/null +++ b/docs/en-US/development/server/collections/schema.svg @@ -0,0 +1 @@ +
Collection
Field Type
Field Component
UI Schema
Field Interface
Collection Field
Relational Database
PostgreSQL
NoSQL
API
SQLite
MySQL
Others
Resource
Client
\ No newline at end of file diff --git a/docs/en-US/development/server/collections/table.jpg b/docs/en-US/development/server/collections/table.jpg new file mode 100644 index 000000000..55fe4c183 Binary files /dev/null and b/docs/en-US/development/server/collections/table.jpg differ diff --git a/docs/en-US/development/server/index.md b/docs/en-US/development/server/index.md index 988b10855..91846ebfa 100644 --- a/docs/en-US/development/server/index.md +++ b/docs/en-US/development/server/index.md @@ -20,13 +20,10 @@ import { InstallOptions, Plugin } from '@nocobase/server'; export class MyPlugin extends Plugin { afterAdd() { // 插件 pm.add 注册进来之后,主要用于放置 app beforeLoad 事件的监听 + this.app.on('beforeLoad'); } beforeLoad() { // 自定义类或方法 - this.db.registerFields(); - this.db.registerFields(); - this.db.registerFields(); - this.db.registerFields(); this.db.registerFieldTypes() this.db.registerModels() this.db.registerRepositories() diff --git a/docs/menus.ts b/docs/menus.ts index 45f90cbd9..b5a38bff3 100644 --- a/docs/menus.ts +++ b/docs/menus.ts @@ -116,7 +116,20 @@ export default { type: 'group', children: [ '/development/server/index', - '/development/server/collections-fields', + { + title: 'Collections & Fields', + 'title.zh-CN': '数据表和字段', + type: 'subMenu', + children: [ + '/development/server/collections/index', + '/development/server/collections/options', + '/development/server/collections/configure', + '/development/server/collections/association-fields', + '/development/server/collections/field-extension', + '/development/server/collections/collection-template', + ], + }, + // '/development/server/collections-fields', '/development/server/resources-actions', '/development/server/middleware', '/development/server/commands', diff --git a/docs/zh-CN/development/server/collections/association-fields.md b/docs/zh-CN/development/server/collections/association-fields.md new file mode 100644 index 000000000..a2e1fa260 --- /dev/null +++ b/docs/zh-CN/development/server/collections/association-fields.md @@ -0,0 +1,153 @@ +# 关系字段配置 + +在关系数据库里,标准的建表关系的方式是添加一个外键字段,然后设置上个外键约束。例如 Knex 建表的例子: + +```ts +knex.schema.table('posts', function (table) { + table.integer('userId').unsigned(); + table.foreign('userId').references('users.id'); +}); +``` + +这个过程会在 posts 表里创建一个 userId 字段,并且设置上外键约束 posts.userId 引用 users.id。而在 NocoBase 的 Collection 中,是通过配置关系字段来建立上这样一种关系约束,如: + +```ts +{ + name: 'posts', + fields: [ + { + type: 'belongsTo', + name: 'user', + target: 'users', + foreignKey: 'userId', + }, + ], +} +``` + +## 关系参数说明 + +### BelongsTo + +```ts +interface BelongsTo { + type: 'belongsTo'; + name: string; + // 默认值为 name 复数 + target?: string; + // 默认值为 target model 的主键,一般为 'id' + targetKey?: any; + // 默认值为 target + 'Id' + foreignKey?: any; +} + +// authors 表主键 id 和 books 表外键 authorId 相连 +{ + name: 'books', + fields: [ + { + type: 'belongsTo', + name: 'author', + target: 'authors', + targetKey: 'id', // authors 表主键 + foreignKey: 'authorId', // 外键在 books 表 + } + ], +} +``` + +### HasOne + +```ts +interface HasOne { + type: 'hasOne'; + name: string; + // 默认值为 name 复数 + target?: string; + // 默认值为 source model 的主键,一般为 'id' + sourceKey?: string; + // 默认值为 source collection name 的单数形态 + 'Id' + foreignKey?: string; +} + +// users 表主键 id 和 profiles 外键 userId 相连 +{ + name: 'users', + fields: [ + { + type: 'hasOne', + name: 'profile', + target: 'profiles', + sourceKey: 'id', // users 表主键 + foreignKey: 'userId', // 外键在 profiles 表 + } + ], +} +``` + +### HasMany + +```ts +interface HasMany { + type: 'hasMany'; + name: string; + // 默认值为 name + target?: string; + // 默认值为 source model 的主键,一般为 'id' + sourceKey?: string; + // 默认值为 source collection name 的单数形态 + 'Id' + foreignKey?: string; +} + +// posts 表主键 id 和 comments 表 postId 相连 +{ + name: 'posts', + fields: [ + { + type: 'hasMany', + name: 'comments', + target: 'comments', + sourceKey: 'id', // posts 表主键 + foreignKey: 'postId', // 外键在 comments 表 + } + ], +} +``` + +### BelongsToMany + +```ts +interface BelongsToMany { + type: 'belongsToMany'; + name: string; + // 默认值为 name + target?: string; + // 默认值为 source collection name 和 target 的首字母自然顺序拼接的字符串 + through?: string; + //默认值为 source collection name 的单数形态 + 'Id' + foreignKey?: string; + // 默认值为 source model 的主键,一般为 id + sourceKey?: string; + //默认值为 target 的单数形态 + 'Id' + otherKey?: string; + // 默认值为 target model 的主键,一般为 id + targetKey?: string; +} + +// tags 表主键、posts 表主键和 posts_tags 两个外键相连 +{ + name: 'posts', + fields: [ + { + type: 'belongsToMany', + name: 'tags', + target: 'tags', + through: 'posts_tags', // 中间表 + foreignKey: 'tagId', // 外键1,在 posts_tags 表里 + otherKey: 'postId', // 外键2,在 posts_tags 表里 + targetKey: 'id', // tags 表主键 + sourceKey: 'id', // posts 表主键 + } + ], +} +``` diff --git a/docs/zh-CN/development/server/collections/cm.svg b/docs/zh-CN/development/server/collections/cm.svg new file mode 100644 index 000000000..9be5cbf5f --- /dev/null +++ b/docs/zh-CN/development/server/collections/cm.svg @@ -0,0 +1 @@ +
Collection Manager Plugin

Provide rest api to manage collections
REST API
Plugin A
db.collection()
Collections
UI: Collections & Fields
UI: Graphical interface
Plugin B
db.collection()
Third party
\ No newline at end of file diff --git a/docs/zh-CN/development/server/collections/collection-field.svg b/docs/zh-CN/development/server/collections/collection-field.svg new file mode 100644 index 000000000..77c6d5f6f --- /dev/null +++ b/docs/zh-CN/development/server/collections/collection-field.svg @@ -0,0 +1 @@ +
Field Type
Field Component
Field Interface
Collection Field
\ No newline at end of file diff --git a/docs/zh-CN/development/server/collections/collection-template.md b/docs/zh-CN/development/server/collections/collection-template.md new file mode 100644 index 000000000..93389bf82 --- /dev/null +++ b/docs/zh-CN/development/server/collections/collection-template.md @@ -0,0 +1,82 @@ +# Collection 模板 + + +📢 Collection 模板计划在 2022 年第四季度提供。 + + +在实际的业务场景中,不同的 collection 可能有自己的初始化规则和业务逻辑,NocoBase 通过提供 Collection 模板来解决这类问题。 + +## 常规表 + +```ts +db.collection({ + name: 'posts', + fields: [ + { + type: 'string', + name: 'title', + } + ], +}); +``` + +## 树结构表 + +```ts +db.collection({ + name: 'categories', + tree: 'adjacency-list', + fields: [ + { + type: 'string', + name: 'name', + }, + { + type: 'string', + name: 'description', + }, + { + type: 'belongsTo', + name: 'parent', + target: 'categories', + foreignKey: 'parentId', + }, + { + type: 'hasMany', + name: 'children', + target: 'categories', + foreignKey: 'parentId', + }, + ], +}); +``` + +## 父子继承表 + +```ts +db.collection({ + name: 'a', + fields: [ + + ], +}); + +db.collection({ + name: 'b', + inherits: 'a', + fields: [ + + ], +}); +``` + +## 更多模板 + +如日历表,每个初始化的表都需要初始化特殊的 cron 和 exclude 字段,而这种字段的定义就由模板来完成 + +```ts +db.collection({ + name: 'events', + template: 'calendar', +}); +``` diff --git a/docs/zh-CN/development/server/collections/configure.md b/docs/zh-CN/development/server/collections/configure.md new file mode 100644 index 000000000..c6824ea41 --- /dev/null +++ b/docs/zh-CN/development/server/collections/configure.md @@ -0,0 +1,62 @@ +# 如何配置数据表? + +NocoBase 有三种方式配置数据表: + + + +## 通过界面配置数据表 + +业务数据一般建议使用界面配置,NocoBase 平台提供了两种界面配置数据表 + +### 常规的表格界面 + + + +### 图形化配置界面 + + + +## 在插件代码里定义 + +一般用于配置插件功能表或系统配置表,用户可以读写数据,但不能修改表结构。 + +```ts +export class MyPlugin extends Plugin { + load() { + this.db.collection(); + this.db.import(); + } +} +``` + +相关 API 参考 + +- [db.collection()](/api/database#collection) +- [db.import()](/api/database#import) + +在插件里配置的 collection,插件激活时自动与数据库同步,生相对应的数据表和字段。 + +## 通过 REST API 管理数据表 + +第三方还可以通过 HTTP 接口管理数据表(需要开放权限) + +### Collections + +```bash +GET /api/collections +POST /api/collections +GET /api/collections/ +PUT /api/collections/ +DELETE /api/collections/ +``` + +### Collection fields + +```bash +GET /api/collections//fields +POST /api/collections//fields +GET /api/collections//fields/ +PUT /api/collections//fields/ +DELETE /api/collections//fields/ +``` + diff --git a/docs/zh-CN/development/server/collections/field-extension.md b/docs/zh-CN/development/server/collections/field-extension.md new file mode 100644 index 000000000..4ab6216c9 --- /dev/null +++ b/docs/zh-CN/development/server/collections/field-extension.md @@ -0,0 +1,39 @@ +# 字段扩展 + +在 NocoBase 中 Collection Field 的构成包括: + + + +## Field Type 扩展 + +例如扩展密码类型字段 `type: 'password'` + +```ts +export class MyPlugin extends Plugin { + beforeLoad() { + this.db.registerFieldTypes({ + password: PasswordField + }); + } +} + +export class PasswordField extends Field { + get dataType() { + return DataTypes.STRING; + } +} +``` + +- [更多内置 field types 的实现点此查看](https://github.com/nocobase/nocobase/tree/main/packages/core/database/src/fields) +- 也可以查看完整的 samples 插件 [packages/samples/shop-modeling](https://github.com/nocobase/nocobase/tree/main/packages/samples/shop-modeling) + +## Field Component 扩展 + +相关扩展文档查看: + +- [扩展 Schema 组件](/development/client/ui-schema-designer/extending-schema-components) +- [Schema 组件库](/development/client/ui-schema-designer/component-library) + +## Field Interface 扩展 + +- [内置 field interfaces 点此查看](https://github.com/nocobase/nocobase/tree/main/packages/core/client/src/collection-manager/interfaces) \ No newline at end of file diff --git a/docs/zh-CN/development/server/collections/graph.jpg b/docs/zh-CN/development/server/collections/graph.jpg new file mode 100644 index 000000000..16c2f95d1 Binary files /dev/null and b/docs/zh-CN/development/server/collections/graph.jpg differ diff --git a/docs/zh-CN/development/server/collections/index.md b/docs/zh-CN/development/server/collections/index.md new file mode 100644 index 000000000..0dd1914ec --- /dev/null +++ b/docs/zh-CN/development/server/collections/index.md @@ -0,0 +1,194 @@ +# 核心概念 + +## Collection + +Collection 是所有种类数据的集合,中文翻译为「数据表」,如订单、商品、用户、评论等都是 Collection,不同 Collection 通过 name 区分,如: + +```ts +// 订单 +{ + name: 'orders', +} +// 商品 +{ + name: 'products', +} +// 用户 +{ + name: 'users', +} +// 评论 +{ + name: 'comments', +} +``` + +## Collection Field + +每个 Collection 都有若干 Fields。 + +```ts +// Collection 配置 +{ + name: 'users', + fields: [ + { type: 'string', name: 'name' }, + { type: 'integer', name: 'age' }, + // 其他字段 + ], +} +// 示例数据 +[ + { + name: '张三', + age: 20, + }, + { + name: '李四', + age: 18, + } +]; +``` + +在 NocoBase 中 Collection Field 的构成包括: + + + +### Field Type + +不同字段通过 name 区分,type 表示字段的数据类型,分为 Attribute Type 和 Association Type,如: + +**属性 - Attribute Type** + +- string +- text +- date +- boolean +- time +- float +- json +- location +- password +- virtual +- ... + +**关系 - Association Type** + +- hasOne +- hasMany +- belongsTo +- belongsToMany +- ... + +### Field Component + +只有数据类型的字段,字段值的 IO 没问题了,但是还不够,如果需要将字段展示在界面上,还需要另一个维度的配置 —— `uiSchema`,如: + +```tsx | pure +// 邮箱字段,用 Input 组件展示,使用 email 校验规则 +{ + type: 'string', + name: 'email', + uiSchema: { + 'x-component': 'Input', + 'x-component-props': { size: 'large' }, + 'x-validator': 'email', + 'x-pattern': 'editable', // 可编辑状态,还有 readonly 不可编辑状态、read-pretty 阅读态 + }, +} + +// 数据示例 +{ + email: 'admin@nocobase.com', +} + +// 组件示例 + +``` + +uiSchema 用于配置字段展示在界面上的组件,每个字段组件都会对应一个 value,包括几个维护的配置: + +- 字段的组件 +- 组件的参数 +- 字段的校验规则 +- 字段的模式(editable、readonly、read-pretty) +- 字段的默认值 +- 其他 + +[更多信息查看 UI Schema 章节](/development/client/ui-schema-designer/what-is-ui-schema)。 + +NocoBase 内置的字段组件有: + +- Input +- InputNumber +- Select +- Radio +- Checkbox +- ... + +### Field Interface + +有了 Field Type 和 Field Component 就可以自由组合出若干字段,我们将这种组合之后的模板称之为 Field Interface,如: + +```ts +// 邮箱字段 string + input,email 校验规则 +{ + type: 'string', + name: 'email', + uiSchema: { + 'x-component': 'Input', + 'x-component-props': {}, + 'x-validator': 'email', + }, +} + +// 手机字段 string + input,phone 校验规则 +{ + type: 'string', + name: 'phone', + uiSchema: { + 'x-component': 'Input', + 'x-component-props': {}, + 'x-validator': 'phone', + }, +} +``` + +上面 email 和 phone 每次都需要配置完整的 uiSchema 非常繁琐,为了简化配置,又引申出另一个概念 Field interface,可以将一些参数模板化,如: + +```ts +// email 字段的模板 +interface email { + type: 'string'; + uiSchema: { + 'x-component': 'Input', + 'x-component-props': {}, + 'x-validator': 'email', + }; +} + +// phone 字段的模板 +interface phone { + type: 'string'; + uiSchema: { + 'x-component': 'Input', + 'x-component-props': {}, + 'x-validator': 'phone', + }; +} + +// 简化之后的字段配置 +// email +{ + interface: 'email', + name: 'email', +} + +// phone +{ + interface: 'phone', + name: 'phone', +} +``` + +[更多 Field Interface 点此查看](https://github.com/nocobase/nocobase/tree/main/packages/core/client/src/collection-manager/interfaces) \ No newline at end of file diff --git a/docs/zh-CN/development/server/collections/options.md b/docs/zh-CN/development/server/collections/options.md new file mode 100644 index 000000000..d94a44eb7 --- /dev/null +++ b/docs/zh-CN/development/server/collections/options.md @@ -0,0 +1,137 @@ +# Collection 协议 + +Collection 是 NocoBase 的中枢,是一种用于描述数据结构(数据表和字段)的协议,和关系型数据库的概念非常接近,但不仅限于关系型数据库,也可以是 NoSQL 数据库、HTTP API 等数据源。 + + + +现阶段基于 Collection 协议实现了关系型数据库的对接(db.collections),NoSQL 数据库、HTTP API 等数据源在未来也会逐步实现。 + +Collection 协议主要包括 CollectionOptions 和 FieldOptions 两部分,因为 Field 是可扩展的,所以 FieldOptions 的参数非常灵活。 + +## CollectionOptions + +```ts +interface CollectionOptions { + name: string; + title?: string; + // 树结构表,TreeRepository + tree?: 'adjacency-list' | 'closure-table' | 'materialized-path' | 'nested-set'; + // 父子继承 + inherits?: string | string[]; + fields?: FieldOptions[]; + timestamps?: boolean; + paranoid?: boolean; + sortable?: CollectionSortable; + model?: string; + repository?: string; + [key: string]: any; +} + +type CollectionSortable = string | boolean | { name?: string; scopeKey?: string }; +``` + +## FieldOptions + +通用的字段参数 + +```ts +interface FieldOptions { + name: string; + type: string; + hidden?: boolean; + index?: boolean; + interface?: string; + uiSchema?: ISchema; +``` + +[UI Schema 的介绍点此查看](/development/client/ui-schema-designer/what-is-ui-schema) + +### Field Type + +Field Type 包括 Attribute Type 和 Association Type 两类: + +**Attribute Type** + +- 'boolean' +- 'integer' +- 'bigInt' +- 'double' +- 'real' +- 'decimal' +- 'string' +- 'text' +- 'password' +- 'date' +- 'time' +- 'array' +- 'json' +- 'jsonb' +- 'uuid' +- 'uid' +- 'formula' +- 'radio' +- 'sort' +- 'virtual' + +**Association Type** + +- 'belongsTo' +- 'hasOne' +- 'hasMany' +- 'belongsToMany' + +### Field Interface + +**Basic** + +- input +- textarea +- phone +- email +- integer +- number +- percent +- password +- icon + +**Choices** + +- checkbox +- select +- multipleSelect +- radioGroup +- checkboxGroup +- chinaRegion + +**Media** + +- attachment +- markdown +- richText + +**Date & Time** + +- datetime +- time + +**Relation** + +- linkTo - `type: 'belongsToMany'` +- oho - `type: 'hasOne'` +- obo - `type: 'belongsTo'` +- o2m - `type: 'hasMany'` +- m2o - `type: 'belongsTo'` +- m2m - `type: 'belongsToMany'` + +**Advanced** + +- formula +- sequence + +**System info** + +- id +- createdAt +- createdBy +- updatedAt +- updatedBy diff --git a/docs/zh-CN/development/server/collections/schema.svg b/docs/zh-CN/development/server/collections/schema.svg new file mode 100644 index 000000000..230a9bbca --- /dev/null +++ b/docs/zh-CN/development/server/collections/schema.svg @@ -0,0 +1 @@ +
Collection
Field Type
Field Component
UI Schema
Field Interface
Collection Field
Relational Database
PostgreSQL
NoSQL
API
SQLite
MySQL
Others
Resource
Client
\ No newline at end of file diff --git a/docs/zh-CN/development/server/collections/table.jpg b/docs/zh-CN/development/server/collections/table.jpg new file mode 100644 index 000000000..55fe4c183 Binary files /dev/null and b/docs/zh-CN/development/server/collections/table.jpg differ diff --git a/docs/zh-CN/development/server/index.md b/docs/zh-CN/development/server/index.md index 988b10855..91846ebfa 100644 --- a/docs/zh-CN/development/server/index.md +++ b/docs/zh-CN/development/server/index.md @@ -20,13 +20,10 @@ import { InstallOptions, Plugin } from '@nocobase/server'; export class MyPlugin extends Plugin { afterAdd() { // 插件 pm.add 注册进来之后,主要用于放置 app beforeLoad 事件的监听 + this.app.on('beforeLoad'); } beforeLoad() { // 自定义类或方法 - this.db.registerFields(); - this.db.registerFields(); - this.db.registerFields(); - this.db.registerFields(); this.db.registerFieldTypes() this.db.registerModels() this.db.registerRepositories()