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} 页
}
;
}