diff --git a/packages/plugins/@hera/plugin-approval/src/client/configuration/trigger/Approval.trigger.tsx b/packages/plugins/@hera/plugin-approval/src/client/configuration/trigger/Approval.trigger.tsx
index 967174181..aa25021a6 100644
--- a/packages/plugins/@hera/plugin-approval/src/client/configuration/trigger/Approval.trigger.tsx
+++ b/packages/plugins/@hera/plugin-approval/src/client/configuration/trigger/Approval.trigger.tsx
@@ -172,11 +172,6 @@ export class ApprovalTrigger extends Trigger {
       compile,
       getCollectionFields,
     });
-    console.log(
-      '%c Line:176 🍷 collectionFieldOptions',
-      'font-size:18px;color:#33a5ff;background:#3f7cff',
-      collectionFieldOptions,
-    );
     return collectionFieldOptions;
   }
 
diff --git a/packages/plugins/@hera/plugin-approval/src/client/usage/approval-block/ApprovalBlock.provider.tsx b/packages/plugins/@hera/plugin-approval/src/client/usage/approval-block/ApprovalBlock.provider.tsx
index fa74b5718..3504618da 100644
--- a/packages/plugins/@hera/plugin-approval/src/client/usage/approval-block/ApprovalBlock.provider.tsx
+++ b/packages/plugins/@hera/plugin-approval/src/client/usage/approval-block/ApprovalBlock.provider.tsx
@@ -1,5 +1,6 @@
-import { ExtendCollectionsProvider, TableBlockProvider, useRecord } from '@tachybase/client';
 import React from 'react';
