跳转到内容

企业级组件

import { Tabs, TabItem } from ‘@astrojs/starlight/components’;

svadmin 提供了一套完整的企业级组件,专为真实的后台管理系统设计。所有组件遵循 Headless + Wrapper 双层架构:

  • Layer A(无头层):纯 UI 组件,通过 Props + Callbacks 驱动 — 不耦合任何后端
  • Layer B(封装层):可选的 AuthProvider 集成,实现开箱即用

完全解耦的 RBAC 权限矩阵,用于管理 (角色 × 资源 × 操作) 的三维关联。

属性类型说明
rolesRoleInfo[]角色列表({ code, name })
resourcesResourceInfo[]资源列表,支持 section 分组
actionsActionInfo[]操作定义(增删改查等)
isGranted(role, resource, action) => boolean外部注入的判权函数
selectedRole$bindable<string>当前选中角色(双向绑定)
onToggle(role, resource, action, grant) => void权限变更回调
sidebarExtraSnippet左侧边栏扩展插槽(如租户/密级选择器)
headerExtraSnippet顶部工具栏扩展插槽
loadingboolean加载状态,禁用所有交互
<script>
import { PermissionMatrix } from '@svadmin/ui';
let policies = $state([]);
function checkGrant(role, resource, action) {
return policies.some(p => p.role === role && p.res === resource && p.act === action);
}
async function handleToggle(role, res, act, grant) {
await fetch('/api/permissions', {
method: 'POST',
body: JSON.stringify({ role, res, act, grant })
});
}
</script>
<PermissionMatrix
roles={[{ code: 'admin', name: '系统管理员' }, { code: 'editor', name: '编辑' }]}
resources={[{ code: 'posts', name: '文章', section: '内容管理' }]}
actions={[{ code: 'read', name: '读取' }, { code: 'write', name: '写入' }]}
isGranted={checkGrant}
onToggle={handleToggle}
>
{#snippet sidebarExtra()}
<p>租户:某某科技有限公司</p>
{/snippet}
</PermissionMatrix>

<RolesSettings /> 组件内置了 AuthProvider 封装。当你使用 <SettingsPage /> 时,它会自动出现在 /settings/roles 路由。

只需在 AuthProvider 上实现以下可选方法:

const authProvider: AuthProvider = {
// ... login, logout, check, getIdentity ...
getRoles: async () => [{ id: '1', name: 'Admin' }],
getRolePermissions: async (roleId) => ({ posts: ['create', 'read'] }),
updateRolePermissions: async (roleId, permissions) => ({ success: true }),
};

合规级审计日志查看器,内置搜索过滤、操作徽章以及 JSON 变更快照抽屉。

const authProvider: AuthProvider = {
getAuditLogs: async ({ page, pageSize }) => ({
data: [
{ id: '1', userName: 'admin', action: 'update', resource: 'users',
createdAt: new Date(), ipAddress: '192.168.1.1',
details: { before: { name: '旧值' }, after: { name: '新值' } } }
],
total: 100,
}),
};

在 <SettingsPage /> 中自动注册于 /settings/audit 路由。


无刷新多租户工作区切换器,适合放置在 Sidebar 顶部。

<script>
import { TenantSwitcher } from '@svadmin/ui';
const tenants = [
{ id: '1', name: '某某科技', logo: '/logo.png' },
{ id: '2', name: '另一公司' },
];
let currentTenantId = $state('1');
function handleSwitch(id: string) {
location.href = `?tenant=${id}`;
}
</script>
<TenantSwitcher {tenants} bind:currentTenantId onSwitch={handleSwitch} />

显示实时进度条、状态指示器和下载/重试按钮的后台任务抽屉。

<script>
import { TaskQueueDrawer } from '@svadmin/ui';
import { createClient } from '@supabase/supabase-js';
import { createSupaCloudClient } from '@supacloud/js';
import { createSupaCloudTaskProvider } from '@svadmin/supabase/supacloud';
const supabase = createClient(import.meta.env.VITE_SUPABASE_URL, import.meta.env.VITE_SUPABASE_ANON_KEY);
const supacloud = createSupaCloudClient({
supabase,
managementApiUrl: import.meta.env.VITE_SUPACLOUD_API_URL,
projectRef: import.meta.env.VITE_SUPACLOUD_PROJECT_REF,
});
const taskProvider = createSupaCloudTaskProvider({ supacloud });
</script>
<TaskQueueDrawer
{taskProvider}
/>

TaskQueueDrawer 现在直接以 TaskProvider 作为一等输入,内置任务 / 死信 Tab、筛选、自动刷新、内联任务提交表单,以及与详情面板联动的正式任务中心体验。


零依赖的拖拽式仪表盘网格,使用原生 HTML5 Drag & Drop API。

<script>
import { DraggableGrid } from '@svadmin/ui';
let modules = $state([
{ id: 'revenue', title: '营收' },
{ id: 'users', title: '活跃用户' },
]);
</script>
<DraggableGrid bind:modules onOrderSave={(ids) => localStorage.setItem('order', JSON.stringify(ids))}>
{#snippet renderItem({ module })}
<div class="p-4 border rounded-lg bg-card">
<h3>{module.title}</h3>
</div>
{/snippet}
</DraggableGrid>

声明式权限守卫组件,仅在用户有权限时渲染子元素。

<CanAccess resource="posts" action="delete">
<button>删除文章</button>
{#snippet fallback()}
<button disabled>无权限</button>
{/snippet}
</CanAccess>

Can 是 CanAccess 的简写别名。


用于一对多关系的动态嵌套表单字段(如订单明细、联系人列表)。

const fields: FieldDefinition[] = [
{
key: 'items',
label: '订单明细',
type: 'array',
subFields: [
{ key: 'name', label: '商品名称', type: 'text', required: true },
{ key: 'quantity', label: '数量', type: 'number', required: true },
{ key: 'price', label: '单价', type: 'number' },
],
},
];

在 FieldDefinition 中指定 type: 'array' 时,AutoForm 会自动渲染 ArrayField。