import { useEffect, useState, type ReactNode } from 'react'; import { ArrowLeft, Eye, Search, ShieldCheck, X } from 'lucide-react'; import { fetchPreviewControl } from './api-client'; import { useAuth, type AuthUser } from './useAuth'; import './PermissionPreview.css'; const scopes = [ { level: 'full', title: '全量数据', role: 'BI-Leader', detail: '查看全量业务数据。' }, { level: 'department', title: '部门数据', role: 'BI-Leader-Dep', detail: '查看当前用户所在部门的数据。' }, { level: 'personal', title: '本人数据', role: '其他角色默认', detail: '查看本人负责的车辆。' }, ]; export function permissionScope(user: AuthUser) { return scopes.find(s => s.level === user.permissionLevel)?.title || '本人数据'; } export default function PermissionPreview({ children }: { children: ReactNode }) { const { isAuthenticated, actor, preview, previewNotice, clearPreviewNotice, stopPreview } = useAuth(); return
{isAuthenticated && preview && } {previewNotice &&
{previewNotice}
} {children}
; } export function PermissionPreviewPage() { const { canPreview } = useAuth(); return
{canPreview ? window.location.assign('/asset#assets')} /> :

无权限访问

当前账号未获授权使用权限视角。

返回 BI
}
; } function PreviewPicker({ onClose }: { onClose: () => void }) { const { startPreview, preview } = useAuth(); const [query, setQuery] = useState(''); const [level, setLevel] = useState(''); const [page, setPage] = useState(1); const [users, setUsers] = useState([]); const [hasMore, setHasMore] = useState(false); const [selected, setSelected] = useState(null); const [loading, setLoading] = useState(false); const [busy, setBusy] = useState(false); const [error, setError] = useState(''); const [retry, setRetry] = useState(0); const hasQuery = query.trim().length > 0; useEffect(() => { const controller = new AbortController(); setError(''); setUsers([]); setSelected(null); setHasMore(false); if (!query.trim()) { setLoading(false); return; } setLoading(true); const timer = window.setTimeout(async () => { try { const params = new URLSearchParams({ q: query.trim(), page: String(page) }); if (level) params.set('level', level); const result = await fetchPreviewControl<{ users: AuthUser[]; page: number; hasMore: boolean }>(`users?${params}`, { signal: controller.signal }); if (!controller.signal.aborted) { setUsers(result.users); setHasMore(result.hasMore); } } catch (e) { if (!controller.signal.aborted) setError(e instanceof Error ? e.message : '加载失败'); } finally { if (!controller.signal.aborted) setLoading(false); } }, 250); return () => { clearTimeout(timer); controller.abort(); }; }, [query, level, page, retry]); async function enter() { if (!selected || busy) return; setBusy(true); setError(''); try { await startPreview?.(selected.userId); onClose(); } catch (e) { setError(e instanceof Error ? e.message : '切换失败,请重试'); setBusy(false); } } return

权限视角

选择人员,查看其实际页面权限与数据范围。

{scopes.map(scope =>
{scope.title}{scope.role}

{scope.detail}

)}

菜单和数据随目标用户权限变化;共享汇总仍按页面注明的公共口径展示。预览期间仅可查看,不能修改业务数据。

{error &&
{error}
} {!hasQuery ?

输入中文姓名、用户名或部门关键词,模糊搜索人员。

:
{loading ?

正在加载人员…

: !users.length ?

未找到匹配人员,请调整搜索条件。

: users.map(user => )}
} {hasQuery && (hasMore || page > 1) &&
第 {page} 页
}
; }