+import { ExtendCollectionsProvider, TableBlockProvider, useRecord } from '@tachybase/client';
+
 import { CollectionApprovalTodos } from '../../common/Cn.ApprovalTodos';
 import { CollectionApprovals } from '../approval-common/Approvals.collection';
 import { CollectionFlowNodes } from '../approval-common/FlowNodes.collection';
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/.npmignore b/packages/plugins/@tachybase/plugin-workflow-notice/.npmignore
new file mode 100644
index 000000000..65f5e8779
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/.npmignore
@@ -0,0 +1,2 @@
+/node_modules
+/src
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/README.md b/packages/plugins/@tachybase/plugin-workflow-notice/README.md
new file mode 100644
index 000000000..f7ffdf277
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/README.md
@@ -0,0 +1 @@
+# @tachybase/plugin-workflow-notice
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/client.d.ts b/packages/plugins/@tachybase/plugin-workflow-notice/client.d.ts
new file mode 100644
index 000000000..6c459cbac
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/client.d.ts
@@ -0,0 +1,2 @@
+export * from './dist/client';
+export { default } from './dist/client';
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/client.js b/packages/plugins/@tachybase/plugin-workflow-notice/client.js
new file mode 100644
index 000000000..b6e3be70e
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/client.js
@@ -0,0 +1 @@
+module.exports = require('./dist/client/index.js');
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/package.json b/packages/plugins/@tachybase/plugin-workflow-notice/package.json
new file mode 100644
index 000000000..e19c99454
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/package.json
@@ -0,0 +1,34 @@
+{
+  "name": "@tachybase/plugin-workflow-notice",
+  "displayName": "Workflow: Notice",
+  "version": "0.21.32",
+  "description": "A powerful BPM tool that provides foundational support for business automation, with the capability to extend unlimited triggers and nodes.",
+  "keywords": [
+    "Workflow",
+    "Notice"
+  ],
+  "main": "dist/server/index.js",
+  "devDependencies": {
+    "@ant-design/icons": "5.x",
+    "@tachybase/actions": "workspace:*",
+    "@tachybase/components": "workspace:*",
+    "@tachybase/data-source-manager": "workspace:*",
+    "@tachybase/database": "workspace:*",
+    "@tachybase/plugin-ui-schema-storage": "workspace:*",
+    "@tachybase/schema": "workspace:*",
+    "@tachybase/utils": "workspace:*",
+    "antd": "5.16.1",
+    "lodash": "^4.17.21",
+    "react": "18.x",
+    "react-i18next": "^11.15.1",
+    "sequelize": "^6.26.0"
+  },
+  "peerDependencies": {
+    "@tachybase/client": "workspace:*",
+    "@tachybase/plugin-workflow": "workspace:*",
+    "@tachybase/server": "workspace:*",
+    "@tachybase/test": "workspace:*"
+  },
+  "description.zh-CN": "工作流节点, 通知。",
+  "displayName.zh-CN": "工作流: 通知"
+}
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/server.d.ts b/packages/plugins/@tachybase/plugin-workflow-notice/server.d.ts
new file mode 100644
index 000000000..c41081ddc
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/server.d.ts
@@ -0,0 +1,2 @@
+export * from './dist/server';
+export { default } from './dist/server';
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/server.js b/packages/plugins/@tachybase/plugin-workflow-notice/server.js
new file mode 100644
index 000000000..972842039
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/server.js
@@ -0,0 +1 @@
+module.exports = require('./dist/server/index.js');
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/src/client/common/flowNodes.collection.ts b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/common/flowNodes.collection.ts
new file mode 100644
index 000000000..6f397decb
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/common/flowNodes.collection.ts
@@ -0,0 +1,42 @@
+import { tval } from '../locale';
+
+export const CollectionFlowNodes = {
+  title: tval('Node'),
+  name: 'flow_nodes',
+  fields: [
+    {
+      type: 'bigInt',
+      name: 'id',
+      interface: 'm2o',
+      uiSchema: {
+        type: 'number',
+        title: 'ID',
+        'x-component': 'RemoteSelect',
+        'x-component-props': {
+          fieldNames: {
+            label: 'title',
+            value: 'id',
+          },
+          service: {
+            resource: 'flow_nodes',
+            params: {
+              filter: {
+                type: 'manual',
+              },
+            },
+          },
+        },
+      },
+    },
+    {
+      type: 'string',
+      name: 'title',
+      interface: 'input',
+      uiSchema: {
+        type: 'string',
+        title: '{{t("Title")}}',
+        'x-component': 'Input',
+      },
+    },
+  ],
+};
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/src/client/common/notice.collection.ts b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/common/notice.collection.ts
new file mode 100644
index 000000000..bed7bbbd2
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/common/notice.collection.ts
@@ -0,0 +1,144 @@
+import { COLLECTION_NOTICE_NAME } from '../../common/constants';
+import { NAMESPACE, tval } from '../locale';
+import { approvalStatusOptions } from '../usage/column/column.status';
+
+export const CollectionWorkflowNotice = {
+  title: tval('Notice Center'),
+  name: COLLECTION_NOTICE_NAME,
+  fields: [
+    {
+      type: 'bigInt',
+      name: 'id',
+      interface: 'number',
+      uiSchema: {
+        type: 'number',
+        title: 'ID',
+        'x-component': 'InputNumber',
+      },
+    },
+    {
+      type: 'belongsTo',
+      name: 'user',
+      target: 'users',
+      foreignKey: 'userId',
+      interface: 'm2o',
+      uiSchema: {
+        type: 'number',
+        title: tval('The Notified Person'),
+        'x-component': 'RemoteSelect',
+        'x-component-props': {
+          fieldNames: {
+            label: 'nickname',
+            value: 'id',
+          },
+          service: { resource: 'users' },
+        },
+      },
+    },
+    {
+      type: 'belongsTo',
+      name: 'node',
+      target: 'flow_nodes',
+      foreignKey: 'nodeId',
+      interface: 'm2o',
+      isAssociation: true,
+      uiSchema: {
+        type: 'number',
+        title: `{{t("Task node", { ns: "${NAMESPACE}" })}}`,
+        'x-component': 'RemoteSelect',
+        'x-component-props': {
+          fieldNames: {
+            label: 'title',
+            value: 'id',
+          },
+          service: {
+            resource: 'flow_nodes',
+          },
+        },
+      },
+    },
+    {
+      type: 'belongsTo',
+      name: 'workflow',
+      target: 'workflows',
+      foreignKey: 'workflowId',
+      interface: 'm2o',
+      uiSchema: {
+        type: 'number',
+        title: '{{t("Workflow", { ns: "workflow" })}}',
+        'x-component': 'RemoteSelect',
+        'x-component-props': {
+          fieldNames: {
+            label: 'title',
+            value: 'id',
+          },
+          service: { resource: 'workflows' },
+        },
+      },
+    },
+    {
+      type: 'integer',
+      name: 'status',
+      interface: 'select',
+      uiSchema: {
+        type: 'number',
+        title: '{{t("Status", { ns: "workflow" })}}',
+        'x-component': 'Select',
+        enum: approvalStatusOptions,
+      },
+    },
+    {
+      type: 'text',
+      name: 'comment',
+      interface: 'markdown',
+      uiSchema: {
+        type: 'string',
+        'x-component': 'Markdown',
+        title: `{{t("Comment", { ns: "${NAMESPACE}" })}}`,
+      },
+    },
+    {
+      name: 'createdAt',
+      type: 'date',
+      interface: 'createdAt',
+      uiSchema: {
+        type: 'datetime',
+        title: '{{t("Created at")}}',
+        'x-component': 'DatePicker',
+        'x-component-props': {
+          showTime: true,
+        },
+      },
+    },
+    {
+      name: 'updatedAt',
+      type: 'date',
+      interface: 'updatedAt',
+      uiSchema: {
+        type: 'datetime',
+        title: '{{t("Updated at")}}',
+        'x-component': 'DatePicker',
+        'x-component-props': {
+          showTime: true,
+        },
+      },
+    },
+    {
+      type: 'string',
+      name: 'summary',
+      interface: 'input',
+      uiSchema: {
+        type: 'string',
+        title: tval('Summary'),
+        'x-component': 'ApprovalsSummary',
+        'x-component-props': {
+          style: {
+            overflow: 'hidden',
+            textOverflow: 'ellipsis',
+            whiteSpace: 'nowrap',
+          },
+        },
+      },
+    },
+  ],
+};
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/src/client/common/workflow.collection.ts b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/common/workflow.collection.ts
new file mode 100644
index 000000000..c21f50dc1
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/common/workflow.collection.ts
@@ -0,0 +1,39 @@
+import { tval } from '../locale';
+
+export const CollectionWorkflows = {
+  title: tval('Workflow'),
+  name: 'workflows',
+  fields: [
+    {
+      type: 'string',
+      name: 'title',
+      interface: 'input',
+      uiSchema: {
+        title: '{{t("Name")}}',
+        type: 'string',
+        'x-component': 'Input',
+        required: true,
+      },
+    },
+    {
+      type: 'boolean',
+      name: 'enabled',
+      interface: 'select',
+      uiSchema: {
+        type: 'boolean',
+        title: '{{t("Status", { ns: "workflow" })}}',
+        'x-component': 'Select',
+        enum: [
+          {
+            label: '{{t("On", { ns: "workflow" })}}',
+            value: true,
+          },
+          {
+            label: '{{t("Off", { ns: "workflow" })}}',
+            value: false,
+          },
+        ],
+      },
+    },
+  ],
+};
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/Notice.instruction.ts b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/Notice.instruction.ts
new file mode 100644
index 000000000..217d2f23e
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/Notice.instruction.ts
@@ -0,0 +1,95 @@
+import { ArrayItems } from '@tachybase/components';
+import { Instruction } from '@tachybase/plugin-workflow/client';
+
+import { NOTICE_INSTRUCTION_NAMESPACE } from '../../common/constants';
+import { tval } from '../locale';
+import { AdditionNotifiedPerson } from './config-items/AddNotifiedPerson.view';
+import { ConfigButtonNotice } from './config-items/ConfigButtonNotice.view';
+import { SelectNotifiedPerson } from './config-items/SelectNotifiedPerson.view';
+import { NoticeDetailContainer } from './show-interface/NoticeDetailContainer.schema';
+import { configSytles } from './style';
+
+// group 的取值, 经查询猜测,可能为
+// 'control' 'collection' 'extended' 'manual' 'advanced'
+// TODO: 需要整理梳理 workflow, 将这个类型转移到 workflow 中去
+type GroupType = 'control' | 'collection' | 'extended' | 'manual' | 'advanced';
+
+export class NoticeInstruction extends Instruction {
+  title = tval('Notice');
+  type = NOTICE_INSTRUCTION_NAMESPACE;
+  group: GroupType = 'extended';
+  description = tval(
+    'In the workflow, notification messages can be viewed by the notified person in the notification center.',
+  );
+  components = {
+    ArrayItems: ArrayItems,
+    SelectNotifiedPerson: SelectNotifiedPerson,
+    AdditionNotifiedPerson: AdditionNotifiedPerson,
+    ConfigButtonNotice: ConfigButtonNotice,
+    ShowNoticeDetail: NoticeDetailContainer,
+  };
+  fieldset = {
+    notifiedPerson: {
+      type: 'array',
+      title: tval('The Notified Person'),
+      required: true,
+      'x-decorator': 'FormItem',
+      'x-component': 'ArrayItems',
+      'x-component-props': {
+        className: configSytles.ArrayItemsStyle,
+      },
+
+      items: {
+        type: 'void',
+        'x-component': 'Space',
+        'x-component-props': {
+          className: configSytles.SpaceStyle,
+        },
+        properties: {
+          sort: {
+            type: 'void',
+            'x-decorator': 'FormItem',
+            'x-component': 'ArrayItems.SortHandle',
+          },
+          input: {
+            type: 'string',
+            'x-decorator': 'FormItem',
+            'x-component': 'SelectNotifiedPerson',
+          },
+          remove: {
+            type: 'void',
+            'x-decorator': 'FormItem',
+            'x-component': 'ArrayItems.Remove',
+          },
+        },
+      },
+      properties: {
+        add: {
+          type: 'void',
+          title: tval('Add Notified Person'),
+          // HACK: 这里原本的框架逻辑, 解析竟然和 Addition 这个单词绑定, 奇怪
+          // 类似的还有, Index, Remove, MoveUp, MoveDown, Copy
+          // isOperationComponent() 针对这类操作组件, 做了特殊逻辑
+          'x-component': 'AdditionNotifiedPerson',
+        },
+      },
+    },
+    showNoticeDetail: {
+      type: 'void',
+      title: tval('Show Notice Detail'),
+      required: true,
+      'x-decorator': 'FormItem',
+      'x-component': 'ConfigButtonNotice',
+      properties: {
+        showNoticeDetail: {
+          type: 'void',
+          'x-component': 'ShowNoticeDetail',
+        },
+      },
+    },
+  };
+
+  isAvailable(params) {
+    return true;
+  }
+}
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/config-items/AddNotifiedPerson.view.tsx b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/config-items/AddNotifiedPerson.view.tsx
new file mode 100644
index 000000000..5b4b28064
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/config-items/AddNotifiedPerson.view.tsx
@@ -0,0 +1,58 @@
+// import { PlusOutlined } from '@ant-design/icons';
+import React, { useCallback, useState } from 'react';
+import { ArrayItems } from '@tachybase/components';
+import { useWorkflowExecuted } from '@tachybase/plugin-workflow/client';
+
+import { Button, Popover, Space } from 'antd';
+
+import { useTranslation } from '../../locale';
+
+export const AdditionNotifiedPerson = () => {
+  const isWorkflowExecuted = useWorkflowExecuted();
+  const array = ArrayItems.useArray() || { field: [] };
+  const { t } = useTranslation();
+  const [isOpen, setIsOpen] = useState(false);
+
+  const onSlecet = useCallback(() => {
+    array.field.push('');
+    setIsOpen(false);
+  }, [array.field]);
+
+  const onQuery = useCallback(() => {
+    array.field.push({ filter: {} });
+    setIsOpen(false);
+  }, [array.field]);
+
+  return (
+    }
+    >
+      }
+        type="dashed"
+        block={true}
+        disabled={isWorkflowExecuted}
+      >
+        {t('Add Notified Person')}
+      
+    
+  );
+};
+
+// Child Component
+const PopoverContent = ({ onSlecet, onQuery }) => {
+  const { t } = useTranslation();
+  return (
+    
+      
+      
+    
+  );
+};
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/config-items/ConfigButtonNotice.view.tsx b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/config-items/ConfigButtonNotice.view.tsx
new file mode 100644
index 000000000..a86cf07ad
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/config-items/ConfigButtonNotice.view.tsx
@@ -0,0 +1,26 @@
+import React, { useCallback, useState } from 'react';
+import { ActionContextProvider } from '@tachybase/client';
+
+import { Button } from 'antd';
+
+import { useTranslation } from '../../locale';
+
+export const ConfigButtonNotice = (props) => {
+  const { t } = useTranslation();
+  const [visible, setVisible] = useState(false);
+
+  const handleButtonClick = useCallback(() => {
+    setVisible(true);
+  }, [setVisible]);
+
+  return (
+    <>
+      
+      
+        {props.children}
+      
+    >
+  );
+};
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/config-items/SelectNotifiedPerson.view.tsx b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/config-items/SelectNotifiedPerson.view.tsx
new file mode 100644
index 000000000..a211e53fb
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/config-items/SelectNotifiedPerson.view.tsx
@@ -0,0 +1,62 @@
+import { RemoteSelect, SchemaComponent, Variable, useCollectionFilterOptions, useToken } from '@tachybase/client';
+import { FilterDynamicComponent, useWorkflowVariableOptions } from '@tachybase/plugin-workflow/client';
+import { useField } from '@tachybase/schema';
+import React from 'react';
+
+// TODO: 可以将这个选择组件封装为一个通用组件, 放在 workflow 下提供使用
+export const SelectNotifiedPerson = (props) => {
+  if (props.value && typeof props.value === 'object') {
+    return ;
+  } else {
+    return ;
+  }
+};
+
+const SelectNotifiedPersonNormal = ({ value, onChange }) => {
+  const scope = useWorkflowVariableOptions({ types: [isUserKeyField] });
+  return (
+    
+      
+    
+  );
+};
+
+const SelectNotifiedPersonCustom = () => {
+  const field = useField();
+  const currentFormFields = useCollectionFilterOptions('users');
+  const { token } = useToken();
+  return (
+    
+      
+    
+  );
+};
+
+function isUserKeyField(field) {
+  if (field.isForeignKey) {
+    return field.target === 'users';
+  } else {
+    return field.collectionName === 'users' && field.name === 'id';
+  }
+}
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/kit.ts b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/kit.ts
new file mode 100644
index 000000000..957bb852d
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/kit.ts
@@ -0,0 +1,24 @@
+import { Plugin } from '@tachybase/client';
+import PluginWorkflow from '@tachybase/plugin-workflow/client';
+import { NoticeInstruction } from './Notice.instruction';
+import { NOTICE_INSTRUCTION_NAMESPACE } from '../../common/constants';
+import { SCNoticeDetail } from './show-interface/NoticeDetail.schema';
+import { ArrayItems } from '@tachybase/components';
+
+// NOTE: 试着用一种新的约束规则去声明文件属于哪种功能. 比如 kit.ts 导出的是单个 Plugin 下的功能集成
+// 注册一个节点
+export class KitConfiguration extends Plugin {
+  async afterAdd() {
+    await this.app.pm.add(SCNoticeDetail);
+  }
+
+  async load() {
+    const pluginWorkflow = this.app.pm.get(PluginWorkflow);
+    pluginWorkflow.registerInstruction(NOTICE_INSTRUCTION_NAMESPACE, NoticeInstruction);
+    this.app.addComponents({
+      ArrayItems,
+    });
+    // this.app.schemaInitializerManager.add(ApproverActionConfigInitializer);
+    // this.app.schemaInitializerManager.add(ApproverAddBlockInitializer);
+  }
+}
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/show-interface/NoticeDetail.block.tsx b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/show-interface/NoticeDetail.block.tsx
new file mode 100644
index 000000000..9f9578106
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/show-interface/NoticeDetail.block.tsx
@@ -0,0 +1,45 @@
+import React from 'react';
+import {
+  createReadPrettyFormBlockSchema,
+  parseCollectionName,
+  SchemaInitializerItem,
+  useRecordCollectionDataSourceItems,
+  useSchemaInitializer,
+  useSchemaInitializerItem,
+  useSchemaTemplateManager,
+} from '@tachybase/client';
+import { useFlowContext } from '@tachybase/plugin-workflow/client';
+
+import _ from 'lodash';
+
+export const NoticeDetailAddBlock = () => {
+  const { workflow } = useFlowContext();
+  const [dataSourceName, collection] = parseCollectionName(workflow.config?.collection);
+  const itemConfig = useSchemaInitializerItem();
+  const { insert } = useSchemaInitializer();
+  const { getTemplateSchemaByMode } = useSchemaTemplateManager();
+  const items = useRecordCollectionDataSourceItems('FormItem');
+  const handleClick = async ({ item }) => {
+    const template = item.template ? await getTemplateSchemaByMode(item) : null;
+    const schema = createReadPrettyFormBlockSchema({
+      actionInitializers: null,
+      resource: collection,
+      collection,
+      dataSource: dataSourceName,
+      template,
+      settings: 'blockSettings:details',
+    });
+
+    const shcemaWithPatch = {};
+
+    // REVIEW: 删除这个属性的必要性, 需要再思考下
+    _.unset(schema, ['x-acl-action', 'x-acl-action-props']);
+
+    const [childSchemaKey] = Object.keys(schema.properties);
+
+    _.set(schema.properties[childSchemaKey], 'x-component-props.useProps', 'usePropsNoticeDetail');
+
+    insert(schema);
+  };
+  return ;
+};
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/show-interface/NoticeDetail.initializer.tsx b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/show-interface/NoticeDetail.initializer.tsx
new file mode 100644
index 000000000..972c9ca92
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/show-interface/NoticeDetail.initializer.tsx
@@ -0,0 +1,78 @@
+import { SchemaInitializer, gridRowColWrap, usePlugin } from '@tachybase/client';
+import PluginWorkflow, {
+  useAvailableUpstreams,
+  useFlowContext,
+  useNodeContext,
+  useTrigger,
+} from '@tachybase/plugin-workflow/client';
+import { tval } from '../../locale';
+import { NoticeDetailAddBlock } from './NoticeDetail.block';
+// import { ApproverAddBlockComponent } from './VC.ApproverAddBlock';
+// import { ApproverAddBlockKit } from './VC.ApproverAddBlockKit';
+
+export const NoticeDetailInitializer = new SchemaInitializer({
+  name: 'NoticeDetailInitializer',
+  wrap: gridRowColWrap,
+  title: "{{t('Add block')}}",
+  items: [
+    {
+      name: 'notice',
+      type: 'itemGroup',
+      title: tval('Notice blocks'),
+      children: [
+        {
+          name: 'detail',
+          type: 'item',
+          title: '{{t("Details")}}',
+          Component: NoticeDetailAddBlock,
+        },
+      ],
+    },
+    {
+      type: 'itemGroup',
+      name: 'dataBlocks',
+      title: '{{t("Data blocks")}}',
+      checkChildrenLength: true,
+      useChildren() {
+        const workflowPlugin = usePlugin(PluginWorkflow);
+        const { workflow } = useFlowContext();
+        const trigger = useTrigger();
+        const currentNodeContext = useNodeContext();
+        const nodes = useAvailableUpstreams(currentNodeContext);
+        const triggerInitializers = [trigger.useInitializers?.call(trigger, workflow.config)].filter(Boolean);
+        const nodeBlockInitializers = nodes
+          .map((node) => {
+            const instruction = workflowPlugin.instructions.get(node.type);
+            return instruction?.useInitializers?.call(instruction, node);
+          })
+          .filter(Boolean);
+        return [
+          ...triggerInitializers,
+          ...(nodeBlockInitializers.length
+            ? [
+                {
+                  name: 'nodes',
+                  type: 'subMenu',
+                  title: '{{t("Node result", { ns: "workflow" })}}',
+                  children: nodeBlockInitializers,
+                },
+              ]
+            : []),
+        ].filter(Boolean);
+      },
+    },
+    {
+      name: 'others',
+      type: 'itemGroup',
+      title: '{{t("Other blocks")}}',
+      children: [
+        {
+          name: 'markdown',
+          type: 'item',
+          title: '{{t("Markdown")}}',
+          component: 'MarkdownBlockInitializer',
+        },
+      ],
+    },
+  ],
+});
diff --git a/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/show-interface/NoticeDetail.schema.tsx b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/show-interface/NoticeDetail.schema.tsx
new file mode 100644
index 000000000..d1aa38645
--- /dev/null
+++ b/packages/plugins/@tachybase/plugin-workflow-notice/src/client/configuration/show-interface/NoticeDetail.schema.tsx
@@ -0,0 +1,86 @@
+import React from 'react';
+import { Plugin, SchemaComponent, useAPIClient, useRequest } from '@tachybase/client';
+import { useForm } from '@tachybase/schema';
+import { uid } from '@tachybase/utils/client';
+
+import { Spin } from 'antd';
+
+import { NoticeDetailInitializer } from './NoticeDetail.initializer';
+
+export class SCNoticeDetail extends Plugin {
+  async load() {
+    this.app.schemaInitializerManager.add(NoticeDetailInitializer);
+  }
+}
+
+function createNewSchema(id) {
+  return {
+    type: 'void',
+    name: id,
+    'x-uid': id,
+    'x-component': 'Grid',
+    'x-initializer': 'NoticeDetailInitializer',
+  };
+}
+
+export const NoticeDetail = (props) => {
+  const { schemaData, loading, handleChange } = useAction(props);
+  if (loading) {
+    return ;
+  }
+  return (
+     {
+          //   return { run() {} };
+          // },
+          // useApprovalFormBlockProps,
+          // useDetailsBlockProps: useFormBlockContext,
+        }
+      }
+      components={{}}
+      schema={schemaData as any}
+      onChange={handleChange}
+    />
+  );
+};
+
+function useAction(props) {
+  const { value: srcID, onChange } = props;
+  const apiClient = useAPIClient();
+  const { values, setValuesIn } = useForm();
+  const { data: schemaData, loading } = useRequest(async () => {
+    if (srcID) {
+      const remoteSchema = await fetchSchema(apiClient, srcID);
+      if (remoteSchema['x-uid'] === srcID) {
+        return remoteSchema;
+      }
+    }
+    const id = srcID ?? uid();
+    const newSchema = createNewSchema(id);
+    await instertSchema(apiClient, newSchema);
+    onChange(id);
+    return newSchema;
+  });
+
+  const handleChange = (data) => {};
+
+  return {
+    schemaData,
+    loading,
+    handleChange,
+  };
+}
+
+async function fetchSchema(apiClient, srcID): Promise