演示

设置

如何用 AppRegistry.setting.add 向全局设置页贡献 UI,并用 base-frontend hooks 读写设置。

概述

Shell 拥有设置中心。插件在 register() 中通过 AppRegistry.setting.add 注入面板,并用 base-frontend hooks 加载与持久化键值。

  • AppRegistry.setting.add({ pluginName, element })
  • useSettingQuery({ mode: 'private' | 'public' })
  • useUpdateSettingQuery()
  • 优先复用已有 SettingKeys

1. 注册设置 UI

在 register() 中调用 AppRegistry.setting.add。

  • 形状:{ pluginName, element }
  • pluginName = metadata.name
  • 在面板内完成加载/保存
TSXfrontend/src/index.tsx
1import type { AppRegistryState, PluginModule } from "@quan-erp/shared-types"; 2import metadata from "../module.metadata.json" with { type: "json" }; 3import { MyPluginSettings } from "./page/setting/my-plugin-settings"; 4 5const Plugin: PluginModule = { 6 register(AppRegistry: AppRegistryState) { 7 AppRegistry.setting.add({ 8 pluginName: metadata.name, 9 element: <MyPluginSettings />, 10 }); 11 }, 12}; 13 14export default Plugin;

2. 构建设置面板

放在 frontend/src/page/setting/。使用 base-frontend hooks 与 shared-ui。

TSXfrontend/src/page/setting/my-plugin-settings.tsx
1import { useSettingContext, useSettingQuery } from "@quan-erp/base-frontend"; 2 3export function MyPluginSettings() { 4 const { data: settings, isLoading } = useSettingQuery({ mode: "private" }); 5 const { onUpdateSetting, editedSetting } = useSettingContext(); 6 7 if (isLoading) return null; 8 9 return ( 10 <div className="flex flex-col gap-4 p-4"> 11 <h3>My plugin</h3> 12 {/* Bind controls to settings / editedSetting; 13 call onUpdateSetting(key, value, datatype) on change */} 14 </div> 15 ); 16}

3. 设置 hooks

Import hooks from @quan-erp/base-frontend.

  • useSettingQuery — 加载设置映射
  • useUpdateSettingQuery — 持久化
  • useSettingStore — 客户端缓存(useSettingStore()())
  • useSettingContext — onUpdateSetting / editedSetting
TSXread + update
1import { 2 useSettingQuery, 3 useUpdateSettingQuery, 4} from "@quan-erp/base-frontend"; 5 6const { data = {} } = useSettingQuery({ mode: "private" }); 7const updateSetting = useUpdateSettingQuery(); 8 9// Prefer useSettingContext().onUpdateSetting inside the Settings hub. 10// For standalone flows: 11await updateSetting.mutateAsync({ /* SettingMapValue */ });

4. 设置 key

优先使用 LOCALE、THEME、DATE_FORMAT、TIMEZONE、BUSINESS_NAME、PRIMARY_COLOR 等。插件私有配置使用清晰命名空间。

  • Private vs public mode — pick the mode that matches who should read the value
  • Do not invent duplicates of LOCALE / THEME / TIMEZONE
  • Align datatype with what onUpdateSetting / backend SettingService expect

关键规则

  • 只在 register() 中 setting.add
  • pluginName 必须等于 metadata.name
  • element 必须是 ReactElement(JSX)
  • 使用 base-frontend 设置 hooks

检查清单

  • Create page/setting panel component
  • AppRegistry.setting.add({ pluginName, element }) in register()
  • Wire useSettingQuery / useSettingContext (or useUpdateSettingQuery)
  • Reuse platform keys when applicable
  • Verify panel appears on Settings after quan-erp watch and install

常见失败

  • 面板不出现 — 未注册 / pluginName 错误
  • 类型错误 — 传了组件函数而非 JSX
  • 加载失败 — mode 错误或在 provider 外
  • 保存失败 — 未调用 onUpdateSetting / datatype 不匹配