- CRM WASM 插件:Cargo.toml + src/lib.rs + plugin.toml(5 实体 + 9 权限 + 6 页面) - 注册 erp-plugin-crm 到 workspace members - PluginTabsPage: 通用标签页容器,递归渲染子页面 - PluginTreePage: 通用树形页面,前端构建树结构 - App.tsx: 新增 /tabs/:pageLabel 和 /tree/:entityName 路由 - plugin store: 从 manifest pages 生成菜单(支持 tabs 聚合) - MainLayout: 动态图标映射(team/user/message/tags/apartment)
62 lines
1.7 KiB
TypeScript
62 lines
1.7 KiB
TypeScript
import { useState } from 'react';
|
|
import { Tabs } from 'antd';
|
|
import {
|
|
PluginPageSchema,
|
|
PluginEntitySchema,
|
|
PluginFieldSchema,
|
|
} from '../api/plugins';
|
|
|
|
interface PluginTabsPageProps {
|
|
pluginId: string;
|
|
label: string;
|
|
icon?: string;
|
|
tabs: PluginPageSchema[];
|
|
entities: PluginEntitySchema[];
|
|
}
|
|
|
|
export function PluginTabsPage({ pluginId, label, tabs, entities }: PluginTabsPageProps) {
|
|
const [activeKey, setActiveKey] = useState(tabs[0] && 'label' in tabs[0] ? tabs[0].label : '');
|
|
|
|
const renderTabContent = (tab: PluginPageSchema) => {
|
|
if (tab.type === 'crud') {
|
|
// 懒加载 PluginCRUDPage 避免循环依赖
|
|
const PluginCRUDPage = require('./PluginCRUDPage').default;
|
|
return (
|
|
<PluginCRUDPage
|
|
pluginIdOverride={pluginId}
|
|
entityOverride={tab.entity}
|
|
enableSearch={tab.enable_search}
|
|
enableViews={tab.enable_views}
|
|
/>
|
|
);
|
|
}
|
|
if (tab.type === 'tree') {
|
|
const PluginTreePage = require('./PluginTreePage').PluginTreePage;
|
|
const entity = entities.find((e) => e.name === tab.entity);
|
|
return (
|
|
<PluginTreePage
|
|
pluginId={pluginId}
|
|
entity={tab.entity}
|
|
idField={tab.id_field}
|
|
parentField={tab.parent_field}
|
|
labelField={tab.label_field}
|
|
fields={entity?.fields || []}
|
|
/>
|
|
);
|
|
}
|
|
return <div>不支持的页面类型: {tab.type}</div>;
|
|
};
|
|
|
|
const items = tabs.map((tab) => ({
|
|
key: 'label' in tab ? tab.label : '',
|
|
label: 'label' in tab ? tab.label : '',
|
|
children: renderTabContent(tab),
|
|
}));
|
|
|
|
return (
|
|
<div style={{ padding: 24 }}>
|
|
<Tabs activeKey={activeKey} onChange={setActiveKey} items={items} />
|
|
</div>
|
|
);
|
|
}
|