feat: new version of the documentation (#95)
* feat: new version of the documentation * feat: add English catalog translation * Update quickstart.md * Update quickstart.zh-CN.md * Update quickstart.zh-CN.md * Update quickstart.zh-CN.md * Update quickstart.zh-CN.md * feat: update quickstart * update doc * update pepository api doc Co-authored-by: ChengLei Shao <chareice@live.com>
This commit is contained in:
		
							parent
							
								
									1408de55d2
								
							
						
					
					
						commit
						ca7af9c8cc
					
				
							
								
								
									
										5
									
								
								.dumi/theme/builtins/Redirect.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.dumi/theme/builtins/Redirect.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					import React, { Redirect } from 'umi';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default (props: any) => {
 | 
				
			||||||
 | 
					  return <Redirect {...props}/>
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -79,6 +79,9 @@ const Layout: React.FC<IRouteComponentProps> = ({ children, location }) => {
 | 
				
			|||||||
        setMenuCollapsed(true);
 | 
					        setMenuCollapsed(true);
 | 
				
			||||||
      }}
 | 
					      }}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
 | 
					      <div className={'tip'} style={{ position: 'fixed', top: 64, left: 0, right: 0, textAlign: 'center', lineHeight: '36px', background: '#fffbe6', borderBottom: '1px solid rgba(60, 72, 88, 0.05)', zIndex: 100 }}>
 | 
				
			||||||
 | 
					        {isCN ? '文档还在建设中,与实际代码存在差异' : 'The documentation is still under construction and differs somewhat from the actual code.'}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
      <Navbar
 | 
					      <Navbar
 | 
				
			||||||
        location={location}
 | 
					        location={location}
 | 
				
			||||||
        navPrefix={<SearchBar />}
 | 
					        navPrefix={<SearchBar />}
 | 
				
			||||||
 | 
				
			|||||||
