feat(frontend): enforce RBAC and refine burst analysis
This commit is contained in:
@@ -106,24 +106,30 @@ type DatabaseHealth = {
|
||||
|
||||
const businessRoleOptions = [
|
||||
{ value: "admin", label: "系统管理员" },
|
||||
{ value: "operator", label: "运行人员" },
|
||||
{ value: "user", label: "普通用户" },
|
||||
{ value: "viewer", label: "只读用户" },
|
||||
];
|
||||
|
||||
const projectRoleLabels: Record<string, string> = {
|
||||
owner: "项目负责人",
|
||||
admin: "项目管理员",
|
||||
member: "项目成员",
|
||||
viewer: "只读成员",
|
||||
};
|
||||
|
||||
const projectRoleOptions = [
|
||||
{ value: "admin", label: projectRoleLabels.admin },
|
||||
{ value: "member", label: projectRoleLabels.member },
|
||||
{ value: "viewer", label: projectRoleLabels.viewer },
|
||||
];
|
||||
|
||||
const projectRolePermissionSummary = [
|
||||
{
|
||||
role: "项目成员",
|
||||
permissions: "WebGIS 编辑、SCADA 清洗、水力模拟、爆管、风险和监测点优化分析",
|
||||
},
|
||||
{
|
||||
role: "只读成员",
|
||||
permissions: "默认工作台、WebGIS、SCADA 和既有模拟结果只读",
|
||||
},
|
||||
];
|
||||
|
||||
const projectStatusOptions = [
|
||||
{ value: "active", label: "启用" },
|
||||
{ value: "inactive", label: "停用" },
|
||||
@@ -1340,7 +1346,7 @@ export const SystemAdminPanel = () => {
|
||||
<Stack spacing={2}>
|
||||
<SectionHeader
|
||||
title="项目成员"
|
||||
description="维护当前项目内权限;此处只管理项目管理员、项目成员和只读成员,项目负责人另行维护。"
|
||||
description="项目访问角色保存在 Metadata DB 的 user_project_membership.project_role。模型上传由桌面端发起,仅系统管理员可执行。"
|
||||
action={
|
||||
<Button
|
||||
variant="outlined"
|
||||
@@ -1352,6 +1358,25 @@ export const SystemAdminPanel = () => {
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<Paper variant="outlined" sx={{ p: 2, borderRadius: 2 }}>
|
||||
<Typography variant="subtitle2" fontWeight={800} sx={{ mb: 1 }}>
|
||||
固定项目权限
|
||||
</Typography>
|
||||
<Stack
|
||||
direction={{ xs: "column", md: "row" }}
|
||||
spacing={1}
|
||||
useFlexGap
|
||||
flexWrap="wrap"
|
||||
>
|
||||
{projectRolePermissionSummary.map((item) => (
|
||||
<Chip
|
||||
key={item.role}
|
||||
label={`${item.role}:${item.permissions}`}
|
||||
variant="outlined"
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
</Paper>
|
||||
{!hasProjectId && (
|
||||
<Alert severity="warning" sx={{ borderRadius: 2 }}>
|
||||
当前未选择管理项目。
|
||||
@@ -1467,7 +1492,6 @@ export const SystemAdminPanel = () => {
|
||||
)}
|
||||
{members.map((member) => {
|
||||
const isSelf = member.user_id === currentAdmin?.id;
|
||||
const isOwner = member.project_role === "owner";
|
||||
|
||||
return (
|
||||
<TableRow key={member.id} hover>
|
||||
@@ -1486,54 +1510,38 @@ export const SystemAdminPanel = () => {
|
||||
</TableCell>
|
||||
<TableCell>{member.email}</TableCell>
|
||||
<TableCell>
|
||||
{isOwner ? (
|
||||
<Tooltip title="项目负责人不在系统管理页维护">
|
||||
<Chip
|
||||
<Tooltip title={isSelf ? "不能操作当前登录用户" : ""}>
|
||||
<span>
|
||||
<FormControl
|
||||
size="small"
|
||||
color="warning"
|
||||
label={getProjectRoleLabel(member.project_role)}
|
||||
/>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<Tooltip title={isSelf ? "不能操作当前登录用户" : ""}>
|
||||
<span>
|
||||
<FormControl
|
||||
size="small"
|
||||
sx={{ minWidth: 140 }}
|
||||
disabled={isSelf}
|
||||
sx={{ minWidth: 140 }}
|
||||
disabled={isSelf}
|
||||
>
|
||||
<Select
|
||||
value={member.project_role}
|
||||
onChange={(e) =>
|
||||
updateMemberRole(member, e.target.value)
|
||||
}
|
||||
renderValue={(value) =>
|
||||
getProjectRoleLabel(String(value))
|
||||
}
|
||||
>
|
||||
<Select
|
||||
value={member.project_role}
|
||||
onChange={(e) =>
|
||||
updateMemberRole(member, e.target.value)
|
||||
}
|
||||
renderValue={(value) =>
|
||||
getProjectRoleLabel(String(value))
|
||||
}
|
||||
>
|
||||
{projectRoleOptions.map((role) => (
|
||||
<MenuItem key={role.value} value={role.value}>
|
||||
{role.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
{projectRoleOptions.map((role) => (
|
||||
<MenuItem key={role.value} value={role.value}>
|
||||
{role.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</span>
|
||||
</Tooltip>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<StatusChip active={member.is_active} />
|
||||
</TableCell>
|
||||
<TableCell align="right">
|
||||
<Tooltip
|
||||
title={
|
||||
isSelf
|
||||
? "不能操作当前登录用户"
|
||||
: isOwner
|
||||
? "项目负责人不在系统管理页维护"
|
||||
: ""
|
||||
}
|
||||
title={isSelf ? "不能操作当前登录用户" : ""}
|
||||
>
|
||||
<span>
|
||||
<Button
|
||||
@@ -1542,7 +1550,7 @@ export const SystemAdminPanel = () => {
|
||||
variant="outlined"
|
||||
startIcon={<RemoveCircleOutlineIcon />}
|
||||
onClick={() => removeMember(member)}
|
||||
disabled={isSelf || isOwner}
|
||||
disabled={isSelf}
|
||||
>
|
||||
移除
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user