user.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. from fastapi import APIRouter, Depends, HTTPException, status
  2. from sqlalchemy import or_
  3. from sqlalchemy.orm import Session
  4. from app.database import get_db
  5. from app.core.deps import require_roles
  6. from app.core.security import hash_password
  7. from app.models.user import User
  8. from app.schemas.common import ApiResponse, PagedData
  9. from app.schemas.user import UserCreate, UserUpdate, UserOut, UserBriefOut, UserStatsSummaryOut
  10. from app.services.user import UserService
  11. DEFAULT_PASSWORD = "123456"
  12. router = APIRouter(prefix="/api/users", tags=["用户管理"])
  13. @router.get("/", response_model=ApiResponse[PagedData[UserOut]])
  14. def list_users(
  15. page: int = 1,
  16. pageSize: int = 10,
  17. keyword: str = "",
  18. status: int | None = None,
  19. db: Session = Depends(get_db),
  20. _: User = Depends(require_roles("ADMIN")),
  21. ):
  22. filters = [User.del_flag == 0]
  23. if status is not None:
  24. filters.append(User.status == status)
  25. if keyword:
  26. filters.append(or_(User.username.contains(keyword), User.real_name.contains(keyword)))
  27. rows, total = UserService.get_paged(db, page=page, page_size=pageSize, filters=filters)
  28. out_rows = [UserOut.model_validate(r) for r in rows]
  29. paged_data = PagedData(rows=out_rows, total=total, page=page, page_size=pageSize)
  30. return ApiResponse(data=paged_data)
  31. @router.get("/dropdown", response_model=ApiResponse[list[UserBriefOut]])
  32. def list_users_dropdown(db: Session = Depends(get_db), _: User = Depends(require_roles("ADMIN"))):
  33. rows = db.query(User).filter(User.del_flag == 0, User.status == 1).order_by(User.id).all()
  34. return ApiResponse(data=[UserBriefOut.model_validate(r) for r in rows])
  35. @router.get("/stats/summary", response_model=ApiResponse[UserStatsSummaryOut])
  36. def users_stats_summary(db: Session = Depends(get_db), _: User = Depends(require_roles("ADMIN"))):
  37. data = UserService.summary_stats(db)
  38. return ApiResponse(data=UserStatsSummaryOut.model_validate(data))
  39. @router.get("/{user_id}", response_model=ApiResponse[UserOut])
  40. def get_user(user_id: int, db: Session = Depends(get_db), _: User = Depends(require_roles("ADMIN"))):
  41. user = UserService.get_by_id(db, user_id)
  42. if not user:
  43. raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="用户不存在")
  44. return ApiResponse(data=UserOut.model_validate(user))
  45. @router.post("/", response_model=ApiResponse[UserOut])
  46. def create_user(body: UserCreate, db: Session = Depends(get_db), _: User = Depends(require_roles("ADMIN"))):
  47. data = body.model_dump(exclude_unset=True)
  48. role_ids = data.pop("role_ids", None) or data.pop("roleIds", None) or []
  49. for key in list(data.keys()):
  50. if key in ("role_ids", "roleIds"):
  51. del data[key]
  52. user = UserService.create(db, data)
  53. if role_ids:
  54. from app.models.role import Role
  55. for rid in role_ids:
  56. role = db.query(Role).filter(Role.id == rid, Role.del_flag == 0).first()
  57. if role:
  58. user.roles.append(role)
  59. db.flush()
  60. return ApiResponse(data=UserOut.model_validate(user))
  61. @router.put("/{user_id}", response_model=ApiResponse[UserOut])
  62. def update_user(user_id: int, body: UserUpdate, db: Session = Depends(get_db), _: User = Depends(require_roles("ADMIN"))):
  63. data = body.model_dump(exclude_unset=True)
  64. role_ids = data.pop("role_ids", None) or data.pop("roleIds", None)
  65. for key in list(data.keys()):
  66. if key in ("role_ids", "roleIds"):
  67. del data[key]
  68. if data.get("password") == "":
  69. del data["password"]
  70. if "username" in data:
  71. name = (data.get("username") or "").strip()
  72. if not name:
  73. del data["username"]
  74. else:
  75. data["username"] = name
  76. taken = (
  77. db.query(User)
  78. .filter(User.username == name, User.del_flag == 0, User.id != user_id)
  79. .first()
  80. )
  81. if taken:
  82. raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="用户名已被占用")
  83. user = UserService.update(db, user_id, data)
  84. if not user:
  85. raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="用户不存在")
  86. if role_ids is not None:
  87. from app.models.role import Role
  88. user.roles.clear()
  89. for rid in role_ids:
  90. role = db.query(Role).filter(Role.id == rid, Role.del_flag == 0).first()
  91. if role:
  92. user.roles.append(role)
  93. db.flush()
  94. return ApiResponse(data=UserOut.model_validate(user))
  95. @router.put("/{user_id}/reset-password", response_model=ApiResponse[None])
  96. def reset_password(user_id: int, db: Session = Depends(get_db), _: User = Depends(require_roles("ADMIN"))):
  97. user = UserService.get_by_id(db, user_id)
  98. if not user:
  99. raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="用户不存在")
  100. user.password = hash_password(DEFAULT_PASSWORD)
  101. db.commit()
  102. return ApiResponse(data=None)
  103. @router.delete("/{user_id}", response_model=ApiResponse[None])
  104. def delete_user(user_id: int, db: Session = Depends(get_db), _: User = Depends(require_roles("ADMIN"))):
  105. UserService.soft_delete(db, user_id)
  106. return ApiResponse(data=None)