@ -19,9 +19,12 @@ body {
 | 
				
			|||||||
  padding: 16px (@s-content-margin + @s-toc-width) 50px @s-menu-width + @s-content-margin;
 | 
					  padding: 16px (@s-content-margin + @s-toc-width) 50px @s-menu-width + @s-content-margin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @media @mobile {
 | 
					  @media @mobile {
 | 
				
			||||||
    padding-top: 66px !important;
 | 
					    padding-top: 98px !important;
 | 
				
			||||||
    padding-left: 16px !important;
 | 
					    padding-left: 16px !important;
 | 
				
			||||||
    padding-right: 16px !important;
 | 
					    padding-right: 16px !important;
 | 
				
			||||||
 | 
					    .tip {
 | 
				
			||||||
 | 
					      top: 50px !important;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  &[data-gapless='true'] {
 | 
					  &[data-gapless='true'] {
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,8 @@
 | 
				
			|||||||
.markdown {
 | 
					.markdown {
 | 
				
			||||||
  color: @c-text;
 | 
					  color: @c-text;
 | 
				
			||||||
  font-size: 15px;
 | 
					  font-size: 15px;
 | 
				
			||||||
  line-height: 1.60625;
 | 
					  // line-height: 1.60625;
 | 
				
			||||||
 | 
					  line-height: 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  &:not(:first-child):empty {
 | 
					  &:not(:first-child):empty {
 | 
				
			||||||
    min-height: 32px;
 | 
					    min-height: 32px;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								.github/workflows/vercel.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/workflows/vercel.yml
									
									
									
									
										vendored
									
									
								
							@ -4,6 +4,7 @@ on:
 | 
				
			|||||||
  push:
 | 
					  push:
 | 
				
			||||||
    branches:
 | 
					    branches:
 | 
				
			||||||
      - develop
 | 
					      - develop
 | 
				
			||||||
 | 
					      - feature/docs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
jobs:
 | 
					jobs:
 | 
				
			||||||
  deploy:
 | 
					  deploy:
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										38
									
								
								.umirc.ts
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								.umirc.ts
									
									
									
									
									
								
							@ -16,21 +16,51 @@ export default defineConfig({
 | 
				
			|||||||
      'pathRewrite': { '^/api/': '/api/' },
 | 
					      'pathRewrite': { '^/api/': '/api/' },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  resolve: {
 | 
				
			||||||
 | 
					    includes: ['docs'],
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  styles: [
 | 
				
			||||||
 | 
					    `
 | 
				
			||||||
 | 
					    .__dumi-default-navbar-logo {
 | 
				
			||||||
 | 
					      height: 100%;
 | 
				
			||||||
 | 
					      width: 100px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .__dumi-default-layout .__dumi-default-navbar {
 | 
				
			||||||
 | 
					      box-shadow: 0 0 3px rgb(60 72 88 / 15%);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    .__dumi-default-layout[data-site-mode='true'] {
 | 
				
			||||||
 | 
					      padding-top: 150px !important;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    @media only screen and (max-width: 767px) {
 | 
				
			||||||
 | 
					      .__dumi-default-layout[data-site-mode="true"] {
 | 
				
			||||||
 | 
					        padding-top: 128px !important;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    @media only screen and (min-width: 768px) {
 | 
				
			||||||
 | 
					      .__dumi-default-menu[data-mode='site'] {
 | 
				
			||||||
 | 
					        top: 100px !important;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      .__dumi-default-layout[data-site-mode='true'] .__dumi-default-layout-toc {
 | 
				
			||||||
 | 
					        top: 150px !important;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    `
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
  // mfsu: {},
 | 
					  // mfsu: {},
 | 
				
			||||||
  // ssr: {},
 | 
					  // ssr: {},
 | 
				
			||||||
  // exportStatic: {},
 | 
					  // exportStatic: {},
 | 
				
			||||||
  mode: 'doc',
 | 
					  mode: 'site',
 | 
				
			||||||
  logo: 'https://www.nocobase.com/dist/images/logo.png',
 | 
					  logo: 'https://www.nocobase.com/images/logo.png',
 | 
				
			||||||
  navs: {
 | 
					  navs: {
 | 
				
			||||||
    'en-US': [
 | 
					    'en-US': [
 | 
				
			||||||
      null,
 | 
					      null,
 | 
				
			||||||
      { title: 'GitHub', path: 'https://github.com/nocobase/nocobase' },
 | 
					      { title: 'GitHub', path: 'https://github.com/nocobase/nocobase' },
 | 
				
			||||||
      { title: 'Changelog', path: 'https://github.com/nocobase/nocobase/releases' },
 | 
					      // { title: 'Changelog', path: 'https://github.com/nocobase/nocobase/releases' },
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    'zh-CN': [
 | 
					    'zh-CN': [
 | 
				
			||||||
      null,
 | 
					      null,
 | 
				
			||||||
      { title: 'GitHub', path: 'https://github.com/nocobase/nocobase' },
 | 
					      { title: 'GitHub', path: 'https://github.com/nocobase/nocobase' },
 | 
				
			||||||
      { title: '更新日志', path: 'https://github.com/nocobase/nocobase/releases' },
 | 
					      // { title: '更新日志', path: 'https://github.com/nocobase/nocobase/releases' },
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  // more config: https://d.umijs.org/config
 | 
					  // more config: https://d.umijs.org/config
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										10
									
								
								docs/api/action.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								docs/api/action.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					toc: menu
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Action
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## action.params
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## action.mergeParams()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										80
									
								
								docs/api/application.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								docs/api/application.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					nav:
 | 
				
			||||||
 | 
					  title: API
 | 
				
			||||||
 | 
					  order: 3
 | 
				
			||||||
 | 
					toc: menu
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.db
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					数据库实例
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.resourcer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					资源实例
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.pm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					插件管理器
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.i18n
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					国际化
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.constructor()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					构造器
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.use()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					中间件
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.on()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					事件
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.emit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.emitAsync()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.collection()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					等同于 app.db.collection()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.actions()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					等同于 app.resourcer.registerActions()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.resource()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					等同于 app.resourcer.define()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.parse()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					等同于 app.cli.parse()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					加载配置
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.init()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					初始化
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.start()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					启动应用
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.stop()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					停止应用
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.command()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					等同于 app.cli.command()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## app.plugin()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					等同于 app.pm.add()
 | 
				
			||||||
							
								
								
									
										13
									
								
								docs/api/cli.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								docs/api/cli.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					toc: menu
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# CLI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## init
 | 
				
			||||||
 | 
					## start
 | 
				
			||||||
 | 
					## db:sync
 | 
				
			||||||
 | 
					## pm:download
 | 
				
			||||||
 | 
					## pm:enable
 | 
				
			||||||
 | 
					## pm:disable
 | 
				
			||||||
 | 
					## pm:remove
 | 
				
			||||||
							
								
								
									
										16
									
								
								docs/api/client.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								docs/api/client.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					toc: menu
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## APIClient
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## createRouteSwitch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## createCollectionField
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## createSchemaComponent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## i18n
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										17
									
								
								docs/api/collection.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								docs/api/collection.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					toc: menu
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Collection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## collection.constructor()
 | 
				
			||||||
 | 
					## collection.mergeOptions()
 | 
				
			||||||
 | 
					## collection.sync()
 | 
				
			||||||
 | 
					## collection.hasField()
 | 
				
			||||||
 | 
					## collection.getField()
 | 
				
			||||||
 | 
					## collection.addField()
 | 
				
			||||||
 | 
					## collection.setFields()
 | 
				
			||||||
 | 
					## collection.mergeField()
 | 
				
			||||||
 | 
					## collection.removeField()
 | 
				
			||||||
 | 
					## collection.forEachField()
 | 
				
			||||||
 | 
					## collection.findField()
 | 
				
			||||||
							
								
								
									
										16
									
								
								docs/api/context.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								docs/api/context.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					toc: menu
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## ctx.db
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## ctx.resourcer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## ctx.action
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## ctx.i18n
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## ctx.t()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										18
									
								
								docs/api/database.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								docs/api/database.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					toc: menu
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Database
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## db.constructor()
 | 
				
			||||||
 | 
					## db.collection()
 | 
				
			||||||
 | 
					## db.sync()
 | 
				
			||||||
 | 
					## db.close()
 | 
				
			||||||
 | 
					## db.registerFieldTypes()
 | 
				
			||||||
 | 
					## db.import()
 | 
				
			||||||
 | 
					## db.on()
 | 
				
			||||||
 | 
					## db.emitAsync()
 | 
				
			||||||
 | 
					## db.emit()
 | 
				
			||||||
 | 
					## db.registerModels()
 | 
				
			||||||
 | 
					## db.registerRepositories()
 | 
				
			||||||
 | 
					## db.registerOperators()
 | 
				
			||||||
							
								
								
									
										30
									
								
								docs/api/field-types.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								docs/api/field-types.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					toc: menu
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Field Types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Field - abstract
 | 
				
			||||||
 | 
					## RelationField - abstract
 | 
				
			||||||
 | 
					## HasOneField
 | 
				
			||||||
 | 
					## HasManyField
 | 
				
			||||||
 | 
					## BelongsToField
 | 
				
			||||||
 | 
					## BelongsToManyField
 | 
				
			||||||
 | 
					## StringField
 | 
				
			||||||
 | 
					## TextField
 | 
				
			||||||
 | 
					## IntegerField
 | 
				
			||||||
 | 
					## FloatField
 | 
				
			||||||
 | 
					## DoubleField
 | 
				
			||||||
 | 
					## RealField
 | 
				
			||||||
 | 
					## DecimalField
 | 
				
			||||||
 | 
					## DateField
 | 
				
			||||||
 | 
					## TimeField
 | 
				
			||||||
 | 
					## JsonField
 | 
				
			||||||
 | 
					## JsonbField
 | 
				
			||||||
 | 
					## VirtualField
 | 
				
			||||||
 | 
					## SortField
 | 
				
			||||||
 | 
					## PasswordField
 | 
				
			||||||
 | 
					## RadioField
 | 
				
			||||||
 | 
					## UidField
 | 
				
			||||||
 | 
					## CreatedByField
 | 
				
			||||||
 | 
					## UpdatedByField
 | 
				
			||||||
							
								
								
									
										50
									
								
								docs/api/operators.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								docs/api/operators.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					toc: menu
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Operators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## string
 | 
				
			||||||
 | 
					- includes
 | 
				
			||||||
 | 
					- notIncludes
 | 
				
			||||||
 | 
					- eq
 | 
				
			||||||
 | 
					- ne
 | 
				
			||||||
 | 
					- null
 | 
				
			||||||
 | 
					- notNull
 | 
				
			||||||
 | 
					## number
 | 
				
			||||||
 | 
					- eq
 | 
				
			||||||
 | 
					- ne
 | 
				
			||||||
 | 
					- gt
 | 
				
			||||||
 | 
					- gte
 | 
				
			||||||
 | 
					- lt
 | 
				
			||||||
 | 
					- lte
 | 
				
			||||||
 | 
					- between
 | 
				
			||||||
 | 
					- null
 | 
				
			||||||
 | 
					- notNull
 | 
				
			||||||
 | 
					## select
 | 
				
			||||||
 | 
					- eq
 | 
				
			||||||
 | 
					- ne
 | 
				
			||||||
 | 
					- in
 | 
				
			||||||
 | 
					- notIn
 | 
				
			||||||
 | 
					- null
 | 
				
			||||||
 | 
					- notNull
 | 
				
			||||||
 | 
					## multipleSelect
 | 
				
			||||||
 | 
					- match
 | 
				
			||||||
 | 
					- notMatch
 | 
				
			||||||
 | 
					- anyOf
 | 
				
			||||||
 | 
					- noneOf
 | 
				
			||||||
 | 
					- null
 | 
				
			||||||
 | 
					- notNull
 | 
				
			||||||
 | 
					## date
 | 
				
			||||||
 | 
					- dateOn
 | 
				
			||||||
 | 
					- dateNotOn
 | 
				
			||||||
 | 
					- dateBefore
 | 
				
			||||||
 | 
					- dateAfter
 | 
				
			||||||
 | 
					- dateNotBefore
 | 
				
			||||||
 | 
					- dateNotAfter
 | 
				
			||||||
 | 
					- null
 | 
				
			||||||
 | 
					- notNull
 | 
				
			||||||
 | 
					## association
 | 
				
			||||||
 | 
					- fieldName.$name
 | 
				
			||||||
 | 
					- exists
 | 
				
			||||||
 | 
					- notExists
 | 
				
			||||||
							
								
								
									
										19
									
								
								docs/api/plugin-manager.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								docs/api/plugin-manager.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					toc: menu
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# PluginManager
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## pm.constructor()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## pm.forEach()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## pm.load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## pm.download()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## pm.enable()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## pm.disable()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## pm.remove()
 | 
				
			||||||
							
								
								
									
										11
									
								
								docs/api/plugin.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								docs/api/plugin.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					toc: menu
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Plugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## plugin.constructor()
 | 
				
			||||||
 | 
					## plugin.enable()
 | 
				
			||||||
 | 
					## plugin.disable()
 | 
				
			||||||
 | 
					## plugin.upgrade()
 | 
				
			||||||
 | 
					## plugin.remove()
 | 
				
			||||||
							
								
								
									
										370
									
								
								docs/api/repository.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										370
									
								
								docs/api/repository.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,370 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					toc: menu
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Repository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## `repository.findMany()`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					查询数据,返回数组。无数据时为空数组,不返回 count。如果需要,请使用 [repository.paginate()](#repositorypaginate) 方法。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##### Definition
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					interface findMany<M extends Sequelize.Model> {
 | 
				
			||||||
 | 
					  (options: FindManyOptions): Promise<M[]>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface FindManyOptions extends Sequelize.FindOptions {
 | 
				
			||||||
 | 
					  // 数据过滤
 | 
				
			||||||
 | 
					  filter?: FilterOptions;
 | 
				
			||||||
 | 
					  // 输出结果显示哪些字段
 | 
				
			||||||
 | 
					  fields?: string[];
 | 
				
			||||||
 | 
					  // 输出结果不显示哪些字段
 | 
				
			||||||
 | 
					  expect?: string[];
 | 
				
			||||||
 | 
					  // 附加字段,用于控制关系字段的输出
 | 
				
			||||||
 | 
					  appends?: string[];
 | 
				
			||||||
 | 
					  // 排序,字段前面加上 “-” 表示降序
 | 
				
			||||||
 | 
					  sort?: string[];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 待补充
 | 
				
			||||||
 | 
					type FilterOptions = any;
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##### Examples
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					###### 全览
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					repository.findMany({
 | 
				
			||||||
 | 
					  // 过滤
 | 
				
			||||||
 | 
					  filter: {
 | 
				
			||||||
 | 
					    $and: [{ a: 5 }, { b: 6 }],            // (a = 5) AND (b = 6)
 | 
				
			||||||
 | 
					    $or: [{ a: 5 }, { b: 6 }],             // (a = 5) OR (b = 6)
 | 
				
			||||||
 | 
					    someAttribute: {
 | 
				
			||||||
 | 
					      // Basics
 | 
				
			||||||
 | 
					      $eq: 3,                              // = 3
 | 
				
			||||||
 | 
					      $ne: 20,                             // != 20
 | 
				
			||||||
 | 
					      $is: null,                           // IS NULL
 | 
				
			||||||
 | 
					      $not: true,                          // IS NOT TRUE
 | 
				
			||||||
 | 
					      $gt: 6,                              // > 6
 | 
				
			||||||
 | 
					      $gte: 6,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 支持使用逗号间隔
 | 
				
			||||||
 | 
					    'someAttribute.$eq': 3,
 | 
				
			||||||
 | 
					    // 内嵌的,一般是关系数据
 | 
				
			||||||
 | 
					    nested: {
 | 
				
			||||||
 | 
					      someAttribute: {},
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 同上,也支持使用逗号间隔
 | 
				
			||||||
 | 
					    'nested.someAttribute': {
 | 
				
			||||||
 | 
					      // 同上
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  // 字段白名单
 | 
				
			||||||
 | 
					  fields: [],
 | 
				
			||||||
 | 
					  // 附加字段,主要用于附加关系字段
 | 
				
			||||||
 | 
					  appends: [],
 | 
				
			||||||
 | 
					  // 字段黑名单
 | 
				
			||||||
 | 
					  expect: [],
 | 
				
			||||||
 | 
					  // 排序
 | 
				
			||||||
 | 
					  sort: ['-createdAt', 'updatedAt'],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					###### filter 参数示例说明
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					以文章和标签为例,文章和标签的 collection 如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					const Tag = db.collection({
 | 
				
			||||||
 | 
					  name: 'tags',
 | 
				
			||||||
 | 
					  fields: [
 | 
				
			||||||
 | 
					    { type: 'string', name: 'name' },
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Post = db.collection({
 | 
				
			||||||
 | 
					  name: 'posts',
 | 
				
			||||||
 | 
					  fields: [
 | 
				
			||||||
 | 
					    { type: 'string', name: 'name' },
 | 
				
			||||||
 | 
					    { type: 'text', name: 'content' },
 | 
				
			||||||
 | 
					    { type: 'belongsToMany', name: 'tags' },
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					最简单的筛选过滤
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await Post.repository.findMany({
 | 
				
			||||||
 | 
					  filter: {
 | 
				
			||||||
 | 
					    'name': 'post1',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					支持多种 Operators,以 `$` 开头。[更多内容,查阅 Operators 章节](operators.md)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await Post.repository.findMany({
 | 
				
			||||||
 | 
					  filter: {
 | 
				
			||||||
 | 
					    'name.$includes': 'post1',
 | 
				
			||||||
 | 
					    // 等同于
 | 
				
			||||||
 | 
					    name: {
 | 
				
			||||||
 | 
					      $includes: 'post1',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					支持关系字段过滤,可以使用 dot 来表示层级结构
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await Post.repository.findMany({
 | 
				
			||||||
 | 
					  filter: {
 | 
				
			||||||
 | 
					    'tags.name': 'tag1',
 | 
				
			||||||
 | 
					    // 等同于
 | 
				
			||||||
 | 
					    tags: {
 | 
				
			||||||
 | 
					      name: 'tag1',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					多个同一关系字段的过滤可以写在一起
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await Post.repository.findMany({
 | 
				
			||||||
 | 
					  filter: {
 | 
				
			||||||
 | 
					    'tags': {
 | 
				
			||||||
 | 
					      'name.$includes': 'tag1',
 | 
				
			||||||
 | 
					      'createdAt.$dateOn': '2020-10-28',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					同时也支持 and、or 逻辑运算符
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await Post.repository.findMany({
 | 
				
			||||||
 | 
					  filter: {
 | 
				
			||||||
 | 
					    $and: [
 | 
				
			||||||
 | 
					      // 一个 Object 只写一个条件
 | 
				
			||||||
 | 
					      { name: 'post1' },
 | 
				
			||||||
 | 
					      // 支持关系字段(非常重要)
 | 
				
			||||||
 | 
					      { 'tags.name.$includes': 'tag1' },
 | 
				
			||||||
 | 
					      { 'tags.name.$includes': 'tag2' },
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					###### sort 参数示例说明
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					指定一组数据的排序,倒序时在字段前加上减号 `-`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await Post.repository.findMany({
 | 
				
			||||||
 | 
					  // 创建日期倒序
 | 
				
			||||||
 | 
					  sort: ['-createdAt'],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					可以设置多个排序规则
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await Post.repository.findMany({
 | 
				
			||||||
 | 
					  // 创建日期倒序,ID 正序
 | 
				
			||||||
 | 
					  sort: ['-createdAt', 'id'],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					也可以是关系表的字段
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await Post.repository.findMany({
 | 
				
			||||||
 | 
					  // 标签名正序,文章创建日期倒序
 | 
				
			||||||
 | 
					  sort: ['tags.name', '-createdAt'],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					###### fields 参数示例说明
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `fields` 显示哪些字段
 | 
				
			||||||
 | 
					- `expect` 不显示哪些字段
 | 
				
			||||||
 | 
					- `appends` 附加哪些字段
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					如果并未指定 fields,输出所有 Attributes,Associations 字段并不输出
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await Post.repository.findMany();
 | 
				
			||||||
 | 
					// [{ id, name, content, createdAt, updatedAt }]
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					只输出指定字段时,可以用 fields
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await Post.repository.findMany({
 | 
				
			||||||
 | 
					  fields: ['name'],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					// [{ name }]
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					当 fields 里有关系字段时,按默认情况输出
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await Post.repository.findMany({
 | 
				
			||||||
 | 
					  fields: ['id', 'name', 'tags'],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					// 
 | 
				
			||||||
 | 
					// [{ id, name, createdAt, updatedAt, tags: [{ id, name, createdAt, updatedAt }] }]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					可以只输出关系数据的某个字段
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await Post.repository.findMany({
 | 
				
			||||||
 | 
					  fields: ['id', 'name', 'tags.name'],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					// [{ id, name, tags: [{ name }] }]
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					排除某些字段时,可以使用 expect
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await Post.repository.findMany({
 | 
				
			||||||
 | 
					  expect: ['content'],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					// [{ id, name, createdAt, updatedAt }]
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Attributes 不变,只附加 Associations 进来时,可以使用 appends
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await Post.repository.findMany({
 | 
				
			||||||
 | 
					  appends: ['tags'],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					// [{ id, name, content, createdAt, updatedAt, tags: [{ id, name, createdAt, updatedAt }] }]
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					如果某个字段只用在 filter 里,但并没有出现在 fields 里,不应该被输出
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await Post.repository.findMany({
 | 
				
			||||||
 | 
					  filter: {
 | 
				
			||||||
 | 
					    'tags.name': 'tag1',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					// 输出所有的 Attributes,但不输出 tags
 | 
				
			||||||
 | 
					// [{ id, name, content, createdAt, updatedAt }]
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					如果某个字段只用在 sort 里,但并没有出现在 fields 里,也不应该被输出
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await Post.repository.findMany({
 | 
				
			||||||
 | 
					  sort: ['-tags.createdAt']
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					// 输出所有的 Attributes,但不输出 tags
 | 
				
			||||||
 | 
					// [{ id, name, content, createdAt, updatedAt }]
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## `repository.paginate()`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					按分页查询数据,并返回所有符合的数据总数。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##### Definition
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					interface paginate<M extends Sequelize.Model> {
 | 
				
			||||||
 | 
					  (options: PaginateOptions): Promise<[ M[], number ]>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface PaginateOptions extends Sequelize.FindAndCountOptions {
 | 
				
			||||||
 | 
					  // 数据过滤
 | 
				
			||||||
 | 
					  filter?: FilterOptions;
 | 
				
			||||||
 | 
					  // 输出结果显示哪些字段
 | 
				
			||||||
 | 
					  fields?: string[];
 | 
				
			||||||
 | 
					  // 输出结果不显示哪些字段
 | 
				
			||||||
 | 
					  expect?: string[];
 | 
				
			||||||
 | 
					  // 附加字段,用于控制关系字段的输出
 | 
				
			||||||
 | 
					  appends?: string[];
 | 
				
			||||||
 | 
					  // 排序,字段前面加上 “-” 表示降序
 | 
				
			||||||
 | 
					  sort?: string[];
 | 
				
			||||||
 | 
					  // 当前页,默认为 1
 | 
				
			||||||
 | 
					  page?: number;
 | 
				
			||||||
 | 
					  // 当前页最大数量,默认为 20
 | 
				
			||||||
 | 
					  pageSize?: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##### Examples
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					大部分参数与 [repository.findMany()](#repositoryfindmany) 一致,所以这里只列举 page 和 pageSize 的例子。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					不填写参数时,默认 page=1,pageSize=20。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					repository.paginate();
 | 
				
			||||||
 | 
					// [[{ id, name, content, createdAt, updatedAt }], 50]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const [models, count] = await repository.paginate();
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## `repository.findOne()`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##### Definition
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					interface findOne<M extends Sequelize.Model> {
 | 
				
			||||||
 | 
					  (options: FindOneOptions): Promise<[ M[], number ]>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface FindOneOptions extends FindManyOptions {
 | 
				
			||||||
 | 
					  // 数据过滤
 | 
				
			||||||
 | 
					  filter?: FilterOptions;
 | 
				
			||||||
 | 
					  // 输出结果显示哪些字段
 | 
				
			||||||
 | 
					  fields?: string[];
 | 
				
			||||||
 | 
					  // 输出结果不显示哪些字段
 | 
				
			||||||
 | 
					  expect?: string[];
 | 
				
			||||||
 | 
					  // 附加字段,用于控制关系字段的输出
 | 
				
			||||||
 | 
					  appends?: string[];
 | 
				
			||||||
 | 
					  // 排序,字段前面加上 “-” 表示降序
 | 
				
			||||||
 | 
					  sort?: string[];
 | 
				
			||||||
 | 
					  // 通过 pk 过滤
 | 
				
			||||||
 | 
					  filterByPk?: number | string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##### Examples
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					大部分参数与 [repository.findMany()](#repositoryfindmany) 一致。这里只列举 filterByPk 的例子。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					await repository.findOne({
 | 
				
			||||||
 | 
					  filterByPk: 1,
 | 
				
			||||||
 | 
					  // 等同于
 | 
				
			||||||
 | 
					  filter: {
 | 
				
			||||||
 | 
					    [Model.primaryKeyAttribute]: 1,
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## repository.create()
 | 
				
			||||||
 | 
					## repository.update()
 | 
				
			||||||
 | 
					## repository.destroy()
 | 
				
			||||||
 | 
					## repository.relation().of()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### findMany()
 | 
				
			||||||
 | 
					### findOne()
 | 
				
			||||||
 | 
					### create()
 | 
				
			||||||
 | 
					### update()
 | 
				
			||||||
 | 
					### destroy()
 | 
				
			||||||
 | 
					### set()
 | 
				
			||||||
 | 
					### add()
 | 
				
			||||||
 | 
					### remove()
 | 
				
			||||||
 | 
					### toggle()
 | 
				
			||||||
							
								
								
									
										0
									
								
								docs/api/resourcer.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/api/resourcer.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										1
									
								
								docs/api/rest-api.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docs/api/rest-api.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					# REST API
 | 
				
			||||||
							
								
								
									
										6
									
								
								docs/components/collection-fields/attachment.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								docs/components/collection-fields/attachment.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					group:
 | 
				
			||||||
 | 
					  title: Collection Fields
 | 
				
			||||||
 | 
					  path: /components/collection-fields
 | 
				
			||||||
 | 
					  order: 3
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
							
								
								
									
										6
									
								
								docs/components/collection-fields/attachment.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								docs/components/collection-fields/attachment.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					group:
 | 
				
			||||||
 | 
					  title: 字段组件
 | 
				
			||||||
 | 
					  path: /zh-CN/components/collection-fields
 | 
				
			||||||
 | 
					  order: 3
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
							
								
								
									
										0
									
								
								docs/components/collection-fields/checkbox-group.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/checkbox-group.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/checkbox.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/checkbox.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/china-region.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/china-region.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/created-at.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/created-at.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/created-by.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/created-by.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/datetime.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/datetime.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/email.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/email.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/icon.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/icon.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/link-to.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/link-to.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/markdown.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/markdown.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/number.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/number.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/password.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/password.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/percent.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/percent.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/phone.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/phone.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/radio-group.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/radio-group.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/select.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/select.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										4
									
								
								docs/components/collection-fields/string.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								docs/components/collection-fields/string.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					group:
 | 
				
			||||||
 | 
					  path: /components/collection-fields
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
							
								
								
									
										0
									
								
								docs/components/collection-fields/sub-table.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/sub-table.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/textarea.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/textarea.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/time.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/time.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/updated-at.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/updated-at.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/collection-fields/updated-by.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/collection-fields/updated-by.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										15
									
								
								docs/components/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								docs/components/index.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					title: Overview
 | 
				
			||||||
 | 
					order: 0
 | 
				
			||||||
 | 
					nav:
 | 
				
			||||||
 | 
					  title: Components
 | 
				
			||||||
 | 
					  order: 4
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Components
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NocoBase 的客户端组件总共有三类:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 通过 createRouteSwitch 创建的路由组件,如 Layou、Page
 | 
				
			||||||
 | 
					- 通过 createCollectionField 创建的字段组件,用于扩展字段
 | 
				
			||||||
 | 
					- 通过 createSchemaComponent 创建的 JSON Schema 组件,可以是任意东西,比如表格、表单、日历、看板等。Schema Component 可用于 Route Component 或 Collection Field 中。
 | 
				
			||||||
							
								
								
									
										15
									
								
								docs/components/index.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								docs/components/index.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					title: 概述
 | 
				
			||||||
 | 
					order: 0
 | 
				
			||||||
 | 
					nav:
 | 
				
			||||||
 | 
					  title: 组件
 | 
				
			||||||
 | 
					  order: 4
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NocoBase 的客户端组件总共有三类:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 通过 createRouteSwitch 创建的路由组件,如 Layou、Page
 | 
				
			||||||
 | 
					- 通过 createCollectionField 创建的字段组件,用于扩展字段
 | 
				
			||||||
 | 
					- 通过 createSchemaComponent 创建的 JSON Schema 组件,可以是任意东西,比如表格、表单、日历、看板等。  
 | 
				
			||||||
 | 
					  Schema Component 可用于 Route Component 或 Collection Field 中。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								docs/components/route-switch/admin-layout.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								docs/components/route-switch/admin-layout.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					order: 3
 | 
				
			||||||
 | 
					title: AdminLayout
 | 
				
			||||||
 | 
					group:
 | 
				
			||||||
 | 
					  title: Route Components
 | 
				
			||||||
 | 
					  path: /components/route-components
 | 
				
			||||||
 | 
					  order: 1
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# AdminLayout
 | 
				
			||||||
							
								
								
									
										10
									
								
								docs/components/route-switch/admin-layout.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								docs/components/route-switch/admin-layout.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					order: 3
 | 
				
			||||||
 | 
					title: AdminLayout
 | 
				
			||||||
 | 
					group:
 | 
				
			||||||
 | 
					  title: 路由组件
 | 
				
			||||||
 | 
					  path: /zh-CN/components/route-components
 | 
				
			||||||
 | 
					  order: 1
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# AdminLayout
 | 
				
			||||||
							
								
								
									
										9
									
								
								docs/components/route-switch/auth-layout.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								docs/components/route-switch/auth-layout.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					order: 2
 | 
				
			||||||
 | 
					title: AuthLayout
 | 
				
			||||||
 | 
					group:
 | 
				
			||||||
 | 
					  path: /components/route-components
 | 
				
			||||||
 | 
					  order: 1
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# AuthLayout
 | 
				
			||||||
							
								
								
									
										8
									
								
								docs/components/schema-components/action.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								docs/components/schema-components/action.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					group:
 | 
				
			||||||
 | 
					  title: Schema Components
 | 
				
			||||||
 | 
					  path: /components/schema-components
 | 
				
			||||||
 | 
					  order: 2
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Action
 | 
				
			||||||
							
								
								
									
										8
									
								
								docs/components/schema-components/action.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								docs/components/schema-components/action.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					group:
 | 
				
			||||||
 | 
					  title: Schema 组件
 | 
				
			||||||
 | 
					  path: /zh-CN/components/schema-components
 | 
				
			||||||
 | 
					  order: 2
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Action
 | 
				
			||||||
							
								
								
									
										1
									
								
								docs/components/schema-components/add-new.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docs/components/schema-components/add-new.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					# AddNew
 | 
				
			||||||
							
								
								
									
										0
									
								
								docs/components/schema-components/block-item.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/block-item.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/calendar.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/calendar.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/card-item.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/card-item.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/cascader.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/cascader.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/chart.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/chart.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/checkbox.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/checkbox.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/collection.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/collection.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/color-select.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/color-select.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/date-picker.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/date-picker.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/filter.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/filter.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/form-item.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/form-item.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/form.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/form.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/grid.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/grid.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/icon-picker.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/icon-picker.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/input-number.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/input-number.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										5
									
								
								docs/components/schema-components/input.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								docs/components/schema-components/input.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					title: Input
 | 
				
			||||||
 | 
					group:
 | 
				
			||||||
 | 
					  path: /components/schema-components
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
							
								
								
									
										0
									
								
								docs/components/schema-components/kanban.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/kanban.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/list-picker.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/list-picker.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/markdown.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/markdown.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/menu.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/menu.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/password.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/password.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/radio.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/radio.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/select.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/select.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/table.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/table.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/tabs.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/tabs.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/time-picker.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/time-picker.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/tree-select.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/tree-select.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								docs/components/schema-components/upload.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/components/schema-components/upload.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										8
									
								
								docs/examples/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								docs/examples/index.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					sidemenu: false
 | 
				
			||||||
 | 
					nav:
 | 
				
			||||||
 | 
					  title: Examples
 | 
				
			||||||
 | 
					  order: 99
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Coming soon...
 | 
				
			||||||
							
								
								
									
										8
									
								
								docs/examples/index.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								docs/examples/index.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					sidemenu: false
 | 
				
			||||||
 | 
					nav:
 | 
				
			||||||
 | 
					  title: 示例
 | 
				
			||||||
 | 
					  order: 99
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					待补充...
 | 
				
			||||||
							
								
								
									
										324
									
								
								docs/guide/basic/client-components.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										324
									
								
								docs/guide/basic/client-components.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,324 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					order: 2
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Client Components
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					为了让更多非开发人员也能参与进来,NocoBase 提供了配套的客户端 —— 无代码的可视化界面。客户端界面非常灵活,由不同组件构成,分为了三类:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 通过 createRouteSwitch 创建的路由组件,如 Layout、Page
 | 
				
			||||||
 | 
					- 通过 createCollectionField 创建的字段组件,用于扩展字段
 | 
				
			||||||
 | 
					- 通过 createSchemaComponent 创建的 JSON Schema 组件,可以是任意东西,比如表格、表单、日历、看板等
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[更多组件内容,查看组件章节](#)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 组件树结构
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					界面是由组件构成的组件树,结构如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					// 布局
 | 
				
			||||||
 | 
					<Layout>
 | 
				
			||||||
 | 
					  // 页面
 | 
				
			||||||
 | 
					  <Page>
 | 
				
			||||||
 | 
					    // 栅格
 | 
				
			||||||
 | 
					    <Grid>
 | 
				
			||||||
 | 
					      // 区块,以表格为例
 | 
				
			||||||
 | 
					      <Table>
 | 
				
			||||||
 | 
					        // 配置工具栏
 | 
				
			||||||
 | 
					        <Table.DesignableBar/>
 | 
				
			||||||
 | 
					        // 操作栏
 | 
				
			||||||
 | 
					        <Table.ActionBar>
 | 
				
			||||||
 | 
					          // 操作
 | 
				
			||||||
 | 
					          <Action/>
 | 
				
			||||||
 | 
					          <Action/>
 | 
				
			||||||
 | 
					        </Table.ActionBar>
 | 
				
			||||||
 | 
					        // 内容区
 | 
				
			||||||
 | 
					        <Table.Content>
 | 
				
			||||||
 | 
					          <Table.Column>
 | 
				
			||||||
 | 
					            // 表格列的字段
 | 
				
			||||||
 | 
					            <CollectionField />
 | 
				
			||||||
 | 
					          </Table.Column>
 | 
				
			||||||
 | 
					          <Table.Column>
 | 
				
			||||||
 | 
					            <CollectionField />
 | 
				
			||||||
 | 
					          </Table.Column>
 | 
				
			||||||
 | 
					        </Table.Content>
 | 
				
			||||||
 | 
					      </Table>
 | 
				
			||||||
 | 
					    </Grid>
 | 
				
			||||||
 | 
					    <AddNew />
 | 
				
			||||||
 | 
					  </Page>
 | 
				
			||||||
 | 
					</Layout>
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					注:以上例子只为表达组件树的结构和组件之间的关系,实际代码并不如此。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					接下来,我们来详细的介绍各部分的概念。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 布局和页面
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					页面是可以通过地址访问的网页,不同页面之间可能具有相同的页眉、页脚和导航,通常我们会把这些公共的内容放在布局组件里。例如,初始化的 NocoBase 提供了两个布局组件,如图所示:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					图
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- AuthLayout:无需登录就能访问,一般用于嵌入登录、注册、忘记密码等页面。
 | 
				
			||||||
 | 
					- AdminLayout:需要登录,管理后台的所有页面。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					布局和页面组件通过 createRouteSwitch 注册,更多扩展内容点此查看。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 页面内容排版
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					对开发者来说,页面内容的编写是自由的,不过为了方便对页面内容进行排版,提供了两种排版方式:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 简易的上下结构
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					<Page>
 | 
				
			||||||
 | 
					  <BlockItem />
 | 
				
			||||||
 | 
					  <BlockItem />
 | 
				
			||||||
 | 
					  <BlockItem />
 | 
				
			||||||
 | 
					</Page>
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					例子如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					// 示例 
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 可拖拽的栅格
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					<Page>
 | 
				
			||||||
 | 
					  <Grid>
 | 
				
			||||||
 | 
					    <Grid.Row>
 | 
				
			||||||
 | 
					      <Grid.Col>
 | 
				
			||||||
 | 
					        <BlockItem />
 | 
				
			||||||
 | 
					      </Grid.Col>
 | 
				
			||||||
 | 
					      <Grid.Col>
 | 
				
			||||||
 | 
					        <BlockItem />
 | 
				
			||||||
 | 
					      </Grid.Col>
 | 
				
			||||||
 | 
					    </Grid.Row>
 | 
				
			||||||
 | 
					    <Grid.Row>
 | 
				
			||||||
 | 
					      <Grid.Col>
 | 
				
			||||||
 | 
					        <BlockItem />
 | 
				
			||||||
 | 
					      </Grid.Col>
 | 
				
			||||||
 | 
					      <Grid.Col>
 | 
				
			||||||
 | 
					        <BlockItem />
 | 
				
			||||||
 | 
					      </Grid.Col>
 | 
				
			||||||
 | 
					    </Grid.Row>
 | 
				
			||||||
 | 
					  </Grid>
 | 
				
			||||||
 | 
					</Page>
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					栅格组件 Grid 基于行(Grid.Row)和列(Grid.Col)来定义区块的外部框架。例子如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					// 示例 
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## AddNew
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AddNew 是页面可视化配置最重要的操作按钮,更多关于 AddNew 的内容点此查看
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 区块 - Block
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					区块一般放在页面里,可以是任意东西,包括文字、附件、表格、表单、日历、看板等等。一个完整的区块由三部分组成:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 内容区 Content,区块的主体
 | 
				
			||||||
 | 
					- 操作栏 ActionBar,可以放置各种操作按钮,用于操作区块数据(可选)
 | 
				
			||||||
 | 
					- 配置工具栏 DesignableBar,操作区块配置的按钮(可选)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					以表格区块为例,组件结构如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					<Table>
 | 
				
			||||||
 | 
					  <Table.DesignableBar />
 | 
				
			||||||
 | 
					  <Table.ActionBar />
 | 
				
			||||||
 | 
					  <Table.Content />
 | 
				
			||||||
 | 
					</Table>
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					具体形态:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					//示例(这里放上一个表示区块结构的示例)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					区块有几种类型:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 数据类型,用于展示数据表的数据,如表格、日历、看板、表单、详情等。
 | 
				
			||||||
 | 
					- 多媒体,用于丰富页面内容,如文本段、附件等。暂时只有一个简易的 Markdown。
 | 
				
			||||||
 | 
					- 图表,用于展示数据统计。
 | 
				
			||||||
 | 
					- 模板,可直接将某些成品模板化,直接应用到页面上。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					区块可以任意扩展,如何扩展查看 createSchemaComponent 章节。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 操作栏 - ActionBar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					操作栏是一系列操作的集合,一般用于区块内部。用户发出操作指令,程序做出改变,并将结果响应在区块内容区。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					例如:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					表格,内容区是一个表格,操作区会放置一些操作按钮,如筛选、新增、删除、导出等
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					// 示例(放一个简易的表格,把操作栏重点突出一下)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					详情,内容区是详情数据,操作区会放置编辑、导出等按钮
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					// 示例(放一个简易的详情,把操作栏重点突出一下)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					不同的区块,操作栏的按钮可能不同。操作栏的按钮也是可以自定义的,具体内容查看操作章节。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 操作 - Action
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					操作是封装的一段指令,一般需要用户参与。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					例如:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 删除数据,需要用户选中待删除数据,再触发删除指令
 | 
				
			||||||
 | 
					- 筛选数据,需要用户填写筛选项,再触发筛选指令
 | 
				
			||||||
 | 
					- 新增数据,需要用户填写数据之后提交,触发新增操作指令
 | 
				
			||||||
 | 
					- 查看详情,用户点击操作按钮,弹窗查看详情或当前窗口打开详情页查看
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					最简单的操作,只需要绑定一段指令即可,简单来说就是指定一段函数,无需传参。组件结构如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					<Action useAction={useAction} />
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					大部分的操作指令需要用户提供参数,如新增数据操作,需要用户填写数据,填写数据一般需要弹出表单,用户填写完数据,点击提交,才触发操作指令。组件结构如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					<Action useAction={useAction}>
 | 
				
			||||||
 | 
					  {/* 这是个弹窗表单,内置提交按钮,点击提交触发操作指令,具体代码省略 */}
 | 
				
			||||||
 | 
					  <Action.Modal x-decorator={'Form'}></Action.Modal>
 | 
				
			||||||
 | 
					</Action>
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					一个完整的操作大概分为两步:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 为 Action 绑定一段指令
 | 
				
			||||||
 | 
					- 如果指令需要用户提供参数,需要提供交互界面,目前内置的有:
 | 
				
			||||||
 | 
					   - Action.Drawer:抽屉
 | 
				
			||||||
 | 
					   - Action.Modal:对话框
 | 
				
			||||||
 | 
					   - Action.Popover:气泡
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					操作是 NocoBase 里非常重要的一个概念,更多详情点此查看
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 配置工具栏 - DesignableBar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					所有的 Schema Component 都可以绑定自己的配置工具栏(DesignableBar),用于修改当前组件的 Schema。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**什么是 Schema Component?**  
 | 
				
			||||||
 | 
					通过 Schema 协议编写的类 JSON Schema 格式的组件,如:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  type: 'void',
 | 
				
			||||||
 | 
					   'x-Component': 'Hello',
 | 
				
			||||||
 | 
					  'x-designable-bar': 'Hello.DesignableBar',
 | 
				
			||||||
 | 
					  'x-dect': 'CardItem',
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					举几个例子,如:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					表单字段的 JSON Schema
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					const schema = {
 | 
				
			||||||
 | 
					  type: 'string',
 | 
				
			||||||
 | 
					  'x-component': 'Input',
 | 
				
			||||||
 | 
					  'x-decorator': 'FormItem',
 | 
				
			||||||
 | 
					  'x-designable-bar': 'Form.Field.DesignableBar',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					表单项的配置工具栏 `Form.Field.DesignableBar` 的效果
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					表格的 JSON Schema
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					const schema = {
 | 
				
			||||||
 | 
					  type: 'array',
 | 
				
			||||||
 | 
					  'x-component': 'Table',
 | 
				
			||||||
 | 
					  'x-decorator': 'CardItem',
 | 
				
			||||||
 | 
					  'x-designable-bar': 'Table.DesignableBar',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					表格配置工具栏 `Table.DesignableBar` 的效果
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					菜单项的 JSON Schema:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					const schema = {
 | 
				
			||||||
 | 
					  type: 'array',
 | 
				
			||||||
 | 
					  'x-component': 'Menu.Item',
 | 
				
			||||||
 | 
					  'x-designable-bar': 'Menu.Item.DesignableBar',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					菜单项配置工具栏 `Menu.Item.DesignableBar` 的效果
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					更多配置工具栏详情点此查看
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 字段组件 - CollectionField
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					字段组件的配置参数可能非常多,在不同数据区块里也可能用到同一个字段组件,为了减少代码重复,NocoBase 里,将字段组件的配置交由数据表统一管理。一处配置,多处使用。数据区块里直接引用字段组件,如果有其他不同参数再另行扩展。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					<Table>
 | 
				
			||||||
 | 
					  // 原生态的写法
 | 
				
			||||||
 | 
					  <Table.Column title={'姓名'}>
 | 
				
			||||||
 | 
					    <Input {...others} name="name" readPretty={true}/>
 | 
				
			||||||
 | 
					  </Table.Column>
 | 
				
			||||||
 | 
					  // 简化之后的字段引用
 | 
				
			||||||
 | 
					  <Table.Column>
 | 
				
			||||||
 | 
					    <CollectionField name="name"/>
 | 
				
			||||||
 | 
					  </Table.Column>
 | 
				
			||||||
 | 
					</Table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<Form>
 | 
				
			||||||
 | 
					  // 如果在表格里也用到,再写一遍
 | 
				
			||||||
 | 
					  <FormItem title={'姓名'}>
 | 
				
			||||||
 | 
					    <Input {...others} name="name"/>
 | 
				
			||||||
 | 
					  </FormItem>
 | 
				
			||||||
 | 
					  // 字段引用,只需要提供 name 即可 
 | 
				
			||||||
 | 
					  <FormItem>
 | 
				
			||||||
 | 
					    <CollectionField name="name"/>
 | 
				
			||||||
 | 
					  </FormItem>
 | 
				
			||||||
 | 
					</Form>
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					字段组件有三种显示状态:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 可填写 - editable
 | 
				
			||||||
 | 
					- 不可填写 - disabled
 | 
				
			||||||
 | 
					- 阅读模式 - read-pretty
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					以单行文本(Input)为例:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					// 示例(Input 的三种显示状态)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 示例待补充
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**为什么字段有多种显示状态?**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 在表单中,一般情况字段为可填写状态(editable),但如果只供查看,这时候就会把字段设置为 disabled 或 read-pretty。
 | 
				
			||||||
 | 
					- 在表格中,一般情况字段为阅读模式(read-pretty),但如果需要在表格内快捷编辑,又可以动态的将某个字段激活为 editable。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					字段组件可以任意扩展,如何扩展查看 createCollectionField 章节。
 | 
				
			||||||
							
								
								
									
										324
									
								
								docs/guide/basic/client-components.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										324
									
								
								docs/guide/basic/client-components.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,324 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					order: 2
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 客户端组件
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					为了让更多非开发人员也能参与进来,NocoBase 提供了配套的客户端 —— 无代码的可视化界面。客户端界面非常灵活,由不同组件构成,分为了三类:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 通过 createRouteSwitch 创建的路由组件,如 Layout、Page
 | 
				
			||||||
 | 
					- 通过 createCollectionField 创建的字段组件,用于扩展字段
 | 
				
			||||||
 | 
					- 通过 createSchemaComponent 创建的 JSON Schema 组件,可以是任意东西,比如表格、表单、日历、看板等
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[更多组件内容,查看组件章节](#)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 组件树结构
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					界面是由组件构成的组件树,结构如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					// 布局
 | 
				
			||||||
 | 
					<Layout>
 | 
				
			||||||
 | 
					  // 页面
 | 
				
			||||||
 | 
					  <Page>
 | 
				
			||||||
 | 
					    // 栅格
 | 
				
			||||||
 | 
					    <Grid>
 | 
				
			||||||
 | 
					      // 区块,以表格为例
 | 
				
			||||||
 | 
					      <Table>
 | 
				
			||||||
 | 
					        // 配置工具栏
 | 
				
			||||||
 | 
					        <Table.DesignableBar/>
 | 
				
			||||||
 | 
					        // 操作栏
 | 
				
			||||||
 | 
					        <Table.ActionBar>
 | 
				
			||||||
 | 
					          // 操作
 | 
				
			||||||
 | 
					          <Action/>
 | 
				
			||||||
 | 
					          <Action/>
 | 
				
			||||||
 | 
					        </Table.ActionBar>
 | 
				
			||||||
 | 
					        // 内容区
 | 
				
			||||||
 | 
					        <Table.Content>
 | 
				
			||||||
 | 
					          <Table.Column>
 | 
				
			||||||
 | 
					            // 表格列的字段
 | 
				
			||||||
 | 
					            <CollectionField />
 | 
				
			||||||
 | 
					          </Table.Column>
 | 
				
			||||||
 | 
					          <Table.Column>
 | 
				
			||||||
 | 
					            <CollectionField />
 | 
				
			||||||
 | 
					          </Table.Column>
 | 
				
			||||||
 | 
					        </Table.Content>
 | 
				
			||||||
 | 
					      </Table>
 | 
				
			||||||
 | 
					    </Grid>
 | 
				
			||||||
 | 
					    <AddNew />
 | 
				
			||||||
 | 
					  </Page>
 | 
				
			||||||
 | 
					</Layout>
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					注:以上例子只为表达组件树的结构和组件之间的关系,实际代码并不如此。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					接下来,我们来详细的介绍各部分的概念。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 布局和页面
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					页面是可以通过地址访问的网页,不同页面之间可能具有相同的页眉、页脚和导航,通常我们会把这些公共的内容放在布局组件里。例如,初始化的 NocoBase 提供了两个布局组件,如图所示:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					图
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- AuthLayout:无需登录就能访问,一般用于嵌入登录、注册、忘记密码等页面。
 | 
				
			||||||
 | 
					- AdminLayout:需要登录,管理后台的所有页面。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					布局和页面组件通过 createRouteSwitch 注册,更多扩展内容点此查看。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 页面内容排版
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					对开发者来说,页面内容的编写是自由的,不过为了方便对页面内容进行排版,提供了两种排版方式:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 简易的上下结构
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					<Page>
 | 
				
			||||||
 | 
					  <BlockItem />
 | 
				
			||||||
 | 
					  <BlockItem />
 | 
				
			||||||
 | 
					  <BlockItem />
 | 
				
			||||||
 | 
					</Page>
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					例子如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					// 示例 
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 可拖拽的栅格
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					<Page>
 | 
				
			||||||
 | 
					  <Grid>
 | 
				
			||||||
 | 
					    <Grid.Row>
 | 
				
			||||||
 | 
					      <Grid.Col>
 | 
				
			||||||
 | 
					        <BlockItem />
 | 
				
			||||||
 | 
					      </Grid.Col>
 | 
				
			||||||
 | 
					      <Grid.Col>
 | 
				
			||||||
 | 
					        <BlockItem />
 | 
				
			||||||
 | 
					      </Grid.Col>
 | 
				
			||||||
 | 
					    </Grid.Row>
 | 
				
			||||||
 | 
					    <Grid.Row>
 | 
				
			||||||
 | 
					      <Grid.Col>
 | 
				
			||||||
 | 
					        <BlockItem />
 | 
				
			||||||
 | 
					      </Grid.Col>
 | 
				
			||||||
 | 
					      <Grid.Col>
 | 
				
			||||||
 | 
					        <BlockItem />
 | 
				
			||||||
 | 
					      </Grid.Col>
 | 
				
			||||||
 | 
					    </Grid.Row>
 | 
				
			||||||
 | 
					  </Grid>
 | 
				
			||||||
 | 
					</Page>
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					栅格组件 Grid 基于行(Grid.Row)和列(Grid.Col)来定义区块的外部框架。例子如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					// 示例 
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## AddNew
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AddNew 是页面可视化配置最重要的操作按钮,更多关于 AddNew 的内容点此查看
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 区块 - Block
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					区块一般放在页面里,可以是任意东西,包括文字、附件、表格、表单、日历、看板等等。一个完整的区块由三部分组成:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 内容区 Content,区块的主体
 | 
				
			||||||
 | 
					- 操作栏 ActionBar,可以放置各种操作按钮,用于操作区块数据(可选)
 | 
				
			||||||
 | 
					- 配置工具栏 DesignableBar,操作区块配置的按钮(可选)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					以表格区块为例,组件结构如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					<Table>
 | 
				
			||||||
 | 
					  <Table.DesignableBar />
 | 
				
			||||||
 | 
					  <Table.ActionBar />
 | 
				
			||||||
 | 
					  <Table.Content />
 | 
				
			||||||
 | 
					</Table>
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					具体形态:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					//示例(这里放上一个表示区块结构的示例)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					区块有几种类型:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 数据类型,用于展示数据表的数据,如表格、日历、看板、表单、详情等。
 | 
				
			||||||
 | 
					- 多媒体,用于丰富页面内容,如文本段、附件等。暂时只有一个简易的 Markdown。
 | 
				
			||||||
 | 
					- 图表,用于展示数据统计。
 | 
				
			||||||
 | 
					- 模板,可直接将某些成品模板化,直接应用到页面上。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					区块可以任意扩展,如何扩展查看 createSchemaComponent 章节。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 操作栏 - ActionBar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					操作栏是一系列操作的集合,一般用于区块内部。用户发出操作指令,程序做出改变,并将结果响应在区块内容区。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					例如:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					表格,内容区是一个表格,操作区会放置一些操作按钮,如筛选、新增、删除、导出等
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					// 示例(放一个简易的表格,把操作栏重点突出一下)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					详情,内容区是详情数据,操作区会放置编辑、导出等按钮
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					// 示例(放一个简易的详情,把操作栏重点突出一下)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					不同的区块,操作栏的按钮可能不同。操作栏的按钮也是可以自定义的,具体内容查看操作章节。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 操作 - Action
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					操作是封装的一段指令,一般需要用户参与。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					例如:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 删除数据,需要用户选中待删除数据,再触发删除指令
 | 
				
			||||||
 | 
					- 筛选数据,需要用户填写筛选项,再触发筛选指令
 | 
				
			||||||
 | 
					- 新增数据,需要用户填写数据之后提交,触发新增操作指令
 | 
				
			||||||
 | 
					- 查看详情,用户点击操作按钮,弹窗查看详情或当前窗口打开详情页查看
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					最简单的操作,只需要绑定一段指令即可,简单来说就是指定一段函数,无需传参。组件结构如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					<Action useAction={useAction} />
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					大部分的操作指令需要用户提供参数,如新增数据操作,需要用户填写数据,填写数据一般需要弹出表单,用户填写完数据,点击提交,才触发操作指令。组件结构如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					<Action useAction={useAction}>
 | 
				
			||||||
 | 
					  {/* 这是个弹窗表单,内置提交按钮,点击提交触发操作指令,具体代码省略 */}
 | 
				
			||||||
 | 
					  <Action.Modal x-decorator={'Form'}></Action.Modal>
 | 
				
			||||||
 | 
					</Action>
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					一个完整的操作大概分为两步:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 为 Action 绑定一段指令
 | 
				
			||||||
 | 
					- 如果指令需要用户提供参数,需要提供交互界面,目前内置的有:
 | 
				
			||||||
 | 
					   - Action.Drawer:抽屉
 | 
				
			||||||
 | 
					   - Action.Modal:对话框
 | 
				
			||||||
 | 
					   - Action.Popover:气泡
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					操作是 NocoBase 里非常重要的一个概念,更多详情点此查看
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 配置工具栏 - DesignableBar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					所有的 Schema Component 都可以绑定自己的配置工具栏(DesignableBar),用于修改当前组件的 Schema。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**什么是 Schema Component?**  
 | 
				
			||||||
 | 
					通过 Schema 协议编写的类 JSON Schema 格式的组件,如:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  type: 'void',
 | 
				
			||||||
 | 
					   'x-Component': 'Hello',
 | 
				
			||||||
 | 
					  'x-designable-bar': 'Hello.DesignableBar',
 | 
				
			||||||
 | 
					  'x-dect': 'CardItem',
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					举几个例子,如:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					表单字段的 JSON Schema
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					const schema = {
 | 
				
			||||||
 | 
					  type: 'string',
 | 
				
			||||||
 | 
					  'x-component': 'Input',
 | 
				
			||||||
 | 
					  'x-decorator': 'FormItem',
 | 
				
			||||||
 | 
					  'x-designable-bar': 'Form.Field.DesignableBar',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					表单项的配置工具栏 `Form.Field.DesignableBar` 的效果
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					表格的 JSON Schema
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					const schema = {
 | 
				
			||||||
 | 
					  type: 'array',
 | 
				
			||||||
 | 
					  'x-component': 'Table',
 | 
				
			||||||
 | 
					  'x-decorator': 'CardItem',
 | 
				
			||||||
 | 
					  'x-designable-bar': 'Table.DesignableBar',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					表格配置工具栏 `Table.DesignableBar` 的效果
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					菜单项的 JSON Schema:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					const schema = {
 | 
				
			||||||
 | 
					  type: 'array',
 | 
				
			||||||
 | 
					  'x-component': 'Menu.Item',
 | 
				
			||||||
 | 
					  'x-designable-bar': 'Menu.Item.DesignableBar',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					菜单项配置工具栏 `Menu.Item.DesignableBar` 的效果
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					更多配置工具栏详情点此查看
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 字段组件 - CollectionField
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					字段组件的配置参数可能非常多,在不同数据区块里也可能用到同一个字段组件,为了减少代码重复,NocoBase 里,将字段组件的配置交由数据表统一管理。一处配置,多处使用。数据区块里直接引用字段组件,如果有其他不同参数再另行扩展。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					<Table>
 | 
				
			||||||
 | 
					  // 原生态的写法
 | 
				
			||||||
 | 
					  <Table.Column title={'姓名'}>
 | 
				
			||||||
 | 
					    <Input {...others} name="name" readPretty={true}/>
 | 
				
			||||||
 | 
					  </Table.Column>
 | 
				
			||||||
 | 
					  // 简化之后的字段引用
 | 
				
			||||||
 | 
					  <Table.Column>
 | 
				
			||||||
 | 
					    <CollectionField name="name"/>
 | 
				
			||||||
 | 
					  </Table.Column>
 | 
				
			||||||
 | 
					</Table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<Form>
 | 
				
			||||||
 | 
					  // 如果在表格里也用到,再写一遍
 | 
				
			||||||
 | 
					  <FormItem title={'姓名'}>
 | 
				
			||||||
 | 
					    <Input {...others} name="name"/>
 | 
				
			||||||
 | 
					  </FormItem>
 | 
				
			||||||
 | 
					  // 字段引用,只需要提供 name 即可 
 | 
				
			||||||
 | 
					  <FormItem>
 | 
				
			||||||
 | 
					    <CollectionField name="name"/>
 | 
				
			||||||
 | 
					  </FormItem>
 | 
				
			||||||
 | 
					</Form>
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					字段组件有三种显示状态:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 可填写 - editable
 | 
				
			||||||
 | 
					- 不可填写 - disabled
 | 
				
			||||||
 | 
					- 阅读模式 - read-pretty
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					以单行文本(Input)为例:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					// 示例(Input 的三种显示状态)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 示例待补充
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**为什么字段有多种显示状态?**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 在表单中,一般情况字段为可填写状态(editable),但如果只供查看,这时候就会把字段设置为 disabled 或 read-pretty。
 | 
				
			||||||
 | 
					- 在表格中,一般情况字段为阅读模式(read-pretty),但如果需要在表格内快捷编辑,又可以动态的将某个字段激活为 editable。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					字段组件可以任意扩展,如何扩展查看 createCollectionField 章节。
 | 
				
			||||||
							
								
								
									
										82
									
								
								docs/guide/basic/collections.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								docs/guide/basic/collections.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,82 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					order: 1
 | 
				
			||||||
 | 
					group:
 | 
				
			||||||
 | 
					  title: Basic Concepts
 | 
				
			||||||
 | 
					  path: /guide/basic
 | 
				
			||||||
 | 
					  order: 4
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Collections & Fields
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NocoBase 的数据表由字段(列)和记录(行)组成。数据表的概念与关系型数据库的数据表概念相近,但是字段的概念并不相同。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 字段
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NocoBase 里,最常见的字段具有组件形态,如:单行文本、多行文本、单选框。这些组件都有数值(value),可交由用户填写,称为有值组件。结构如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  interface: 'textarea',
 | 
				
			||||||
 | 
					  type: 'text',
 | 
				
			||||||
 | 
					  name: 'description',
 | 
				
			||||||
 | 
					  uiSchema: {
 | 
				
			||||||
 | 
					    type: 'string',
 | 
				
			||||||
 | 
					    title: '描述',
 | 
				
			||||||
 | 
					    'x-component': 'Input.TextArea',
 | 
				
			||||||
 | 
					    'x-decorator': 'FormItem',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					上述是一个描述字段的配置:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- type 表示字段的存储类型,为 text 长文本类型
 | 
				
			||||||
 | 
					- uiSchema 为字段的组件参数
 | 
				
			||||||
 | 
					- uiSchema.type 为字段组件的数值类型
 | 
				
			||||||
 | 
					- uiSchema.x-component 表示组件类型,为多行输入框
 | 
				
			||||||
 | 
					- 绑定了组件的字段,都要设置一个 interface,表示当前字段的类型,例子描述字段为多行文本类型
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					除了常见的绑定了组件的字段以外,还有一些无需绑定组件的字段,如 token 字段,这类组件并不会显示在界面上。无组件字段的结构如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  type: 'string',
 | 
				
			||||||
 | 
					  name: 'token',
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**为什么字段要区分存储类型和组件类型?**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					其一:存储类型和组件类型是多对多关系,并不适合合并处理。
 | 
				
			||||||
 | 
					同一组件的 value 的类型(存储类型)可能并不相同,比如 select 的 value 可能是 string 或者 integer。同一存储类型也可能以不同的组件呈现,如 string 绑定的组件可能是 Input,也可能是 Select。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					其二:有限的存储类型和组件类型可以组合出无数种字段类型。
 | 
				
			||||||
 | 
					单行文本、电子邮件、网址、手机号这些字段的存储类型和组件类型虽然都相同,但是校验参数并不相同,只需要调整 validate 参数即可创建出无数种字段。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 字段的类型
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					| 名称     | Interface | Type   | Component      | 备注              |
 | 
				
			||||||
 | 
					| :------- | :-------- | :----- | :------------- | :---------------- |
 | 
				
			||||||
 | 
					| 单行文本 | string    | string | Input          |                   |
 | 
				
			||||||
 | 
					| 多行文本 | textarea  | text   | Input.TextArea |                   |
 | 
				
			||||||
 | 
					| 邮箱     | email     | string | Input          | validate: 'email' |
 | 
				
			||||||
 | 
					| 手机号   | phone     | string | Input          | validate: 'phone' |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 可以做什么?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 快速建模
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					与专业的建模工具不同,NocoBase 提供了一种更利于普通用户理解的数据表配置方法。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 可以直接通过 app.collection() 直接写代码里,多用于配置底层系统表。
 | 
				
			||||||
 | 
					- 也可以通过无代码平台的数据表配置入口配置数据表,多用于配置业务表。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 创建数据区块
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					配置好的数据表可用于创建对应的数据区块,如以表格的形式展示某个数据表的内容。表格里可以选择哪些字段作为表格列显示出来。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					更多关于区块的内容可以查看客户端组件章节。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### HTTP API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					跨平台也可以通过 HTTP API 的方式操作数据表(增删改查配置等),更多内容查看 SDK 章节。
 | 
				
			||||||
							
								
								
									
										82
									
								
								docs/guide/basic/collections.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								docs/guide/basic/collections.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,82 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					order: 1
 | 
				
			||||||
 | 
					group:
 | 
				
			||||||
 | 
					  title: 基础概念
 | 
				
			||||||
 | 
					  path: /zh-CN/guide/basic
 | 
				
			||||||
 | 
					  order: 4
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 数据表和字段
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NocoBase 的数据表由字段(列)和记录(行)组成。数据表的概念与关系型数据库的数据表概念相近,但是字段的概念并不相同。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 字段
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NocoBase 里,最常见的字段具有组件形态,如:单行文本、多行文本、单选框。这些组件都有数值(value),可交由用户填写,称为有值组件。结构如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  interface: 'textarea',
 | 
				
			||||||
 | 
					  type: 'text',
 | 
				
			||||||
 | 
					  name: 'description',
 | 
				
			||||||
 | 
					  uiSchema: {
 | 
				
			||||||
 | 
					    type: 'string',
 | 
				
			||||||
 | 
					    title: '描述',
 | 
				
			||||||
 | 
					    'x-component': 'Input.TextArea',
 | 
				
			||||||
 | 
					    'x-decorator': 'FormItem',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					上述是一个描述字段的配置:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- type 表示字段的存储类型,为 text 长文本类型
 | 
				
			||||||
 | 
					- uiSchema 为字段的组件参数
 | 
				
			||||||
 | 
					- uiSchema.type 为字段组件的数值类型
 | 
				
			||||||
 | 
					- uiSchema.x-component 表示组件类型,为多行输入框
 | 
				
			||||||
 | 
					- 绑定了组件的字段,都要设置一个 interface,表示当前字段的类型,例子描述字段为多行文本类型
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					除了常见的绑定了组件的字段以外,还有一些无需绑定组件的字段,如 token 字段,这类组件并不会显示在界面上。无组件字段的结构如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  type: 'string',
 | 
				
			||||||
 | 
					  name: 'token',
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**为什么字段要区分存储类型和组件类型?**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					其一:存储类型和组件类型是多对多关系,并不适合合并处理。
 | 
				
			||||||
 | 
					同一组件的 value 的类型(存储类型)可能并不相同,比如 select 的 value 可能是 string 或者 integer。同一存储类型也可能以不同的组件呈现,如 string 绑定的组件可能是 Input,也可能是 Select。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					其二:有限的存储类型和组件类型可以组合出无数种字段类型。
 | 
				
			||||||
 | 
					单行文本、电子邮件、网址、手机号这些字段的存储类型和组件类型虽然都相同,但是校验参数并不相同,只需要调整 validate 参数即可创建出无数种字段。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 字段的类型
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					| 名称     | Interface | Type   | Component      | 备注              |
 | 
				
			||||||
 | 
					| :------- | :-------- | :----- | :------------- | :---------------- |
 | 
				
			||||||
 | 
					| 单行文本 | string    | string | Input          |                   |
 | 
				
			||||||
 | 
					| 多行文本 | textarea  | text   | Input.TextArea |                   |
 | 
				
			||||||
 | 
					| 邮箱     | email     | string | Input          | validate: 'email' |
 | 
				
			||||||
 | 
					| 手机号   | phone     | string | Input          | validate: 'phone' |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 可以做什么?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 快速建模
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					与专业的建模工具不同,NocoBase 提供了一种更利于普通用户理解的数据表配置方法。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 可以直接通过 app.collection() 直接写代码里,多用于配置底层系统表。
 | 
				
			||||||
 | 
					- 也可以通过无代码平台的数据表配置入口配置数据表,多用于配置业务表。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 创建数据区块
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					配置好的数据表可用于创建对应的数据区块,如以表格的形式展示某个数据表的内容。表格里可以选择哪些字段作为表格列显示出来。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					更多关于区块的内容可以查看客户端组件章节。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### HTTP API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					跨平台也可以通过 HTTP API 的方式操作数据表(增删改查配置等),更多内容查看 SDK 章节。
 | 
				
			||||||
							
								
								
									
										6
									
								
								docs/guide/deployment.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								docs/guide/deployment.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					order: 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Deployment
 | 
				
			||||||
							
								
								
									
										5
									
								
								docs/guide/deployment.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								docs/guide/deployment.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					order: 3
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 部署
 | 
				
			||||||
							
								
								
									
										42
									
								
								docs/guide/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								docs/guide/index.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					nav:
 | 
				
			||||||
 | 
					  title: Guide
 | 
				
			||||||
 | 
					  order: 1
 | 
				
			||||||
 | 
					order: 1
 | 
				
			||||||
 | 
					title: Introducation
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## What is NocoBase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NocoBase is a scalability-first, open-source no-code development platform. No programming required, build your own collaboration platform, management system with NocoBase in minutes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## When to use NocoBase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- **SMEs and organizations build business platforms and management systems for themselves or for their industry**
 | 
				
			||||||
 | 
					  - Want the price to be low enough or even free
 | 
				
			||||||
 | 
					  - Can be flexibly customized without programming knowledge
 | 
				
			||||||
 | 
					  - Need full control of source code and data
 | 
				
			||||||
 | 
					  - Can freely distribute and sell as their own products
 | 
				
			||||||
 | 
					- **Service providers and outsourcing teams develop collaboration platforms and management systems for their clients**
 | 
				
			||||||
 | 
					  - Want to keep development costs as low as possible
 | 
				
			||||||
 | 
					  - Need the most user-friendly secondary development experience
 | 
				
			||||||
 | 
					  - Must be deployed privately as a standalone product for the client
 | 
				
			||||||
 | 
					  - Can be freely distributed and sold by the client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Why choose NocoBase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- **Open source and free**
 | 
				
			||||||
 | 
					  - Unrestricted commercial use under the MIT license
 | 
				
			||||||
 | 
					  - Full code ownership, private deployment, private and secure data
 | 
				
			||||||
 | 
					  - Free to expand and develop for actual needs
 | 
				
			||||||
 | 
					  - Good ecological support
 | 
				
			||||||
 | 
					- **Strong no-code capability**
 | 
				
			||||||
 | 
					  - WYSIWYG visual configuration
 | 
				
			||||||
 | 
					  - Separation of data structure configuration from interface configuration
 | 
				
			||||||
 | 
					  - Rich combination of blocks and operations
 | 
				
			||||||
 | 
					  - Role-based access control
 | 
				
			||||||
 | 
					- **Developer-friendly**
 | 
				
			||||||
 | 
					  - Microkernel architecture, flexible and easy to extend, with a robust plug-in system
 | 
				
			||||||
 | 
					  - Node.js-based, with popular frameworks and technologies, including Koa, Sequelize, React, Formily, Ant Design, etc.
 | 
				
			||||||
 | 
					  - Progressive development, easy for getting-started, friendly to newcomers
 | 
				
			||||||
 | 
					  - No binding, no strong dependencies, can be used in any combination or extensions, can be used in existing projects
 | 
				
			||||||
							
								
								
									
										42
									
								
								docs/guide/index.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								docs/guide/index.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					nav:
 | 
				
			||||||
 | 
					  title: 指南
 | 
				
			||||||
 | 
					  order: 1
 | 
				
			||||||
 | 
					order: 1
 | 
				
			||||||
 | 
					title: 介绍
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## NocoBase 是什么
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NocoBase 是一个极易扩展的开源无代码开发平台。无需编程,使用 NocoBase 搭建自己的协作平台、管理系统,只需要几分钟时间。 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 哪些场景适合使用 NocoBase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 中小企业和组织为自己或者为所在行业搭建业务平台和管理系统
 | 
				
			||||||
 | 
					   - 希望价格足够低,甚至免费
 | 
				
			||||||
 | 
					   - 不懂编程也可以灵活定制
 | 
				
			||||||
 | 
					   - 需要完全掌控源代码和数据
 | 
				
			||||||
 | 
					   - 可以以自有产品的形态自由分发和销售
 | 
				
			||||||
 | 
					- 服务商和外包团队为客户开发协作平台和管理系统
 | 
				
			||||||
 | 
					   - 希望尽可能降低开发成本
 | 
				
			||||||
 | 
					   - 需要极致友好的二次开发体验
 | 
				
			||||||
 | 
					   - 必须以独立产品的形态为客户私有部署
 | 
				
			||||||
 | 
					   - 客户可以自由分发和销售
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 为什么选择 NocoBase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 开源免费
 | 
				
			||||||
 | 
					   - 采用 MIT 许可协议,不限制商业使用
 | 
				
			||||||
 | 
					   - 拥有全部代码,私有化部署,保障数据私有和安全
 | 
				
			||||||
 | 
					   - 针对实际需求自由扩展开发
 | 
				
			||||||
 | 
					   - 具备良好的生态支持
 | 
				
			||||||
 | 
					- 无代码能力强
 | 
				
			||||||
 | 
					   - 所见即所得的可视化配置
 | 
				
			||||||
 | 
					   - 数据结构配置与界面配置分离
 | 
				
			||||||
 | 
					   - 丰富的区块和操作任意组合
 | 
				
			||||||
 | 
					   - 基于角色的访问权限
 | 
				
			||||||
 | 
					- 对开发者友好
 | 
				
			||||||
 | 
					   - 微内核,灵活易扩展,具备健全的插件体系
 | 
				
			||||||
 | 
					   - 基于 Node.js,使用主流框架和技术,包括 Koa、Sequelize、React、Formily、Ant Design 等
 | 
				
			||||||
 | 
					   - 渐进式开发,上手难度低,对新人友好
 | 
				
			||||||
 | 
					   - 不绑架、不强依赖,可任意组合使用或扩展,可用于现有项目中
 | 
				
			||||||
							
								
								
									
										1268
									
								
								docs/guide/kernel-principle/choose-an-orm.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1268
									
								
								docs/guide/kernel-principle/choose-an-orm.md
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1268
									
								
								docs/guide/kernel-principle/choose-an-orm.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1268
									
								
								docs/guide/kernel-principle/choose-an-orm.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										158
									
								
								docs/guide/kernel-principle/client-side-kernel.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								docs/guide/kernel-principle/client-side-kernel.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,158 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					order: 2
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Client-side Kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					为了让更多非开发人员也能参与进来,NocoBase 提供了配套的客户端插件 —— 无代码的可视化配置界面。这部分的核心就是 @nocobase/client,理想状态可以用在任意前端构建工具或框架内,如:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- umijs
 | 
				
			||||||
 | 
					- create-react-app
 | 
				
			||||||
 | 
					- icejs
 | 
				
			||||||
 | 
					- vite
 | 
				
			||||||
 | 
					- snowpack
 | 
				
			||||||
 | 
					- nextjs
 | 
				
			||||||
 | 
					- 其他
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					暂时只支持 umijs(打包编译还有些问题),未来会逐步支持以上罗列的各个框架。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					客户端主要的组成部分包括:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 请求
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- API Client
 | 
				
			||||||
 | 
					- Request Hook
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					const api = new APIClient({
 | 
				
			||||||
 | 
						request,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					api.auth();
 | 
				
			||||||
 | 
					api.get();
 | 
				
			||||||
 | 
					api.post();
 | 
				
			||||||
 | 
					api.resource('collections').create();
 | 
				
			||||||
 | 
					api.resource('collections').findOne({});
 | 
				
			||||||
 | 
					api.resource('collections').findMany({});
 | 
				
			||||||
 | 
					api.resource('collections').relation('fields').of(1).create();
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					以下细节待定,特殊的资源
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					api.collections.create();
 | 
				
			||||||
 | 
					api.uiSchemas.create();
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Request Hook
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[https://www.npmjs.com/package/@ahooksjs/use-request](https://www.npmjs.com/package/@ahooksjs/use-request)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					const { data } = useRequest(() => api.resource('users').findMany());
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 路由
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- createRouteSwitch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					const RouteSwitch = createRouteSwitch({
 | 
				
			||||||
 | 
						components: {},
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<RouteSwitch routes={[]} />
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Schema 组件
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- createSchemaComponent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					function Hello() {
 | 
				
			||||||
 | 
						return <div>Hello Word</div>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const SchemaComponent = createSchemaComponent({
 | 
				
			||||||
 | 
					  scope,
 | 
				
			||||||
 | 
					  components: {
 | 
				
			||||||
 | 
					  	Hello
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const schema = {
 | 
				
			||||||
 | 
					  type: 'void',
 | 
				
			||||||
 | 
						'x-component': 'Hello',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<SchemaComponent schema={schema} />
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 怎么组装起来?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					import { I18nextProvider } from 'react-i18next';
 | 
				
			||||||
 | 
					import { createRouteSwitch, APIClient } from '@nocobase/client';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const apiClient = new APIClient();
 | 
				
			||||||
 | 
					const i18n = i18next.createInstance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Hello = () => {
 | 
				
			||||||
 | 
						return <div>Hello</div>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const SchemaComponent = createSchemaComponent({
 | 
				
			||||||
 | 
						components: {
 | 
				
			||||||
 | 
					    Hello,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const PageTemplate = () => {
 | 
				
			||||||
 | 
					  const schema = {
 | 
				
			||||||
 | 
					  	type: 'void',
 | 
				
			||||||
 | 
					    'x-component': 'Hello',
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
						return (
 | 
				
			||||||
 | 
					  	<SchemaComponent schema={schema}/>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const RouteSwitch = createRouteSwitch({
 | 
				
			||||||
 | 
						components: {
 | 
				
			||||||
 | 
					    PageTemplate,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const routes = [
 | 
				
			||||||
 | 
					  { path: '/hello', component: 'Hello' },
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function AntdProvider(props) {
 | 
				
			||||||
 | 
					  // 可以根据 i18next 的情况动态处理这里的 locale
 | 
				
			||||||
 | 
						return (
 | 
				
			||||||
 | 
					  	<ConfigProvider locale={locale}>{props.children}</ConfigProvider>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const App = () => {
 | 
				
			||||||
 | 
						return (
 | 
				
			||||||
 | 
					    <APIClientProvider client={apiClient}>
 | 
				
			||||||
 | 
					      <I18nextProvider i18n={i18n}>
 | 
				
			||||||
 | 
					        <AntdProvider>
 | 
				
			||||||
 | 
					          <Router>
 | 
				
			||||||
 | 
					            <RouteSwitch routes=[routes]/>
 | 
				
			||||||
 | 
					          </Router>
 | 
				
			||||||
 | 
					        </AntdProvider>
 | 
				
			||||||
 | 
					      </I18nextProvider>
 | 
				
			||||||
 | 
					    </APIClientProvider>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- APIClientProvider:提供 APIClient
 | 
				
			||||||
 | 
					- I18nextProvider:国际化
 | 
				
			||||||
 | 
					- AntdProvider:处理 antd 组件的国际化,需要放在 I18nextProvider 里
 | 
				
			||||||
 | 
					- Router:路由驱动
 | 
				
			||||||
 | 
					- RouteSwitch:路由分发
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					上面代码看似有些啰嗦,实际各部分的功能和作用并不一样,不适合过度封装。如果需要可以根据实际情况,再进一步封装。
 | 
				
			||||||
							
								
								
									
										158
									
								
								docs/guide/kernel-principle/client-side-kernel.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								docs/guide/kernel-principle/client-side-kernel.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,158 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					order: 2
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 客户端内核
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					为了让更多非开发人员也能参与进来,NocoBase 提供了配套的客户端插件 —— 无代码的可视化配置界面。这部分的核心就是 @nocobase/client,理想状态可以用在任意前端构建工具或框架内,如:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- umijs
 | 
				
			||||||
 | 
					- create-react-app
 | 
				
			||||||
 | 
					- icejs
 | 
				
			||||||
 | 
					- vite
 | 
				
			||||||
 | 
					- snowpack
 | 
				
			||||||
 | 
					- nextjs
 | 
				
			||||||
 | 
					- 其他
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					暂时只支持 umijs(打包编译还有些问题),未来会逐步支持以上罗列的各个框架。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					客户端主要的组成部分包括:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 请求
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- API Client
 | 
				
			||||||
 | 
					- Request Hook
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					const api = new APIClient({
 | 
				
			||||||
 | 
						request,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					api.auth();
 | 
				
			||||||
 | 
					api.get();
 | 
				
			||||||
 | 
					api.post();
 | 
				
			||||||
 | 
					api.resource('collections').create();
 | 
				
			||||||
 | 
					api.resource('collections').findOne({});
 | 
				
			||||||
 | 
					api.resource('collections').findMany({});
 | 
				
			||||||
 | 
					api.resource('collections').relation('fields').of(1).create();
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					以下细节待定,特殊的资源
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					api.collections.create();
 | 
				
			||||||
 | 
					api.uiSchemas.create();
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Request Hook
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[https://www.npmjs.com/package/@ahooksjs/use-request](https://www.npmjs.com/package/@ahooksjs/use-request)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					const { data } = useRequest(() => api.resource('users').findMany());
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 路由
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- createRouteSwitch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					const RouteSwitch = createRouteSwitch({
 | 
				
			||||||
 | 
						components: {},
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<RouteSwitch routes={[]} />
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Schema 组件
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- createSchemaComponent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					function Hello() {
 | 
				
			||||||
 | 
						return <div>Hello Word</div>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const SchemaComponent = createSchemaComponent({
 | 
				
			||||||
 | 
					  scope,
 | 
				
			||||||
 | 
					  components: {
 | 
				
			||||||
 | 
					  	Hello
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const schema = {
 | 
				
			||||||
 | 
					  type: 'void',
 | 
				
			||||||
 | 
						'x-component': 'Hello',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<SchemaComponent schema={schema} />
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 怎么组装起来?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					import { I18nextProvider } from 'react-i18next';
 | 
				
			||||||
 | 
					import { createRouteSwitch, APIClient } from '@nocobase/client';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const apiClient = new APIClient();
 | 
				
			||||||
 | 
					const i18n = i18next.createInstance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Hello = () => {
 | 
				
			||||||
 | 
						return <div>Hello</div>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const SchemaComponent = createSchemaComponent({
 | 
				
			||||||
 | 
						components: {
 | 
				
			||||||
 | 
					    Hello,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const PageTemplate = () => {
 | 
				
			||||||
 | 
					  const schema = {
 | 
				
			||||||
 | 
					  	type: 'void',
 | 
				
			||||||
 | 
					    'x-component': 'Hello',
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
						return (
 | 
				
			||||||
 | 
					  	<SchemaComponent schema={schema}/>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const RouteSwitch = createRouteSwitch({
 | 
				
			||||||
 | 
						components: {
 | 
				
			||||||
 | 
					    PageTemplate,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const routes = [
 | 
				
			||||||
 | 
					  { path: '/hello', component: 'Hello' },
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function AntdProvider(props) {
 | 
				
			||||||
 | 
					  // 可以根据 i18next 的情况动态处理这里的 locale
 | 
				
			||||||
 | 
						return (
 | 
				
			||||||
 | 
					  	<ConfigProvider locale={locale}>{props.children}</ConfigProvider>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const App = () => {
 | 
				
			||||||
 | 
						return (
 | 
				
			||||||
 | 
					    <APIClientProvider client={apiClient}>
 | 
				
			||||||
 | 
					      <I18nextProvider i18n={i18n}>
 | 
				
			||||||
 | 
					        <AntdProvider>
 | 
				
			||||||
 | 
					          <Router>
 | 
				
			||||||
 | 
					            <RouteSwitch routes=[routes]/>
 | 
				
			||||||
 | 
					          </Router>
 | 
				
			||||||
 | 
					        </AntdProvider>
 | 
				
			||||||
 | 
					      </I18nextProvider>
 | 
				
			||||||
 | 
					    </APIClientProvider>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- APIClientProvider:提供 APIClient
 | 
				
			||||||
 | 
					- I18nextProvider:国际化
 | 
				
			||||||
 | 
					- AntdProvider:处理 antd 组件的国际化,需要放在 I18nextProvider 里
 | 
				
			||||||
 | 
					- Router:路由驱动
 | 
				
			||||||
 | 
					- RouteSwitch:路由分发
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					上面代码看似有些啰嗦,实际各部分的功能和作用并不一样,不适合过度封装。如果需要可以根据实际情况,再进一步封装。
 | 
				
			||||||
							
								
								
									
										73
									
								
								docs/guide/kernel-principle/installation-startup.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								docs/guide/kernel-principle/installation-startup.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,73 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					order: 3
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Installation and Startup Process
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 项目安装
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					yarn nocobase init
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- app.constructor()
 | 
				
			||||||
 | 
					- app.parse()
 | 
				
			||||||
 | 
					  - yarn nocobase init  
 | 
				
			||||||
 | 
					    初始化安装
 | 
				
			||||||
 | 
					    - app.load()  
 | 
				
			||||||
 | 
					      加载配置
 | 
				
			||||||
 | 
					      - app.emitAsync('beforeLoad')  
 | 
				
			||||||
 | 
					        所有配置加载之前的钩子
 | 
				
			||||||
 | 
					      - app.pluginManager.load()  
 | 
				
			||||||
 | 
					        按顺序载入所有激活的插件的配置
 | 
				
			||||||
 | 
					        - 加载 plugin-collections 的配置
 | 
				
			||||||
 | 
					        - 添加 app.on('init') 监听
 | 
				
			||||||
 | 
					          - db.getModel('collections').load()  
 | 
				
			||||||
 | 
					            把 collections 表的配置都导入 db.table()
 | 
				
			||||||
 | 
					          - app.db.sync({force: false})  
 | 
				
			||||||
 | 
					            再执行 sync,创建 collections 表里配置的数据表
 | 
				
			||||||
 | 
					      - app.emitAsync('afterLoad')  
 | 
				
			||||||
 | 
					        所有配置加载之后的钩子
 | 
				
			||||||
 | 
					      - app.db.sync({force: true})  
 | 
				
			||||||
 | 
					        根据配置生成数据表、字段、索引等
 | 
				
			||||||
 | 
					      - app.emitAsync('init')  
 | 
				
			||||||
 | 
					        执行所有 init listeners,一般是初始化的数据操作
 | 
				
			||||||
 | 
					        - 触发 plugin-collections 的 init 事件,数据表就创建好了
 | 
				
			||||||
 | 
					      - app.stop()  
 | 
				
			||||||
 | 
					        结束
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 项目启动
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					yarn nocobase start --init --sync
 | 
				
			||||||
 | 
					# --init 用于启动时快捷安装
 | 
				
			||||||
 | 
					# --sync 开发环境时,当 app.collection() 有更新时快速建表或更新表
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- app.constructor()
 | 
				
			||||||
 | 
					- app.parse()
 | 
				
			||||||
 | 
					  - yarn nocobase start  
 | 
				
			||||||
 | 
					    初始化安装
 | 
				
			||||||
 | 
					    - app.load()  
 | 
				
			||||||
 | 
					      加载配置
 | 
				
			||||||
 | 
					      - app.emitAsync('beforeLoad')  
 | 
				
			||||||
 | 
					        所有配置加载之前的钩子
 | 
				
			||||||
 | 
					      - app.pluginManager.load()
 | 
				
			||||||
 | 
					        按顺序载入所有激活的插件的配置
 | 
				
			||||||
 | 
					        - 加载 plugin-collections 的配置
 | 
				
			||||||
 | 
					          - 添加 app.on('start') 监听
 | 
				
			||||||
 | 
					          - db.getModel('collections').load()  
 | 
				
			||||||
 | 
					            把 collections 表的配置都导入 db.table(),在 start 流程里不需要再 db.sync
 | 
				
			||||||
 | 
					      - app.emitAsync('afterLoad')  
 | 
				
			||||||
 | 
					        所有配置加载之后的钩子
 | 
				
			||||||
 | 
					      - app.db.sync({force: false})  
 | 
				
			||||||
 | 
					        yarn nocobase start --sync 有更新时快速建表或更新表  
 | 
				
			||||||
 | 
					        yarn nocobase start --init 快捷 init
 | 
				
			||||||
 | 
					      - app.emitAsync('init')  
 | 
				
			||||||
 | 
					        yarn nocobase start --init 快捷 init
 | 
				
			||||||
 | 
					      - app.emitAsync('start')  
 | 
				
			||||||
 | 
					        执行所有 start listeners,一般是从数据表里读取一些必要的数据
 | 
				
			||||||
 | 
					      - app.listen()
 | 
				
			||||||
 | 
					        启动 http server
 | 
				
			||||||
							
								
								
									
										73
									
								
								docs/guide/kernel-principle/installation-startup.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								docs/guide/kernel-principle/installation-startup.zh-CN.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,73 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					order: 3
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 项目安装和启动流程
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 项目安装
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					yarn nocobase init
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- app.constructor()
 | 
				
			||||||
 | 
					- app.parse()
 | 
				
			||||||
 | 
					  - yarn nocobase init  
 | 
				
			||||||
 | 
					    初始化安装
 | 
				
			||||||
 | 
					    - app.load()  
 | 
				
			||||||
 | 
					      加载配置
 | 
				
			||||||
 | 
					      - app.emitAsync('beforeLoad')  
 | 
				
			||||||
 | 
					        所有配置加载之前的钩子
 | 
				
			||||||
 | 
					      - app.pluginManager.load()  
 | 
				
			||||||
 | 
					        按顺序载入所有激活的插件的配置
 | 
				
			||||||
 | 
					        - 加载 plugin-collections 的配置
 | 
				
			||||||
 | 
					        - 添加 app.on('init') 监听
 | 
				
			||||||
 | 
					          - db.getModel('collections').load()  
 | 
				
			||||||
 | 
					            把 collections 表的配置都导入 db.table()
 | 
				
			||||||
 | 
					          - app.db.sync({force: false})  
 | 
				
			||||||
 | 
					            再执行 sync,创建 collections 表里配置的数据表
 | 
				
			||||||
 | 
					      - app.emitAsync('afterLoad')  
 | 
				
			||||||
 | 
					        所有配置加载之后的钩子
 | 
				
			||||||
 | 
					      - app.db.sync({force: true})  
 | 
				
			||||||
 | 
					        根据配置生成数据表、字段、索引等
 | 
				
			||||||
 | 
					      - app.emitAsync('init')  
 | 
				
			||||||
 | 
					        执行所有 init listeners,一般是初始化的数据操作
 | 
				
			||||||
 | 
					        - 触发 plugin-collections 的 init 事件,数据表就创建好了
 | 
				
			||||||
 | 
					      - app.stop()  
 | 
				
			||||||
 | 
					        结束
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 项目启动
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					yarn nocobase start --init --sync
 | 
				
			||||||
 | 
					# --init 用于启动时快捷安装
 | 
				
			||||||
 | 
					# --sync 开发环境时,当 app.collection() 有更新时快速建表或更新表
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- app.constructor()
 | 
				
			||||||
 | 
					- app.parse()
 | 
				
			||||||
 | 
					  - yarn nocobase start  
 | 
				
			||||||
 | 
					    初始化安装
 | 
				
			||||||
 | 
					    - app.load()  
 | 
				
			||||||
 | 
					      加载配置
 | 
				
			||||||
 | 
					      - app.emitAsync('beforeLoad')  
 | 
				
			||||||
 | 
					        所有配置加载之前的钩子
 | 
				
			||||||
 | 
					      - app.pluginManager.load()
 | 
				
			||||||
 | 
					        按顺序载入所有激活的插件的配置
 | 
				
			||||||
 | 
					        - 加载 plugin-collections 的配置
 | 
				
			||||||
 | 
					          - 添加 app.on('start') 监听
 | 
				
			||||||
 | 
					          - db.getModel('collections').load()  
 | 
				
			||||||
 | 
					            把 collections 表的配置都导入 db.table(),在 start 流程里不需要再 db.sync
 | 
				
			||||||
 | 
					      - app.emitAsync('afterLoad')  
 | 
				
			||||||
 | 
					        所有配置加载之后的钩子
 | 
				
			||||||
 | 
					      - app.db.sync({force: false})  
 | 
				
			||||||
 | 
					        yarn nocobase start --sync 有更新时快速建表或更新表  
 | 
				
			||||||
 | 
					        yarn nocobase start --init 快捷 init
 | 
				
			||||||
 | 
					      - app.emitAsync('init')  
 | 
				
			||||||
 | 
					        yarn nocobase start --init 快捷 init
 | 
				
			||||||
 | 
					      - app.emitAsync('start')  
 | 
				
			||||||
 | 
					        执行所有 start listeners,一般是从数据表里读取一些必要的数据
 | 
				
			||||||
 | 
					      - app.listen()
 | 
				
			||||||
 | 
					        启动 http server
 | 
				
			||||||
							
								
								
									
										13
									
								
								docs/guide/kernel-principle/microkernel-architecture.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								docs/guide/kernel-principle/microkernel-architecture.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					order: 0
 | 
				
			||||||
 | 
					group:
 | 
				
			||||||
 | 
					  title: Kernel Principle
 | 
				
			||||||
 | 
					  path: /guide/kernel-principle
 | 
				
			||||||
 | 
					  order:  6
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Microkernel Architecture
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<img src="../../images/NocoBase.png" style="max-width: 800px; width: 100%;">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NocoBase 采用微内核架构,各类功能以插件形式扩展,所以微内核架构也叫插件化架构,由内核和插件两部分组成。内核提供了最小功能的 WEB 服务器,还提供了各种插件化接口;插件是按功能划分的各种独立模块,通过接口适配,具有可插拔的特点。插件化的设计降低了模块之间的耦合度,提高了复用率。随着插件库的不断扩充,常见的场景只需要组合插件即可完成基础搭建,这种设计理念非常适合无代码平台。
 | 
				
			||||||
@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					order: 0
 | 
				
			||||||
 | 
					group:
 | 
				
			||||||
 | 
					  title: 内核原理
 | 
				
			||||||
 | 
					  path: /zh-CN/guide/kernel-principle
 | 
				
			||||||
 | 
					  order:  6
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 微内核架构
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<img src="../../images/NocoBase.png" style="max-width: 800px; width: 100%;">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NocoBase 采用微内核架构,各类功能以插件形式扩展,所以微内核架构也叫插件化架构,由内核和插件两部分组成。内核提供了最小功能的 WEB 服务器,还提供了各种插件化接口;插件是按功能划分的各种独立模块,通过接口适配,具有可插拔的特点。插件化的设计降低了模块之间的耦合度,提高了复用率。随着插件库的不断扩充,常见的场景只需要组合插件即可完成基础搭建,这种设计理念非常适合无代码平台。
 | 
				
			||||||
							
								
								
									
										903
									
								
								docs/guide/kernel-principle/server-side-kernel.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										903
									
								
								docs/guide/kernel-principle/server-side-kernel.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,903 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					order: 1
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Server-side Kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 微服务 - Microservices
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					为了更快的理解 NocoBase,我们先创建一个应用,新建一个 app.js 文件,代码如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					const { Application } = require('@nocobase/server');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const app = new Application({
 | 
				
			||||||
 | 
					  // 省略配置信息
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 配置一张 users 表
 | 
				
			||||||
 | 
					app.collection({
 | 
				
			||||||
 | 
					  name: 'users',
 | 
				
			||||||
 | 
					  fields: [
 | 
				
			||||||
 | 
					    { type: 'string', name: 'username' },
 | 
				
			||||||
 | 
					    { type: 'password', name: 'password' }
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 解析 argv 参数,终端通过命令行进行不同操作
 | 
				
			||||||
 | 
					app.parse(process.argv);
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					终端运行
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					# 根据配置生成数据库表结构
 | 
				
			||||||
 | 
					node app.js db:sync
 | 
				
			||||||
 | 
					# 启动应用
 | 
				
			||||||
 | 
					node app.js start --port=3000
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					相关 users 表的 REST API 就生成了
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					GET     http://localhost:3000/api/users
 | 
				
			||||||
 | 
					POST    http://localhost:3000/api/users
 | 
				
			||||||
 | 
					GET     http://localhost:3000/api/users/1
 | 
				
			||||||
 | 
					PUT     http://localhost:3000/api/users/1
 | 
				
			||||||
 | 
					DELETE  http://localhost:3000/api/users/1
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					以上示例,只用了 10 行左右的代码就创建了真实可用的 REST API 服务。除了内置的 REST API 以外,还可以通过 `app.actions()` 自定义其他操作,如登录、注册、注销等。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					app.actions({
 | 
				
			||||||
 | 
					  async login(ctx, next) {},
 | 
				
			||||||
 | 
					  async register(ctx, next) {},
 | 
				
			||||||
 | 
					  async logout(ctx, next) {},
 | 
				
			||||||
 | 
					}, {
 | 
				
			||||||
 | 
					  resourceName: 'users', // 属于 users 资源
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					以上自定义操作的 HTTP API 为:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					POST    http://localhost:3000/api/users:login
 | 
				
			||||||
 | 
					POST    http://localhost:3000/api/users:register
 | 
				
			||||||
 | 
					POST    http://localhost:3000/api/users:logout
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					自定义的 HTTP API 依旧保持 REST API 的风格,以 `<resourceName>:<actionName>` 格式表示。实际上 REST API 也可以显式指定 `actionName`,当指定了 `actionName`,无所谓使用什么请求方法,如:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					# 更新操作
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NocoBase 的路由(Resourcer)基于资源(Resource)和操作(Action)设计,将 REST 和 RPC 结合起来,提供更为灵活且统一的 Resource Action API。结合客户端 SDK 是这样的:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					const { ClientSDK } = require('@nocobase/sdk');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const api = new ClientSDK({
 | 
				
			||||||
 | 
					  // 可以适配不同 request
 | 
				
			||||||
 | 
					  request(params) => Promise.resolve({}),
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					await api.resource('users').list();
 | 
				
			||||||
 | 
					await api.resource('users').create();
 | 
				
			||||||
 | 
					await api.resource('users').get();
 | 
				
			||||||
 | 
					await api.resource('users').update();
 | 
				
			||||||
 | 
					await api.resource('users').destroy();
 | 
				
			||||||
 | 
					await api.resource('users').login();
 | 
				
			||||||
 | 
					await api.resource('users').register();
 | 
				
			||||||
 | 
					await api.resource('users').logout();
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 应用 - Application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NocoBase 的 Application 继承了 Koa,集成了 DB 和 CLI,添加了一些必要的 API,这里列一些重点:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `app.db`:数据库实例,每个 app 都有自己的 db。
 | 
				
			||||||
 | 
					    - `db.getCollection()` 数据表/数据集
 | 
				
			||||||
 | 
					      - `collection.repository` 数据仓库
 | 
				
			||||||
 | 
					      - `collection.model` 数据模型
 | 
				
			||||||
 | 
					  - `db.on()` 添加事件监听,由 EventEmitter 提供
 | 
				
			||||||
 | 
					  - `db.emit()` 触发事件,由 EventEmitter 提供
 | 
				
			||||||
 | 
					  - `db.emitAsync()` 触发异步事件
 | 
				
			||||||
 | 
					- `app.cli`,Commander 实例,提供命令行操作
 | 
				
			||||||
 | 
					- `app.context`,上下文
 | 
				
			||||||
 | 
					  - `ctx.db`
 | 
				
			||||||
 | 
					  - `ctx.action` 当前资源操作实例
 | 
				
			||||||
 | 
					    - `action.params` 操作参数
 | 
				
			||||||
 | 
					    - `action.mergeParams()` 参数合并方法
 | 
				
			||||||
 | 
					- `app.constructor()` 初始化
 | 
				
			||||||
 | 
					- `app.collection()` 定义数据 Schema,等同于 `app.db.collection()`
 | 
				
			||||||
 | 
					- `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()`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 数据集 - Collection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NocoBase 通过 `app.collection()` 方法定义数据的 Schema,Schema 的类型包括:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					属性 Attribute
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Boolean 布尔型
 | 
				
			||||||
 | 
					- String 字符串
 | 
				
			||||||
 | 
					- Text 长文本
 | 
				
			||||||
 | 
					- Integer 整数型
 | 
				
			||||||
 | 
					- Float 浮点型
 | 
				
			||||||
 | 
					- Decimal 货币
 | 
				
			||||||
 | 
					- Json/Jsonb/Array 不同数据库的 JSON 类型不一致,存在兼容性问题
 | 
				
			||||||
 | 
					- Time 时间
 | 
				
			||||||
 | 
					- Date 日期
 | 
				
			||||||
 | 
					- Virtual 虚拟字段
 | 
				
			||||||
 | 
					- Reference 引用
 | 
				
			||||||
 | 
					- Formula 计算公式
 | 
				
			||||||
 | 
					- Context 上下文
 | 
				
			||||||
 | 
					- Password 密码
 | 
				
			||||||
 | 
					- Sort 排序
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					关系 Association/Realtion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- HasOne 一对一
 | 
				
			||||||
 | 
					- HasMany 一对多
 | 
				
			||||||
 | 
					- BelongsTo 多对一
 | 
				
			||||||
 | 
					- BelongsToMany 多对多
 | 
				
			||||||
 | 
					- Polymorphic 多态
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					比如一个微型博客的表结构可以这样设计:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					// 用户
 | 
				
			||||||
 | 
					app.collection({
 | 
				
			||||||
 | 
					  name: 'users',
 | 
				
			||||||
 | 
					  fields: {
 | 
				
			||||||
 | 
					    username: { type: 'string', unique: true },
 | 
				
			||||||
 | 
					    password: { type: 'password', unique: true },
 | 
				
			||||||
 | 
					    posts:    { type: 'hasMany' },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 文章
 | 
				
			||||||
 | 
					app.collection({
 | 
				
			||||||
 | 
					  name: 'posts',
 | 
				
			||||||
 | 
					  fields: {
 | 
				
			||||||
 | 
					    title:    'string',
 | 
				
			||||||
 | 
					    content:  'text',
 | 
				
			||||||
 | 
					    tags:     'belongsToMany',
 | 
				
			||||||
 | 
					    comments: 'hasMany',
 | 
				
			||||||
 | 
					    author:   { type: 'belongsTo', target: 'users' },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 标签
 | 
				
			||||||
 | 
					app.collection({
 | 
				
			||||||
 | 
					  name: 'tags',
 | 
				
			||||||
 | 
					  fields: [
 | 
				
			||||||
 | 
					    { type: 'string', name: 'name' },
 | 
				
			||||||
 | 
					    { type: 'belongsToMany', name: 'posts' },
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 评论
 | 
				
			||||||
 | 
					app.collection({
 | 
				
			||||||
 | 
					  name: 'comments',
 | 
				
			||||||
 | 
					  fields: [
 | 
				
			||||||
 | 
					    { type: 'text', name: 'content' },
 | 
				
			||||||
 | 
					    { type: 'belongsTo', name: 'user' },
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					除了通过 `app.collection()` 配置 schema,也可以直接调用 api 插入或修改 schema,collection 的核心 API 有:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `collection` 当前 collection 的数据结构
 | 
				
			||||||
 | 
					  - `collection.hasField()` 判断字段是否存在
 | 
				
			||||||
 | 
					  - `collection.addField()` 添加字段配置
 | 
				
			||||||
 | 
					  - `collection.getField()` 获取字段配置
 | 
				
			||||||
 | 
					  - `collection.removeField()` 移除字段配置
 | 
				
			||||||
 | 
					  - `collection.sync()` 与数据库表结构同步
 | 
				
			||||||
 | 
					- `collection.repository` 当前 collection 的数据仓库
 | 
				
			||||||
 | 
					  - `repository.findMany()`
 | 
				
			||||||
 | 
					  - `repository.findOne()`
 | 
				
			||||||
 | 
					  - `repository.create()`
 | 
				
			||||||
 | 
					  - `repository.update()`
 | 
				
			||||||
 | 
					  - `repository.destroy()`
 | 
				
			||||||
 | 
					  - `repository.relatedQuery().for()`
 | 
				
			||||||
 | 
					    - `create()`
 | 
				
			||||||
 | 
					    - `update()`
 | 
				
			||||||
 | 
					    - `destroy()`
 | 
				
			||||||
 | 
					    - `findMany()`
 | 
				
			||||||
 | 
					    - `findOne()`
 | 
				
			||||||
 | 
					    - `set()`
 | 
				
			||||||
 | 
					    - `add()`
 | 
				
			||||||
 | 
					    - `remove()`
 | 
				
			||||||
 | 
					    - `toggle()`
 | 
				
			||||||
 | 
					- `collection.model` 当前 collection 的数据模型
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Collection 示例:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					const collection = app.db.getCollection('posts');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					collection.hasField('title');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					collection.getField('title');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 添加或更新
 | 
				
			||||||
 | 
					collection.addField({
 | 
				
			||||||
 | 
					  type: 'string',
 | 
				
			||||||
 | 
					  name: 'content',
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 移除
 | 
				
			||||||
 | 
					collection.removeField('content');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 添加、或指定 key path 替换
 | 
				
			||||||
 | 
					collection.mergeField({
 | 
				
			||||||
 | 
					  name: 'content',
 | 
				
			||||||
 | 
					  type: 'string',
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					除了全局的 `db.sync()`,也有 `collection.sync()` 方法。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					await collection.sync();
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`db:sync` 是非常常用的命令行之一,数据库根据 collection 的 schema 生成表结构。更多详情见 CLI 章节。`db:sync` 之后,就可以往表里写入数据了,可以使用 Repository 或 Model 操作。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Repository 初步提供了 findAll、findOne、create、update、destroy 核心操作方法。
 | 
				
			||||||
 | 
					- Model 为 Sequelize.Model,详细使用说明可以查看 Sequelize 文档。
 | 
				
			||||||
 | 
					- Model 取决于适配的 ORM,Repository 基于 Model 提供统一的接口。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					通过 Repository 创建数据
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					const User = app.db.getCollection('users');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const user = await User.repository.create({
 | 
				
			||||||
 | 
					  title: 't1',
 | 
				
			||||||
 | 
					  content: 'c1',
 | 
				
			||||||
 | 
					  author: 1,
 | 
				
			||||||
 | 
					  tags: [1,2,3],
 | 
				
			||||||
 | 
					}, {
 | 
				
			||||||
 | 
					  whitelist: [],
 | 
				
			||||||
 | 
					  blacklist: [],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					await User.repository.findMany({
 | 
				
			||||||
 | 
					  filter: {
 | 
				
			||||||
 | 
					    title: 't1',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  fields: ['id', 'title', 'content'],
 | 
				
			||||||
 | 
					  sort: '-created_at',
 | 
				
			||||||
 | 
					  page: 1,
 | 
				
			||||||
 | 
					  perPage: 20,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					await User.repository.findOne({
 | 
				
			||||||
 | 
					  filter: {
 | 
				
			||||||
 | 
					    title: 't1',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  fields: ['id', 'title', 'content'],
 | 
				
			||||||
 | 
					  sort: '-created_at',
 | 
				
			||||||
 | 
					  page: 1,
 | 
				
			||||||
 | 
					  perPage: 20,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					await User.repository.update({
 | 
				
			||||||
 | 
					  title: 't1',
 | 
				
			||||||
 | 
					  content: 'c1',
 | 
				
			||||||
 | 
					  author: 1,
 | 
				
			||||||
 | 
					  tags: [1,2,3],
 | 
				
			||||||
 | 
					}, {
 | 
				
			||||||
 | 
					  filter: {},
 | 
				
			||||||
 | 
					  whitelist: [],
 | 
				
			||||||
 | 
					  blacklist: [],
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					await User.repository.destroy({
 | 
				
			||||||
 | 
					  filter: {},
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					通过 Model 创建数据
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					const User = db.getCollection('users');
 | 
				
			||||||
 | 
					const user = await User.model.create({
 | 
				
			||||||
 | 
					  title: 't1',
 | 
				
			||||||
 | 
					  content: 'c1',
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 资源 & 操作 - Resource & Action
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Resource 是互联网资源,互联网资源都对应一个地址。客户端请求资源地址,服务器响应请求,在这里「请求」就是一种「操作」,在 REST 里通过判断请求方法(GET/POST/PUT/DELETE)来识别具体的操作,但是请求方法局限性比较大,如上文提到的登录、注册、注销就无法用 REST API 的方式表示。为了解决这类问题,NocoBase 以 `<resourceName>:<actionName>` 格式表示资源的操作。在关系模型的世界里,关系无处不在,基于关系,NocoBase 又延伸了关系资源的概念,对应关系资源的操作的格式为 `<associatedName>.<resourceName>:<actionName>`。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Collection 会自动同步给 Resource,如上文 Collection 章节定义的 Schema,可以提炼的资源有:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `users`
 | 
				
			||||||
 | 
					- `users.posts`
 | 
				
			||||||
 | 
					- `posts`
 | 
				
			||||||
 | 
					- `posts.tags`
 | 
				
			||||||
 | 
					- `posts.comments`
 | 
				
			||||||
 | 
					- `posts.author`
 | 
				
			||||||
 | 
					- `tags`
 | 
				
			||||||
 | 
					- `tags.posts`
 | 
				
			||||||
 | 
					- `comments`
 | 
				
			||||||
 | 
					- `comments.user`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<Alert title="Collection 和 Resource 的关系与区别" type="warning">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Collection 定义数据的 schema(结构和关系)
 | 
				
			||||||
 | 
					- Resource 定义数据的 action(操作方法)
 | 
				
			||||||
 | 
					- Resource 请求和响应的数据结构由 Collection 定义
 | 
				
			||||||
 | 
					- Collection 默认自动同步给 Resource
 | 
				
			||||||
 | 
					- Resource 的概念更大,除了对接 Collection 以外,也可以对接外部数据或其他自定义
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</Alert>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					资源相关 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({
 | 
				
			||||||
 | 
					  name: 'users',
 | 
				
			||||||
 | 
					  actions: {
 | 
				
			||||||
 | 
					    list: {
 | 
				
			||||||
 | 
					      fields: ['id', 'username'], // 只输出 id 和 username 字段
 | 
				
			||||||
 | 
					      filter: {
 | 
				
			||||||
 | 
					        'username.$ne': 'admin', // 数据范围筛选过滤 username != admin
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      sort: ['-created_at'], // 创建时间倒序
 | 
				
			||||||
 | 
					      perPage: 50,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    get: {
 | 
				
			||||||
 | 
					      fields: ['id', 'username'], // 只输出 id 和 username 字段
 | 
				
			||||||
 | 
					      filter: {
 | 
				
			||||||
 | 
					        'username.$ne': 'admin', // 数据范围筛选过滤 username != admin
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    create: {
 | 
				
			||||||
 | 
					      fields: ['username'], // 白名单
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    update: {
 | 
				
			||||||
 | 
					      fields: ['username'], // 白名单
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    destroy: {
 | 
				
			||||||
 | 
					      filter: { // 不能删除 admin
 | 
				
			||||||
 | 
					        'username.$ne': 'admin',
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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) {},
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					在 Middleware Handler 和 Action Handler 里,都可以通过 `ctx.action` 获取到当前 action 实例,提供了两个非常有用的 API:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `ctx.action.params`:获取操作对应的参数
 | 
				
			||||||
 | 
					- `ctx.action.mergeParams()`:处理多来源参数合并
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`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;
 | 
				
			||||||
 | 
					  // ...
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`ctx.action.mergeParams()` 主要用于多来源参数合并,以 `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);
 | 
				
			||||||
 | 
					  // filter 是特殊的 and 合并
 | 
				
			||||||
 | 
					  // {
 | 
				
			||||||
 | 
					  //   and: [
 | 
				
			||||||
 | 
					  //     { created_at: '2021-09-15' },
 | 
				
			||||||
 | 
					  //     { status: 'publish' },
 | 
				
			||||||
 | 
					  //     { created_by_id: 1, }
 | 
				
			||||||
 | 
					  //   ]
 | 
				
			||||||
 | 
					  // }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 事件 - Event
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					在操作执行前、后都放置了相关事件监听器,可以通过 `app.db.on()` 和 `app.on()` 添加。区别在于:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `app.db.on()` 添加数据库层面的监听器
 | 
				
			||||||
 | 
					- `app.on()` 添加服务器应用层面的监听器
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					以 `users:login` 为例,在数据库里为「查询」操作,在应用里为「登录」操作。也就是说,如果需要记录登录操作日志,要在 `app.on()` 里处理。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					// 创建数据时,执行 User.create() 时触发
 | 
				
			||||||
 | 
					app.db.on('users.beforeCreate', async (model) => {});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 客户端 `POST /api/users:login` 时触发
 | 
				
			||||||
 | 
					app.on('users.beforeLogin', async (ctx, next) => {});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 客户端 `POST /api/users` 时触发
 | 
				
			||||||
 | 
					app.on('users.beforeCreate', async (ctx, next) => {});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 中间件 - Middleware
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Server Application 基于 Koa,所有 Koa 的插件(中间件)都可以直接使用,可以通过 `app.use()` 添加。如:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					const responseTime = require('koa-response-time');
 | 
				
			||||||
 | 
					app.use(responseTime());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.use(async (ctx, next) => {
 | 
				
			||||||
 | 
					  await next();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					与 `koa.use(middleware)` 略有不同,`app.use(middleware, options)` 多了个 options 参数,可以用于限定 resource 和 action,也可以用于控制中间件的插入位置。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					import { middleware } from '@nocobase/server';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.use(async (ctx, next) => {}, {
 | 
				
			||||||
 | 
					  name: 'middlewareName1',
 | 
				
			||||||
 | 
					  resourceNames: [], // 作用于资源内所有 actions
 | 
				
			||||||
 | 
					  actionNames: [
 | 
				
			||||||
 | 
					    'list', // 全部 list action
 | 
				
			||||||
 | 
					    'users:list', // 仅 users 资源的 list action,
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					  insertBefore: '',
 | 
				
			||||||
 | 
					  insertAfter: '',
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 命令行 - CLI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Application 除了可以做 HTTP Server 以外,也是 CLI(内置了 Commander)。目前内置的命令有:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- `init` 初始化
 | 
				
			||||||
 | 
					- `db:sync --force` 用于配置与数据库表结构同步
 | 
				
			||||||
 | 
					- `start --port` 启动应用
 | 
				
			||||||
 | 
					- `plugin:**` 插件相关
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					自定义:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					app.command('foo').action(async () => {
 | 
				
			||||||
 | 
					  console.log('foo...');
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 插件 - Plugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					上文,讲述了核心的扩展接口,包括但不局限于:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Database/Collection
 | 
				
			||||||
 | 
					  - `app.db` database 实例
 | 
				
			||||||
 | 
					  - `app.collection()` 等同于 `app.db.collection()`
 | 
				
			||||||
 | 
					- Resource/Action
 | 
				
			||||||
 | 
					  - `app.resource()` 等同于 `app.resourcer.define()`
 | 
				
			||||||
 | 
					  - `app.actions()` 等同于 `app.resourcer.registerActions()`
 | 
				
			||||||
 | 
					- Hook/Event
 | 
				
			||||||
 | 
					  - `app.on()` 添加服务器监听器
 | 
				
			||||||
 | 
					  - `app.db.on()` 添加数据库监听器
 | 
				
			||||||
 | 
					- Middleware
 | 
				
			||||||
 | 
					  - `app.use()` 添加中间件
 | 
				
			||||||
 | 
					- CLI
 | 
				
			||||||
 | 
					  - `app.cli` commander 实例
 | 
				
			||||||
 | 
					  - `app.command()` 等同于 `app.cli.command()`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					基于以上扩展接口,进一步提供了模块化、可插拔的插件,可以通过 `app.plugin()` 添加。插件的流程包括安装、升级、激活、载入、禁用、卸载,不需要的流程可缺失。如:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**最简单的插件**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					app.plugin(function pluginName1() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					这种方式添加的插件会直接载入,无需安装。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**JSON 风格**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					const plugin = app.plugin({
 | 
				
			||||||
 | 
					  enable: false, // 默认为 true,不需要启用时可以禁用。
 | 
				
			||||||
 | 
					  name: 'plugin-name1',
 | 
				
			||||||
 | 
					  displayName: '插件名称',
 | 
				
			||||||
 | 
					  version: '1.2.3',
 | 
				
			||||||
 | 
					  dependencies: {
 | 
				
			||||||
 | 
					    pluginName2: '1.x', 
 | 
				
			||||||
 | 
					    pluginName3: '1.x',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  async install() {},
 | 
				
			||||||
 | 
					  async upgrade() {},
 | 
				
			||||||
 | 
					  async activate() {},
 | 
				
			||||||
 | 
					  async bootstrap() {},
 | 
				
			||||||
 | 
					  async deactivate() {},
 | 
				
			||||||
 | 
					  async unstall() {},
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					// 通过 api 激活插件
 | 
				
			||||||
 | 
					plugin.activate();
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**OOP 风格**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					class MyPlugin extends Plugin {
 | 
				
			||||||
 | 
					  async install() {}
 | 
				
			||||||
 | 
					  async upgrade() {}
 | 
				
			||||||
 | 
					  async bootstrap() {}
 | 
				
			||||||
 | 
					  async activate() {}
 | 
				
			||||||
 | 
					  async deactivate() {}
 | 
				
			||||||
 | 
					  async unstall() {}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.plugin(MyPlugin);
 | 
				
			||||||
 | 
					// 或
 | 
				
			||||||
 | 
					app.plugin({
 | 
				
			||||||
 | 
					  name: 'plugin-name1',
 | 
				
			||||||
 | 
					  displayName: '插件名称',
 | 
				
			||||||
 | 
					  version: '1.2.3',
 | 
				
			||||||
 | 
					  dependencies: {
 | 
				
			||||||
 | 
					    pluginName2: '1.x', 
 | 
				
			||||||
 | 
					    pluginName3: '1.x',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  plugin: MyPlugin,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**引用独立的 Package**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					app.plugin('@nocobase/plugin-action-logs');
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					插件信息也可以直接写在 `package.json` 里
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```js
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  name: 'pluginName1',
 | 
				
			||||||
 | 
					  displayName: '插件名称',
 | 
				
			||||||
 | 
					  version: '1.2.3',
 | 
				
			||||||
 | 
					  dependencies: {
 | 
				
			||||||
 | 
					    pluginName2: '1.x', 
 | 
				
			||||||
 | 
					    pluginName3: '1.x',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**插件 CLI**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					plugin:install pluginName1
 | 
				
			||||||
 | 
					plugin:unstall pluginName1
 | 
				
			||||||
 | 
					plugin:activate pluginName1
 | 
				
			||||||
 | 
					plugin:deactivate pluginName1
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					目前已有的插件:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- @nocobase/plugin-collections 提供数据表配置接口,可通过 HTTP API 管理数据表。
 | 
				
			||||||
 | 
					- @nocobase/plugin-action-logs 操作日志
 | 
				
			||||||
 | 
					- @nocobase/plugin-automations 自动化(未升级 v0.5,暂不能使用)
 | 
				
			||||||
 | 
					- @nocobase/plugin-china-region 中国行政区
 | 
				
			||||||
 | 
					- @nocobase/plugin-client 提供客户端,无代码的可视化配置界面,需要与 @nocobase/client 配合使用
 | 
				
			||||||
 | 
					- @nocobase/plugin-export 导出
 | 
				
			||||||
 | 
					- @nocobase/plugin-file-manager 文件管理器
 | 
				
			||||||
 | 
					- @nocobase/plugin-permissions 角色和权限
 | 
				
			||||||
 | 
					- @nocobase/plugin-system-settings 系统配置
 | 
				
			||||||
 | 
					- @nocobase/plugin-ui-router 前端路由配置
 | 
				
			||||||
 | 
					- @nocobase/plugin-ui-schema ui 配置
 | 
				
			||||||
 | 
					- @nocobase/plugin-users 用户模块
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 测试 - Testing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					有代码就需要测试,@nocobase/test 提供了 mockDatabase 和 mockServer 用于数据库和服务器的测试,如:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					import { mockServer, MockServer } from '@nocobase/test';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('mock server', () => {
 | 
				
			||||||
 | 
					  let api: MockServer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  beforeEach(() => {
 | 
				
			||||||
 | 
					    api = mockServer({
 | 
				
			||||||
 | 
					      dataWrapping: false,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    api.actions({
 | 
				
			||||||
 | 
					      list: async (ctx, next) => {
 | 
				
			||||||
 | 
					        ctx.body = [1, 2];
 | 
				
			||||||
 | 
					        await next();
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    api.resource({
 | 
				
			||||||
 | 
					      name: 'test',
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  afterEach(async () => {
 | 
				
			||||||
 | 
					    return api.destroy();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('agent.get', async () => {
 | 
				
			||||||
 | 
					    const response = await api.agent().get('/test');
 | 
				
			||||||
 | 
					    expect(response.body).toEqual([1, 2]);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('agent.resource', async () => {
 | 
				
			||||||
 | 
					    const response = await api.agent().resource('test').list();
 | 
				
			||||||
 | 
					    expect(response.body).toEqual([1, 2]);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 客户端 - Client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					为了让更多非开发人员也能参与进来,NocoBase 提供了配套的客户端插件 —— 无代码的可视化配置界面。客户端插件需要与 @nocobase/client 配合使用,可以直接使用,也可以自行改造。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					插件配置
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```ts
 | 
				
			||||||
 | 
					app.plugin('@nocobase/plugin-client', {
 | 
				
			||||||
 | 
					  // 自定义 dist 路径
 | 
				
			||||||
 | 
					  dist: path.resolve(__dirname, './node_modules/@nocobase/client/app'),
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					为了满足各类场景需求,客户端 `@nocobase/client` 提供了丰富的基础组件:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Action - 操作
 | 
				
			||||||
 | 
					  - Action.Window 当前浏览器窗口/标签里打开
 | 
				
			||||||
 | 
					  - Action.Drawer 打开抽屉(默认右侧划出)
 | 
				
			||||||
 | 
					  - Action.Modal 打开对话框
 | 
				
			||||||
 | 
					  - Action.Dropdown 下拉菜单
 | 
				
			||||||
 | 
					  - Action.Popover 气泡卡片
 | 
				
			||||||
 | 
					  - Action.Group 按钮分组
 | 
				
			||||||
 | 
					  - Action.Bar 操作栏
 | 
				
			||||||
 | 
					- AddNew 「添加」模块
 | 
				
			||||||
 | 
					  - AddNew.CardItem -  添加区块
 | 
				
			||||||
 | 
					  - AddNew.PaneItem - 添加区块(查看面板,与当前查看的数据相关)
 | 
				
			||||||
 | 
					  - AddNew.FormItem -  添加字段
 | 
				
			||||||
 | 
					- BlockItem/CardItem/FormItem - 装饰器
 | 
				
			||||||
 | 
					  - BlockItem - 普通装饰器(无包装效果)
 | 
				
			||||||
 | 
					  - CardItem - 卡片装饰器
 | 
				
			||||||
 | 
					  - FormItem - 字段装饰器
 | 
				
			||||||
 | 
					- Calendar - 日历
 | 
				
			||||||
 | 
					- Cascader - 级联选择
 | 
				
			||||||
 | 
					- Chart - 图表
 | 
				
			||||||
 | 
					- Checkbox - 勾选
 | 
				
			||||||
 | 
					- Checkbox.Group - 多选框
 | 
				
			||||||
 | 
					- Collection - 数据表配置
 | 
				
			||||||
 | 
					- Collection.Field - 数据表字段
 | 
				
			||||||
 | 
					- ColorSelect - 颜色选择器
 | 
				
			||||||
 | 
					- DatePicker - 日期选择器
 | 
				
			||||||
 | 
					- DesignableBar - 配置工具栏
 | 
				
			||||||
 | 
					- Filter - 筛选器
 | 
				
			||||||
 | 
					- Form - 表单
 | 
				
			||||||
 | 
					- Grid - 栅格布局
 | 
				
			||||||
 | 
					- IconPicker - 图标选择器
 | 
				
			||||||
 | 
					- Input - 输入框
 | 
				
			||||||
 | 
					- Input.TextArea - 多行输入框
 | 
				
			||||||
 | 
					- InputNumber - 数字框
 | 
				
			||||||
 | 
					- Kanban - 看板
 | 
				
			||||||
 | 
					- ListPicker - 列表选择器(用于选择、展示关联数据)
 | 
				
			||||||
 | 
					- Markdown 编辑器
 | 
				
			||||||
 | 
					- Menu - 菜单
 | 
				
			||||||
 | 
					- Password - 密码
 | 
				
			||||||
 | 
					- Radio - 单选框
 | 
				
			||||||
 | 
					- Select - 选择器
 | 
				
			||||||
 | 
					- Table - 表格
 | 
				
			||||||
 | 
					- Tabs - 标签页
 | 
				
			||||||
 | 
					- TimePicker - 时间选择器
 | 
				
			||||||
 | 
					- Upload - 上传
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					可以自行扩展组件,以上组件基于 Formily 构建,怎么自定义组件大家查看相关组件源码或 Formily 文档,这里说点不一样的。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 如何扩展数据库字段?
 | 
				
			||||||
 | 
					- 如何将第三方区块添加到 AddNew 模块中?
 | 
				
			||||||
 | 
					- 如何在操作栏里添加更多的内置操作?
 | 
				
			||||||
 | 
					- 如何自定义配置工具栏?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					除了组件具备灵活的扩展以外,客户端也可以在任意前端框架中使用,可以自定义 Request 和 Router,如:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<pre lang="tsx">
 | 
				
			||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import { MemoryRouter } from 'react-router-dom';
 | 
				
			||||||
 | 
					import { ClientSDK, Application } from '@nocobase/client';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 初始化 client 实例
 | 
				
			||||||
 | 
					const client = new ClientSDK({
 | 
				
			||||||
 | 
					  request: (options) => Promise.resolve({}),
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 适配 Route Component
 | 
				
			||||||
 | 
					const RouteSwitch = createRouteSwitch({
 | 
				
			||||||
 | 
					  components: {
 | 
				
			||||||
 | 
					    AdminLayout,
 | 
				
			||||||
 | 
					    AuthLayout,
 | 
				
			||||||
 | 
					    RouteSchemaRenderer,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ReactDOM.render(
 | 
				
			||||||
 | 
					  <ClientProvider client={client}>
 | 
				
			||||||
 | 
					    <MemoryRouter initialEntries={['/admin']}>
 | 
				
			||||||
 | 
					      <RouteSwitch routes={[]}/>
 | 
				
			||||||
 | 
					    </MemoryRouter>
 | 
				
			||||||
 | 
					  </ClientProvider>,
 | 
				
			||||||
 | 
					  document.getElementById('root'),
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					</pre>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					更多细节,可以通过 `create-nocobase-app` 初始化项目脚手架并体验。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					yarn create nocobase-app my-nocobase-project
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					nocobase-app 默认使用 umijs 作为项目构建工具,并集成了 Server 作数据接口,初始化的目录结构如下:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					|- src
 | 
				
			||||||
 | 
					  |- pages
 | 
				
			||||||
 | 
					  |- apis
 | 
				
			||||||
 | 
					|- .env
 | 
				
			||||||
 | 
					|- .umirc.ts
 | 
				
			||||||
 | 
					|- package.json
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 场景 - Cases
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					小型管理信息系统,具备完整的前后端。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<img src="../../images/MiniMIS.png" style="max-width: 300px; width: 100%;">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					API 服务,无客户端,提供纯后端接口。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<img src="../../images/API.png" style="max-width: 280px; width: 100%;">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					小程序 + 后台管理,只需要一套数据库,但有两套用户和权限,一套用于后台用户,一套用于小程序用户。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<img src="../../images/MiniProgram.png" style="max-width: 600px; width: 100%;">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SaaS 服务(共享用户),每个应用有自己配套的数据库,各应用数据完全隔离。应用不需要用户和权限模块,SaaS 主站全局共享了。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<img src="../../images/SaaS2.png" style="max-width: 450px; width: 100%;">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SaaS 服务(独立用户),每个应用有自己的独立用户模块和权限,应用可以绑定自己的域名。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<img src="../../images/SaaS1.png" style="max-width: 450px; width: 100%;">
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user