新功能
支援多資料來源
新增「資料來源管理」插件,用於管理資料來源的所有資料表和欄位。資料來源管理插件提供統一的介面來管理資料來源,本身不提供存取資料來源的能力,需要與各種資料來源插件搭配使用。目前已支援的資料來源包括:
- 主資料庫:NocoBase 主資料庫,支援 MySQL、PostgreSQL、SQLite 等關聯式資料庫。
- 外部 MySQL 資料來源:存取已有的 MySQL 資料庫作為資料來源。
- 外部 MariaDB 資料來源:存取已有的 MariaDB 資料庫作為資料來源。
- 外部 PostgreSQL 資料來源:存取已有的 PostgreSQL 資料庫作為資料來源。
此外,還可以擴展更多資料來源,可以是常見類型的資料庫,也可以是提供 API(SDK)的平台。

集合管理調整
將原「集合管理」移至「資料來源 > 主資料庫 > 配置」。

支援非 ID 欄位作為主鍵與關聯約束
建立集合時,可以選擇不建立 ID 欄位。

整數欄位可作為主鍵。

單行文字欄位也可作為主鍵。

關聯約束支援選擇其他設定了唯一索引的非主鍵欄位。

拖曳排序調整
新增「排序」類型欄位。排序欄位不再於建立集合時自動產生,需手動建立。

選擇欄位作為分組時,會先進行分組再排序。

在表格區塊中啟用拖曳排序時,需選擇排序欄位。

建立看板區塊時,需選擇排序欄位。

使用者與權限介面調整
新增使用者管理介面,並將使用者與角色管理統一在一個選單下。

調整角色管理介面,方便管理使用者關聯的角色、權限、部門等。

將原「操作權限」移至「資料來源」頁籤。

部門插件

按部門組織使用者,設定層級關係,關聯角色以控制權限,並在工作流程和表達式中將部門作為變數使用。
工作流程:審批
審批插件提供了專用的工作流程類型(觸發器)「發起審批」和「審批」節點。結合 NocoBase 獨特的自訂資料表和自訂區塊,可以快速靈活地建立和管理各種審批場景。
審批配置

審批流程

更多詳情請參閱文件:工作流程審批
工作流程:結束流程節點
此節點在執行時立即結束當前工作流程的執行,並以節點中配置的狀態結束。通常用於特定的邏輯流程控制,在滿足某些邏輯條件後退出當前工作流程,不繼續執行後續處理。可類比為程式語言中的 return 指令,用於退出當前執行的函數。

更多詳情請參閱文件:結束流程節點
工作流程:自訂變數節點
可以在工作流程中宣告變數,或為先前宣告的變數賦值,通常用於儲存工作流程中的臨時資料。適用於需要儲存計算結果以供後續在分支外部(如迴圈、並行等)使用的場景。

更多詳情請參閱文件:自訂變數節點
工作流程:請求攔截器
請求攔截器插件提供了一種攔截表單操作的機制,攔截事件在對應表單操作提交後、處理前觸發。如果觸發後續流程中執行了「結束流程」節點,或其他節點執行失敗(錯誤或其他未完成執行),則表單操作將被攔截,否則將正常執行預定操作。可用於業務驗證或邏輯檢查,以批准或攔截用戶端提交的新增、更新和刪除操作。

更多詳情請參閱文件:請求攔截器
工作流程:回應訊息節點
回應訊息節點用於在特定類型的工作流程(如請求攔截和表單事件)中,向客戶端提供自訂訊息的回饋。
節點配置

提示訊息

