schoolclass.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import copy
  4. from typing import Optional
  5. from fastapi import APIRouter, Depends, Query, Path
  6. from sqlalchemy import text
  7. from sqlalchemy.ext.asyncio import AsyncSession
  8. from starlette.background import BackgroundTasks
  9. from bgtask.tasks import delete_related_object
  10. from crud.school import crud_class, crud_school, crud_grade
  11. from models.user import SysUser
  12. from schemas.school.school import (SchoolClassList, NewClassInfo,
  13. SchoolClassDetail, ClassInDB, UpdateClass)
  14. from utils.depends import get_async_db, get_current_user
  15. router = APIRouter()
  16. # 班级列表
  17. @router.get("/classes",
  18. response_model=SchoolClassList,
  19. response_model_exclude_none=True,
  20. summary="班级列表")
  21. async def get_classes(page: Optional[int] = None,
  22. size: Optional[int] = None,
  23. sid: int = Query(None, description="学校ID"),
  24. gid: int = Query(None, description="年级ID"),
  25. db: AsyncSession = Depends(get_async_db),
  26. current_user: SysUser = Depends(get_current_user)):
  27. filters = {}
  28. if sid is not None:
  29. filters["school_id"] = sid
  30. if gid is not None:
  31. filters["grade_id"] = gid
  32. if ((page is not None) and page >= 1) and ((size is not None)
  33. and size >= 1):
  34. offset = (page - 1) * size
  35. else:
  36. offset = size = None
  37. total, items = await crud_class.find_all(db,
  38. filters=filters,
  39. offset=offset,
  40. limit=size,
  41. order_by=[text("-created_at")])
  42. return {"total": total, "data": items}
  43. @router.post("/classes",
  44. response_model=SchoolClassDetail,
  45. response_model_exclude_none=True,
  46. summary="新建班级")
  47. async def create_class(info: NewClassInfo,
  48. db: AsyncSession = Depends(get_async_db),
  49. current_user: SysUser = Depends(get_current_user)):
  50. info_dict = info.dict(exclude_none=True)
  51. if not info_dict:
  52. return {"errcode": 400, "mess": "提交参数为空!"}
  53. if not (("name" not in info_dict) or
  54. ("amount" not in info_dict)): # 单个建班或快速建班
  55. return {"errcode": 400, "mess": "缺少班级名称或数量"}
  56. # 判断学校是否存在
  57. db_school = await crud_school.find_one(db, {"id": info_dict["school_id"]})
  58. if not db_school:
  59. return {"errcode": 404, "mess": "学校不存在!"}
  60. else:
  61. info_dict["school_name"] = db_school.name
  62. # 判断年级是否存在
  63. db_grade = await crud_grade.find_one(db, {
  64. "school_id": info.school_id,
  65. "id": info.grade_id
  66. })
  67. if not db_grade:
  68. return {"errcode": 404, "mess": "年级不存在!"}
  69. else:
  70. info_dict["grade_name"] = db_grade.name
  71. # 新建班级,如果存在amount,表示为快速建班,否则为普通建班
  72. new_classes = []
  73. info_dict["creator_id"] = info_dict["editor_id"] = current_user.id
  74. info_dict["creator_name"] = info_dict["editor_name"] = current_user.username
  75. if info_dict.get("amount", 0):
  76. # 查询当前学校+当前年级下是否存在班级
  77. _, db_class = await crud_class.find_all(db,
  78. filters={
  79. "school_id": info.school_id,
  80. "grade_id": info.grade_id
  81. },
  82. return_fields=["name"])
  83. db_class_names = [x.name for x in db_class]
  84. for i in range(1, info_dict.pop("amount") + 1):
  85. name = f"{info_dict['grade_name']}{str(i)}班"
  86. if name not in db_class_names:
  87. temp = copy.deepcopy(info_dict)
  88. temp["name"] = name
  89. new_classes.append(temp)
  90. else:
  91. info_dict["name"] = info_dict["grade_name"] + info_dict["name"]
  92. new_classes.append(ClassInDB(**info_dict))
  93. item = await crud_class.insert_many(db, new_classes)
  94. if item is None:
  95. return {"errcode": 400, "mess": "存在同名班级"}
  96. else:
  97. return {"data": item}
  98. @router.get("/classes/{cid}",
  99. response_model=SchoolClassDetail,
  100. response_model_exclude_none=True,
  101. summary="班级详情")
  102. async def get_class(cid: str = Path(..., description="班级ID"),
  103. db: AsyncSession = Depends(get_async_db),
  104. current_user: SysUser = Depends(get_current_user)):
  105. db_obj = await crud_class.find_one(db, {"id": cid})
  106. return {"data": db_obj} if db_obj else {"errcode": 404, "mess": "班级不存在!"}
  107. # 更新班级
  108. @router.put("/classes/{cid}",
  109. response_model=SchoolClassDetail,
  110. response_model_exclude_none=True,
  111. summary="更新班级")
  112. async def update_class(info: UpdateClass,
  113. cid: int = Path(..., description="班级ID"),
  114. db: AsyncSession = Depends(get_async_db),
  115. current_user: SysUser = Depends(get_current_user)):
  116. # 判断提交参数
  117. info_dict = info.dict(exclude_none=True)
  118. if not info_dict:
  119. return {"errcode": 400, "mess": "提交参数为空!"}
  120. # 判断班级是否存在
  121. db_obj = await crud_class.find_one(db, {"id": cid})
  122. if not db_obj:
  123. return {"errcode": 404, "mess": "班级不存在!"}
  124. # 如果学校ID不等于班级的school_id, 则更新
  125. if ("school_id"
  126. in info_dict) and (db_obj.school_id != info_dict["school_id"]):
  127. db_school = await crud_school.count(db, {"id": info.school_id})
  128. if not db_school:
  129. return {"errcode": 404, "mess": "学校不存在!"}
  130. else:
  131. info.school_name = db_school.name
  132. # 判断年级是否存在
  133. if ("grade_id" in info_dict) and (db_obj.grade_id != info_dict["grade_id"]):
  134. db_grade = await crud_grade.count(db, {
  135. "school_id": info.school_id,
  136. "id": info.grade_id
  137. })
  138. if not db_grade:
  139. return {"errcode": 404, "mess": "年级不存在!"}
  140. else:
  141. info.grade_name = db_grade.name
  142. # 更新班级
  143. info.editor_id = current_user.id
  144. info.editor_name = current_user.username
  145. db_obj = await crud_class.update(db, db_obj, info)
  146. return {"data": db_obj}
  147. # 删除班级
  148. @router.delete("/classes/{cid}",
  149. response_model=SchoolClassDetail,
  150. response_model_exclude_none=True,
  151. summary="删除班级")
  152. async def delete_class(bg_task: BackgroundTasks,
  153. cid: int = Path(..., description="班级ID"),
  154. db: AsyncSession = Depends(get_async_db),
  155. current_user: SysUser = Depends(get_current_user)):
  156. existed = await crud_class.count(db, {"id": cid})
  157. if not existed:
  158. return {"errcode": 404, "mess": "班级不存在!"}
  159. else:
  160. await crud_class.delete(db, obj_id=cid)
  161. bg_task.add_task(delete_related_object, db, cid=cid)
  162. return {"data": None}