feat(平台端): 完整用户管理 — 新增 修改(PUT /admin/users/{id}) + 删除(DELETE /admin/users/{id})
UserRepository.delete(硬删);UpdateUserRequest(昵称/角色/子角色/组织/区域);update_user 调 update_profile+set_role, delete_user 调 delete;走 action:user.manage + write_audit。TestClient:create/update/delete 均 200。
This commit is contained in:
@@ -7,7 +7,7 @@ from pydantic import BaseModel
|
||||
|
||||
from ..dependencies import get_db
|
||||
from ..schemas.admin import SetUserRoleRequest, SetUserStatusRequest
|
||||
from ..schemas.admin import UserCreateRequest, RolePermissionRequest
|
||||
from ..schemas.admin import UserCreateRequest, RolePermissionRequest, UpdateUserRequest
|
||||
from ...rbac import require_permission, require_roles, write_audit
|
||||
from ...infrastructure.repositories import Database
|
||||
|
||||
@@ -89,6 +89,43 @@ async def set_user_status(
|
||||
return {"ok": True, "user": await db.users.to_profile(updated)}
|
||||
|
||||
|
||||
@router.put("/users/{user_id}", summary="修改用户(资料/角色)")
|
||||
async def update_user(
|
||||
user_id: str,
|
||||
req: UpdateUserRequest,
|
||||
request: Request,
|
||||
db: Database = Depends(get_db),
|
||||
actor: dict = Depends(require_permission("action:user.manage")),
|
||||
):
|
||||
user = await db.users.get_by_id(user_id)
|
||||
if user is None:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
profile_fields = {k: v for k, v in req.model_dump(exclude_none=True).items() if k in ("nickname",)}
|
||||
if profile_fields:
|
||||
user = await db.users.update_profile(user_id, profile_fields) or user
|
||||
if req.role or req.sub_role is not None:
|
||||
user = await db.users.set_role(user_id, req.role or user.get("role"), req.sub_role,
|
||||
req.org_id or user.get("org_id"), req.region_id or user.get("region_id"))
|
||||
await write_audit(db, action="user.update", resource="user", resource_id=user_id,
|
||||
detail=str(req.model_dump(exclude_none=True)), user=actor, request=request)
|
||||
return {"ok": True, "user": await db.users.to_profile(user)}
|
||||
|
||||
|
||||
@router.delete("/users/{user_id}", summary="删除用户")
|
||||
async def delete_user(
|
||||
user_id: str,
|
||||
request: Request,
|
||||
db: Database = Depends(get_db),
|
||||
actor: dict = Depends(require_permission("action:user.manage")),
|
||||
):
|
||||
ok = await db.users.delete(user_id)
|
||||
if not ok:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
await write_audit(db, action="user.delete", resource="user", resource_id=user_id,
|
||||
detail="deleted", user=actor, request=request)
|
||||
return {"ok": True, "user_id": user_id}
|
||||
|
||||
|
||||
@router.get("/roles", summary="角色列表")
|
||||
async def list_roles(
|
||||
db: Database = Depends(get_db),
|
||||
|
||||
@@ -9,6 +9,13 @@ class SetUserRoleRequest(BaseModel):
|
||||
class SetUserStatusRequest(BaseModel):
|
||||
status: str = "active" # active | disabled
|
||||
|
||||
class UpdateUserRequest(BaseModel):
|
||||
nickname: str | None = None
|
||||
role: str | None = None
|
||||
sub_role: str | None = None
|
||||
org_id: str | None = None
|
||||
region_id: str | None = None
|
||||
|
||||
class UserCreateRequest(BaseModel):
|
||||
username: str # 手机号
|
||||
password: str
|
||||
|
||||
@@ -181,6 +181,15 @@ class UserRepository:
|
||||
async def list(self) -> list[dict]:
|
||||
return [_user_to_dict(u) for u in await self.session.scalars(select(User).order_by(User.created_at))]
|
||||
|
||||
async def delete(self, user_id: str) -> bool:
|
||||
"""硬删除用户(含其身份/会话在级联范围内由 DB 层处理)。"""
|
||||
u = await self.session.get(User, user_id)
|
||||
if u is None:
|
||||
return False
|
||||
await self.session.delete(u)
|
||||
await self.session.commit()
|
||||
return True
|
||||
|
||||
async def create(
|
||||
self,
|
||||
username: str,
|
||||
|
||||
Reference in New Issue
Block a user