更多詳情請參閱文件:回應訊息節點
不相容的變更
名稱衝突的 API
在此次核心變更中,部分新版本的 API 與舊版本名稱衝突。這些衝突的舊版本 API 將在此版本中保留,但會統一加上 _deprecated 後綴。
| 原始 API | 已棄用的 API | 新 API |
|---|---|---|
| CollectionProvider | CollectionProvider_deprecated | CollectionProvider |
| useCollection | useCollection_deprecated | useCollection |
| useCollectionField | useCollectionField_deprecated | useCollectionField |
| useCollectionManager | useCollectionManager_deprecated | useCollectionManager |
| useContext(CollectionManagerContext) | useCollectionManager_deprecated | useCollectionManager |
如果您正在使用上述相關 API,有兩種變更方式:
- 簡單替換:將原始 API 替換為帶有
_deprecated後綴的 API,例如將useCollection()替換為useRecord_deprecated()。 - 根據新文件使用新 API:雖然新 API 的名稱與舊 API 相同,但參數和回傳值有所不同。您需要參考新文件來調整對應的程式碼。
其他需要調整的 API
registerTemplate()改為app.dataSourceManager.addCollectionTemplates()registerField()改為app.dataSourceManager.addFieldInterfaces()registerGroup()改為app.dataSourceManager.addFieldInterfaceGroups()useContext(CollectionManagerContext)改為useCollectionManager_deprecated()- 使用
ExtendCollectionsProvider擴展集合 RecordProvider在需要時需明確傳遞 parent 參數
變更範例
集合模板擴展
定義
先前定義為物件,現在需要改為類別。例如:
之前:
import { ICollectionTemplate } from '@nocobase/client';
const calendar: ICollectionTemplate = {
name: 'calendar',
title: '日曆集合',
order: 2,
color: 'orange',
// ...
}
現在:
import { CollectionTemplate } from '@nocobase/client';
class CalendarCollectionTemplate extends CollectionTemplate {
name = 'calendar';
title = '日曆集合';
order = 2;
color = 'orange';
}
原物件的屬性變為類別成員。
註冊
先前透過 registerTemplate 註冊,現在需要透過插件的 dataSourceManager.addCollectionTemplates 註冊。例如:
之前:
import { registerTemplate } from '@nocobase/client';
import { calendar } from './calendar'
registerTemplate('calendar', calendar);
現在:
import { Plugin } from '@nocobase/client';
import { CalendarCollectionTemplate } from './calendar'
export class CalendarPluginClient extends Plugin {
async load() {
this.app.dataSourceManager.addCollectionTemplates([CalendarCollectionTemplate]);
}
}
欄位介面擴展
定義
先前定義為物件,現在需要改為類別。例如:
之前:
import { IField } from '@nocobase/client';
const attachment: IField = {
name: 'attachment',
type: 'object',
group: 'media',
title: '附件',
// ...
}
現在:
import { CollectionFieldInterface } from '@nocobase/client';
class AttachmentFieldInterface extends CollectionFieldInterface {
name = 'attachment';
type = 'object';
group = 'media';
title = '附件';
// ...
}
原物件的屬性變為類別成員。
註冊
先前透過 registerField 註冊,現在需要透過插件的 dataSourceManager.addFieldInterfaces 註冊,且無需再次傳遞 CollectionManagerProvider。例如:
之前:
import { registerField } from '@nocobase/client';
import { attachment } from './attachment'
- registerField(attachment.group, 'attachment', attachment);
export const FileManagerProvider: FC = (props) => {
return (
- <CollectionManagerProvider interfaces={{ attachment }}>
<SchemaComponentOptions scope={hooks} components={{ UploadActionInitializer }}>
{props.children}
</SchemaComponentOptions>
- </CollectionManagerProvider>
);
};
現在:
import { Plugin } from '@nocobase/client';
import { AttachmentFieldInterface } from './attachment'
export class FilPlugin extends Plugin {
async load() {
this.app.dataSourceManager.addFieldInterfaces([AttachmentFieldInterface]);
}
}
欄位介面群組擴展
先前透過 registerGroup 註冊,現在需要透過插件的 dataSourceManager.addFieldInterfaceGroups 註冊。例如:
- import { registerGroup, Plugin } from '@nocobase/client';
+ import { Plugin } from '@nocobase/client';
- registerGroup('map', {
- label: '基於地圖的幾何',
- order: 10
- })
export class MapPlugin extends Plugin {
async load() {
+ this.app.dataSourceManager.addFieldInterfaceGroups({
+ map: {
+ label: generateNTemplate('基於地圖的幾何'),
+ order: 51,
+ },
+ });
}
}
useContext(CollectionManagerContext) 改為 useCollectionManager_deprecated()
- const ctx = useContext(CollectionManagerContext);
+ const ctx = useCollectionManager_deprecated();
擴展集合,使用 ExtendCollectionsProvider 取代 CollectionManagerProvider
const Demo = () => {
- <CollectionManagerProvider collections={[apiKeysCollection]}>
+ <ExtendCollectionsProvider collections={[apiKeysCollection]}>
...
- </CollectionManagerProvider>
+ </ExtendCollectionsProvider>
}
RecordProvider 的變更
先前未傳遞 parent 屬性時,會自動取得上一個 RecordProvider 的值作為 parent。現在需要明確傳遞 parent,當未傳遞 parent 時,parent 的值將為 undefined。
- <RecordProvider record={recordData}>
+ <RecordProvider record={recordData} parent={parentRecordData}>
...
</RecordProvider>
如果沒有歷史包袱,也可以直接使用 CollectionRecordProvider 來取代。
- <RecordProvider record={recordData}>
+ <CollectionRecordProvider record={recordData} parent={parentRecordData}>
...
- </RecordProvider>
+ </CollectionRecordProvider>
⚠️RecordProvider 與 CollectionRecordProvider 的差異
- RecordProvider 已棄用,將在未來版本中移除。
- RecordProvider 攜帶舊的 RecordContext,而 CollectionRecordProvider 則沒有。