移除用户系统级角色,权限完全迁移至项目级管理

- 用户注册/创建不再需要选择角色,账号管理只管资料和状态
- 移除前后端所有系统级 role 字段的暴露,改用 is_admin 标识管理员
- PM(项目负责人)角色自动拥有全部项目权限且不可修改
- 系统管理员在项目中的成员身份不可被删除
- 管理界面全面美化

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Cheng Zhou
2026-05-20 15:52:17 +08:00
parent 6cefa620e4
commit 5b97ea32ab
35 changed files with 1937 additions and 481 deletions
-2
View File
@@ -89,8 +89,6 @@ async def register(
payload: UserRegisterRequest,
db: AsyncSession = Depends(get_db_session),
):
if payload.role == UserRole.ADMIN.value:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="不允许注册管理员账号")
existing = await user_crud.get_by_email(db, payload.email)
if existing:
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="邮箱已注册")
+3
View File
@@ -274,6 +274,9 @@ async def remove_member(
member = await member_crud.get_member_by_id(db, member_id)
if not member or member.study_id != study_id:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="成员不存在")
target_user = await user_crud.get_by_id(db, member.user_id)
if target_user and _role_value(target_user) == "ADMIN":
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="系统管理员不可从项目中移除")
await _ensure_member_mutation_allowed(db, study_id, current_user, target_member=member)
before_data = {"role_in_study": member.role_in_study, "is_active": member.is_active}
removed = await member_crud.remove_member(db, member)
+1 -5
View File
@@ -54,21 +54,17 @@ async def update_user(
if user_crud.is_protected_admin_user(db_user):
if user_in.email is not None and user_in.email != db_user.email:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="系统管理员邮箱不允许修改")
if user_in.role is not None and user_in.role != "ADMIN":
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="系统管理员角色不允许修改")
requested_status = user_in.status
if user_in.is_active is not None:
requested_status = "ACTIVE" if user_in.is_active else "DISABLED"
if requested_status is not None and requested_status != "ACTIVE":
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="系统管理员不允许停用")
if db_user.role.value == "ADMIN":
requested_role = user_in.role
requested_status = user_in.status
if user_in.is_active is not None:
requested_status = "ACTIVE" if user_in.is_active else "DISABLED"
will_leave_admin = requested_role is not None and requested_role != "ADMIN"
will_disable = requested_status is not None and requested_status != "ACTIVE"
if (will_leave_admin or will_disable) and db_user.status.value == "ACTIVE":
if will_disable and db_user.status.value == "ACTIVE":
active_admins = await user_crud.count_active_admins(db)
if active_admins <= 1:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="至少保留一个管理员账号")