import { useCallback, useEffect, useState } from 'react'; import { clearUserPolicyOverrides, getRolePolicies, getUserPolicies, listPolicyCatalog, updateRolePolicies, updateUserPolicies, } from '../api/client'; import type { AdminUserRow, PolicyDefinition, PolicyMap } from '../types'; const RISK_LABEL: Record = { low: '低', medium: '中', high: '高', }; function PolicyGrid({ catalog, values, disabled, onChange, }: { catalog: PolicyDefinition[]; values: PolicyMap; disabled?: boolean; onChange: (key: string, value: PolicyMap[string]) => void; }) { const grouped = catalog.reduce>((acc, item) => { acc[item.category] ??= []; acc[item.category].push(item); return acc; }, {}); return (
{Object.entries(grouped).map(([category, items]) => (

{category}

    {items.map((item) => (
  • ))}
))}
); } export function PolicySettings({ users, userId, userOnly = false, }: { users: AdminUserRow[]; userId?: string; userOnly?: boolean; }) { const [catalog, setCatalog] = useState([]); const [rolePolicies, setRolePolicies] = useState({}); const [selectedUserId, setSelectedUserId] = useState(userId ?? ''); const [userPolicies, setUserPolicies] = useState({}); const [userOverrides, setUserOverrides] = useState({}); const [userUnrestricted, setUserUnrestricted] = useState(false); const [loading, setLoading] = useState(true); const [message, setMessage] = useState(null); const [error, setError] = useState(null); const load = useCallback(async () => { setLoading(true); setError(null); try { const [catalogItems, roleState] = await Promise.all([ listPolicyCatalog(), getRolePolicies('user'), ]); setCatalog(catalogItems); setRolePolicies(roleState.policies); } catch (err) { setError(err instanceof Error ? err.message : '加载安全策略失败'); } finally { setLoading(false); } }, []); const loadUserPolicies = useCallback(async (userId: string) => { if (!userId) { setUserPolicies({}); setUserOverrides({}); setUserUnrestricted(false); return; } try { const state = await getUserPolicies(userId); setUserPolicies(state.policies); setUserOverrides(state.overrides); setUserUnrestricted(state.unrestricted); } catch (err) { setError(err instanceof Error ? err.message : '加载用户策略失败'); } }, []); useEffect(() => { void load(); }, [load]); useEffect(() => { void loadUserPolicies(selectedUserId); }, [loadUserPolicies, selectedUserId]); useEffect(() => { if (userId) { setSelectedUserId(userId); } }, [userId]); const saveRoleDefaults = async () => { setMessage(null); setError(null); try { const result = await updateRolePolicies('user', rolePolicies); setRolePolicies(result.policies); setMessage('普通用户默认安全策略已保存'); } catch (err) { setError(err instanceof Error ? err.message : '保存失败'); } }; const saveUserOverrides = async () => { if (!selectedUserId) return; setMessage(null); setError(null); try { const result = await updateUserPolicies(selectedUserId, userPolicies); setUserPolicies(result.policies); await loadUserPolicies(selectedUserId); setMessage('用户单独策略已保存'); } catch (err) { setError(err instanceof Error ? err.message : '保存失败'); } }; const resetUserOverrides = async () => { if (!selectedUserId) return; setMessage(null); setError(null); try { await clearUserPolicyOverrides(selectedUserId); await loadUserPolicies(selectedUserId); setMessage('已恢复为角色默认策略'); } catch (err) { setError(err instanceof Error ? err.message : '重置失败'); } }; const regularUsers = users.filter((user) => user.role === 'user'); return (

安全策略

控制 TKMind 模式、工作区只读、网络出站与 API 代理锁定。与上方「能力权限」叠加生效(策略会进一步收紧高风险能力)。

{error &&

{error}

} {message &&

{message}

} {loading ? (

加载中…

) : ( <> {!userOnly && ( <>

普通用户默认策略

setRolePolicies((prev) => ({ ...prev, [key]: value }))} />
)} {!userOnly &&

单用户策略覆盖

} {!userOnly && (
)} {selectedUserId && ( <> {userUnrestricted ? (

该用户为管理员,不受策略限制。

) : ( <> {Object.keys(userOverrides).length > 0 && (

已设置 {Object.keys(userOverrides).length} 项单独覆盖。

)} setUserPolicies((prev) => ({ ...prev, [key]: value })) } />
)} )} )}
); }