admins.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. """
  2. 管理员管理接口
  3. """
  4. from fastapi import APIRouter, Depends, Query, Request
  5. from sqlalchemy.orm import Session
  6. from pydantic import BaseModel
  7. from app.database import get_db
  8. from app.api.deps import get_current_admin
  9. from app.models.admin import Admin
  10. from app.core.security import get_password_hash, verify_password
  11. from datetime import datetime
  12. from app.utils.timezone import beijing_now
  13. router = APIRouter()
  14. class AdminCreate(BaseModel):
  15. """创建管理员请求"""
  16. username: str
  17. password: str
  18. real_name: str = None
  19. email: str = None
  20. role: str = "admin"
  21. class AdminUpdate(BaseModel):
  22. """更新管理员请求"""
  23. real_name: str = None
  24. email: str = None
  25. role: str = None
  26. class AdminPasswordReset(BaseModel):
  27. """重置密码请求"""
  28. new_password: str
  29. @router.get("")
  30. async def get_admins(
  31. page: int = Query(1, ge=1),
  32. page_size: int = Query(10, ge=1, le=100),
  33. keyword: str = Query(None, description="搜索关键词(用户名、邮箱)"),
  34. role: str = Query(None, description="角色筛选"),
  35. status: int = Query(None, description="状态筛选:1-正常,0-禁用"),
  36. db: Session = Depends(get_db),
  37. current_admin = Depends(get_current_admin)
  38. ):
  39. """获取管理员列表"""
  40. offset = (page - 1) * page_size
  41. query = db.query(Admin).filter(Admin.is_deleted == 0)
  42. # 搜索
  43. if keyword:
  44. query = query.filter(
  45. (Admin.username.like(f"%{keyword}%")) |
  46. (Admin.email.like(f"%{keyword}%"))
  47. )
  48. # 筛选
  49. if role:
  50. query = query.filter(Admin.role == role)
  51. if status is not None:
  52. query = query.filter(Admin.status == status)
  53. # 排序
  54. query = query.order_by(Admin.created_at.desc())
  55. admins = query.offset(offset).limit(page_size).all()
  56. total = query.count()
  57. return {
  58. "code": 200,
  59. "msg": "成功",
  60. "data": [
  61. {
  62. "id": a.id,
  63. "username": a.username,
  64. "real_name": a.real_name,
  65. "email": a.email,
  66. "role": a.role,
  67. "status": a.status,
  68. "last_login_time": a.last_login_time.isoformat() if a.last_login_time else None,
  69. "last_login_ip": a.last_login_ip,
  70. "created_at": a.created_at.isoformat() if a.created_at else None,
  71. "updated_at": a.updated_at.isoformat() if a.updated_at else None
  72. }
  73. for a in admins
  74. ],
  75. "total": total,
  76. "page": page,
  77. "page_size": page_size
  78. }
  79. @router.post("")
  80. async def create_admin(
  81. req: AdminCreate,
  82. request: Request,
  83. db: Session = Depends(get_db),
  84. current_admin = Depends(get_current_admin)
  85. ):
  86. """创建管理员"""
  87. # 检查用户名是否存在
  88. existing = db.query(Admin).filter(Admin.username == req.username).first()
  89. if existing:
  90. return {"code": 400, "msg": "用户名已存在"}
  91. # 创建管理员
  92. admin = Admin(
  93. username=req.username,
  94. password=get_password_hash(req.password),
  95. real_name=req.real_name,
  96. email=req.email,
  97. role=req.role,
  98. status=1,
  99. created_at=beijing_now(),
  100. updated_at=beijing_now()
  101. )
  102. db.add(admin)
  103. # 刷新以获取ID
  104. db.flush()
  105. # 创建历史记录
  106. from app.utils.history import create_admin_history, create_operation_log
  107. create_admin_history(db, admin, "INSERT")
  108. # 记录操作日志
  109. client_ip = request.client.host if request.client else None
  110. create_operation_log(
  111. db=db,
  112. admin_id=current_admin.id,
  113. module="管理员管理",
  114. action="创建管理员",
  115. description=f"创建管理员账号:{req.username}",
  116. new_data={
  117. "username": req.username,
  118. "real_name": req.real_name,
  119. "email": req.email,
  120. "role": req.role
  121. },
  122. ip_address=client_ip
  123. )
  124. # 一次性提交所有更改
  125. db.commit()
  126. return {"code": 200, "msg": "创建成功", "data": {"id": admin.id}}
  127. @router.get("/{admin_id}")
  128. async def get_admin(
  129. admin_id: int,
  130. db: Session = Depends(get_db),
  131. current_admin = Depends(get_current_admin)
  132. ):
  133. """获取管理员详情"""
  134. admin = db.query(Admin).filter(Admin.id == admin_id).first()
  135. if not admin:
  136. return {"code": 404, "msg": "管理员不存在"}
  137. return {
  138. "code": 200,
  139. "msg": "成功",
  140. "data": {
  141. "id": admin.id,
  142. "username": admin.username,
  143. "real_name": admin.real_name,
  144. "email": admin.email,
  145. "role": admin.role,
  146. "status": admin.status,
  147. "last_login_time": admin.last_login_time.isoformat() if admin.last_login_time else None,
  148. "last_login_ip": admin.last_login_ip,
  149. "created_at": admin.created_at.isoformat() if admin.created_at else None,
  150. "updated_at": admin.updated_at.isoformat() if admin.updated_at else None
  151. }
  152. }
  153. @router.put("/{admin_id}")
  154. async def update_admin(
  155. admin_id: int,
  156. req: AdminUpdate,
  157. request: Request,
  158. db: Session = Depends(get_db),
  159. current_admin = Depends(get_current_admin)
  160. ):
  161. """更新管理员"""
  162. admin = db.query(Admin).filter(Admin.id == admin_id).first()
  163. if not admin:
  164. return {"code": 404, "msg": "管理员不存在"}
  165. # 不能修改自己的角色
  166. if current_admin.id == admin_id and req.role and req.role != admin.role:
  167. return {"code": 400, "msg": "不能修改自己的角色"}
  168. # 记录更新前的状态
  169. old_data = {
  170. "real_name": admin.real_name,
  171. "email": admin.email,
  172. "role": admin.role
  173. }
  174. # 更新字段
  175. if req.real_name is not None:
  176. admin.real_name = req.real_name
  177. if req.email is not None:
  178. admin.email = req.email
  179. if req.role is not None:
  180. admin.role = req.role
  181. admin.updated_at = beijing_now()
  182. # 创建历史记录
  183. from app.utils.history import create_admin_history, create_operation_log
  184. create_admin_history(db, admin, "UPDATE")
  185. # 记录操作日志
  186. client_ip = request.client.host if request.client else None
  187. create_operation_log(
  188. db=db,
  189. admin_id=current_admin.id,
  190. module="管理员管理",
  191. action="更新管理员",
  192. description=f"更新管理员信息:{admin.username}",
  193. old_data=old_data,
  194. new_data={
  195. "real_name": admin.real_name,
  196. "email": admin.email,
  197. "role": admin.role
  198. },
  199. ip_address=client_ip
  200. )
  201. # 一次性提交所有更改
  202. db.commit()
  203. return {"code": 200, "msg": "更新成功"}
  204. @router.put("/{admin_id}/reset-password")
  205. async def reset_admin_password(
  206. admin_id: int,
  207. req: AdminPasswordReset,
  208. request: Request,
  209. db: Session = Depends(get_db),
  210. current_admin = Depends(get_current_admin)
  211. ):
  212. """重置管理员密码"""
  213. admin = db.query(Admin).filter(Admin.id == admin_id).first()
  214. if not admin:
  215. return {"code": 404, "msg": "管理员不存在"}
  216. # 更新密码
  217. admin.password = get_password_hash(req.new_password)
  218. admin.updated_at = beijing_now()
  219. # 记录操作日志
  220. from app.utils.history import create_operation_log
  221. client_ip = request.client.host if request.client else None
  222. create_operation_log(
  223. db=db,
  224. admin_id=current_admin.id,
  225. module="管理员管理",
  226. action="重置管理员密码",
  227. description=f"为管理员重置密码:{admin.username}",
  228. ip_address=client_ip
  229. )
  230. # 一次性提交所有更改
  231. db.commit()
  232. return {"code": 200, "msg": "密码重置成功"}
  233. @router.put("/{admin_id}/status")
  234. async def update_admin_status(
  235. admin_id: int,
  236. status: int = Query(..., description="状态:1-正常,0-禁用"),
  237. request: Request = None,
  238. db: Session = Depends(get_db),
  239. current_admin = Depends(get_current_admin)
  240. ):
  241. """启用/禁用管理员"""
  242. admin = db.query(Admin).filter(Admin.id == admin_id).first()
  243. if not admin:
  244. return {"code": 404, "msg": "管理员不存在"}
  245. # 不能禁用自己
  246. if current_admin.id == admin_id:
  247. return {"code": 400, "msg": "不能禁用自己"}
  248. old_status = admin.status
  249. admin.status = status
  250. admin.updated_at = beijing_now()
  251. # 记录操作日志
  252. from app.utils.history import create_operation_log
  253. client_ip = request.client.host if request and request.client else None
  254. status_text = "启用" if status == 1 else "禁用"
  255. create_operation_log(
  256. db=db,
  257. admin_id=current_admin.id,
  258. module="管理员管理",
  259. action="更新管理员状态",
  260. description=f"{status_text}管理员账号:{admin.username}",
  261. old_data={"status": old_status},
  262. new_data={"status": status},
  263. ip_address=client_ip
  264. )
  265. # 一次性提交所有更改
  266. db.commit()
  267. return {"code": 200, "msg": "状态更新成功"}
  268. @router.delete("/{admin_id}")
  269. async def delete_admin(
  270. admin_id: int,
  271. request: Request,
  272. db: Session = Depends(get_db),
  273. current_admin = Depends(get_current_admin)
  274. ):
  275. """删除管理员(软删除)"""
  276. admin = db.query(Admin).filter(Admin.id == admin_id, Admin.is_deleted == 0).first()
  277. if not admin:
  278. return {"code": 404, "msg": "管理员不存在"}
  279. # 不能删除自己
  280. if current_admin.id == admin_id:
  281. return {"code": 400, "msg": "不能删除自己"}
  282. admin.is_deleted = 1
  283. admin.updated_at = beijing_now()
  284. # 创建历史记录
  285. from app.utils.history import create_admin_history, create_operation_log
  286. create_admin_history(db, admin, "DELETE")
  287. # 记录操作日志
  288. client_ip = request.client.host if request.client else None
  289. create_operation_log(
  290. db=db,
  291. admin_id=current_admin.id,
  292. module="管理员管理",
  293. action="删除管理员",
  294. description=f"删除管理员账号:{admin.username}",
  295. old_data={
  296. "username": admin.username,
  297. "real_name": admin.real_name,
  298. "email": admin.email,
  299. "role": admin.role
  300. },
  301. ip_address=client_ip
  302. )
  303. # 一次性提交所有更改
  304. db.commit()
  305. return {"code": 200, "msg": "删除成功"}