admins.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  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 = "super_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. # 系统只使用 super_admin 角色,强制写为 super_admin,避免外部传入其他值
  98. role='super_admin',
  99. status=1,
  100. created_at=beijing_now(),
  101. updated_at=beijing_now()
  102. )
  103. db.add(admin)
  104. # 刷新以获取ID
  105. db.flush()
  106. # 创建历史记录
  107. from app.utils.history import create_admin_history, create_operation_log
  108. create_admin_history(db, admin, "INSERT")
  109. # 记录操作日志
  110. client_ip = request.client.host if request.client else None
  111. create_operation_log(
  112. db=db,
  113. admin_id=current_admin.id,
  114. module="管理员管理",
  115. action="创建管理员",
  116. description=f"创建管理员账号:{req.username}",
  117. new_data={
  118. "username": req.username,
  119. "real_name": req.real_name,
  120. "email": req.email,
  121. "role": req.role
  122. },
  123. ip_address=client_ip
  124. )
  125. # 一次性提交所有更改
  126. db.commit()
  127. return {"code": 200, "msg": "创建成功", "data": {"id": admin.id}}
  128. @router.get("/{admin_id}")
  129. async def get_admin(
  130. admin_id: int,
  131. db: Session = Depends(get_db),
  132. current_admin = Depends(get_current_admin)
  133. ):
  134. """获取管理员详情"""
  135. admin = db.query(Admin).filter(Admin.id == admin_id).first()
  136. if not admin:
  137. return {"code": 404, "msg": "管理员不存在"}
  138. return {
  139. "code": 200,
  140. "msg": "成功",
  141. "data": {
  142. "id": admin.id,
  143. "username": admin.username,
  144. "real_name": admin.real_name,
  145. "email": admin.email,
  146. "role": admin.role,
  147. "status": admin.status,
  148. "last_login_time": admin.last_login_time.isoformat() if admin.last_login_time else None,
  149. "last_login_ip": admin.last_login_ip,
  150. "created_at": admin.created_at.isoformat() if admin.created_at else None,
  151. "updated_at": admin.updated_at.isoformat() if admin.updated_at else None
  152. }
  153. }
  154. @router.put("/{admin_id}")
  155. async def update_admin(
  156. admin_id: int,
  157. req: AdminUpdate,
  158. request: Request,
  159. db: Session = Depends(get_db),
  160. current_admin = Depends(get_current_admin)
  161. ):
  162. """更新管理员"""
  163. admin = db.query(Admin).filter(Admin.id == admin_id).first()
  164. if not admin:
  165. return {"code": 404, "msg": "管理员不存在"}
  166. # 不能修改自己的角色
  167. if current_admin.id == admin_id and req.role and req.role != admin.role:
  168. return {"code": 400, "msg": "不能修改自己的角色"}
  169. # 记录更新前的状态
  170. old_data = {
  171. "real_name": admin.real_name,
  172. "email": admin.email,
  173. "role": admin.role
  174. }
  175. # 更新字段
  176. if req.real_name is not None:
  177. admin.real_name = req.real_name
  178. if req.email is not None:
  179. admin.email = req.email
  180. if req.role is not None:
  181. # 系统只支持 super_admin,任何传入值都统一设置为 super_admin
  182. admin.role = 'super_admin'
  183. admin.updated_at = beijing_now()
  184. # 创建历史记录
  185. from app.utils.history import create_admin_history, create_operation_log
  186. create_admin_history(db, admin, "UPDATE")
  187. # 记录操作日志
  188. client_ip = request.client.host if request.client else None
  189. create_operation_log(
  190. db=db,
  191. admin_id=current_admin.id,
  192. module="管理员管理",
  193. action="更新管理员",
  194. description=f"更新管理员信息:{admin.username}",
  195. old_data=old_data,
  196. new_data={
  197. "real_name": admin.real_name,
  198. "email": admin.email,
  199. "role": admin.role
  200. },
  201. ip_address=client_ip
  202. )
  203. # 一次性提交所有更改
  204. db.commit()
  205. return {"code": 200, "msg": "更新成功"}
  206. @router.put("/{admin_id}/reset-password")
  207. async def reset_admin_password(
  208. admin_id: int,
  209. req: AdminPasswordReset,
  210. request: Request,
  211. db: Session = Depends(get_db),
  212. current_admin = Depends(get_current_admin)
  213. ):
  214. """重置管理员密码"""
  215. admin = db.query(Admin).filter(Admin.id == admin_id).first()
  216. if not admin:
  217. return {"code": 404, "msg": "管理员不存在"}
  218. # 更新密码
  219. admin.password = get_password_hash(req.new_password)
  220. admin.updated_at = beijing_now()
  221. # 记录操作日志
  222. from app.utils.history import create_operation_log
  223. client_ip = request.client.host if request.client else None
  224. create_operation_log(
  225. db=db,
  226. admin_id=current_admin.id,
  227. module="管理员管理",
  228. action="重置管理员密码",
  229. description=f"为管理员重置密码:{admin.username}",
  230. ip_address=client_ip
  231. )
  232. # 一次性提交所有更改
  233. db.commit()
  234. return {"code": 200, "msg": "密码重置成功"}
  235. @router.put("/{admin_id}/status")
  236. async def update_admin_status(
  237. admin_id: int,
  238. status: int = Query(..., description="状态:1-正常,0-禁用"),
  239. request: Request = None,
  240. db: Session = Depends(get_db),
  241. current_admin = Depends(get_current_admin)
  242. ):
  243. """启用/禁用管理员"""
  244. admin = db.query(Admin).filter(Admin.id == admin_id).first()
  245. if not admin:
  246. return {"code": 404, "msg": "管理员不存在"}
  247. # 不能禁用自己
  248. if current_admin.id == admin_id:
  249. return {"code": 400, "msg": "不能禁用自己"}
  250. old_status = admin.status
  251. admin.status = status
  252. admin.updated_at = beijing_now()
  253. # 记录操作日志
  254. from app.utils.history import create_operation_log
  255. client_ip = request.client.host if request and request.client else None
  256. status_text = "启用" if status == 1 else "禁用"
  257. create_operation_log(
  258. db=db,
  259. admin_id=current_admin.id,
  260. module="管理员管理",
  261. action="更新管理员状态",
  262. description=f"{status_text}管理员账号:{admin.username}",
  263. old_data={"status": old_status},
  264. new_data={"status": status},
  265. ip_address=client_ip
  266. )
  267. # 一次性提交所有更改
  268. db.commit()
  269. return {"code": 200, "msg": "状态更新成功"}
  270. @router.delete("/{admin_id}")
  271. async def delete_admin(
  272. admin_id: int,
  273. request: Request,
  274. db: Session = Depends(get_db),
  275. current_admin = Depends(get_current_admin)
  276. ):
  277. """删除管理员(软删除)"""
  278. admin = db.query(Admin).filter(Admin.id == admin_id, Admin.is_deleted == 0).first()
  279. if not admin:
  280. return {"code": 404, "msg": "管理员不存在"}
  281. # 不能删除自己
  282. if current_admin.id == admin_id:
  283. return {"code": 400, "msg": "不能删除自己"}
  284. admin.is_deleted = 1
  285. admin.updated_at = beijing_now()
  286. # 创建历史记录
  287. from app.utils.history import create_admin_history, create_operation_log
  288. create_admin_history(db, admin, "DELETE")
  289. # 记录操作日志
  290. client_ip = request.client.host if request.client else None
  291. create_operation_log(
  292. db=db,
  293. admin_id=current_admin.id,
  294. module="管理员管理",
  295. action="删除管理员",
  296. description=f"删除管理员账号:{admin.username}",
  297. old_data={
  298. "username": admin.username,
  299. "real_name": admin.real_name,
  300. "email": admin.email,
  301. "role": admin.role
  302. },
  303. ip_address=client_ip
  304. )
  305. # 一次性提交所有更改
  306. db.commit()
  307. return {"code": 200, "msg": "删除成功"}