resource.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import datetime
  4. from fastapi import Depends, Query, Path
  5. from sqlalchemy import text
  6. from sqlalchemy.ext.asyncio import AsyncSession
  7. from starlette.background import BackgroundTasks
  8. from bgtask.tasks import bgtask_delete_remote_file
  9. from common.const import RESOURCE_TYPES
  10. from crud.resource import CATEGORY_CRUDS, RESOURCE_CRUDS
  11. from crud.school import crud_school
  12. from models.resource import RESOURCE_MODES
  13. from models.user import Admin
  14. from schemas.base import OrderByField, ReturnField
  15. from schemas.resource.resource import NewResource, UpdateResource
  16. from utils.depends import get_async_db, get_current_user
  17. async def get_resources(page: int = 1,
  18. size: int = 10,
  19. name: str = "",
  20. year: int = 0,
  21. sid: int = 0,
  22. ctype: str = Query(..., description="资源分类名称,exam/work"),
  23. ctgid: int = Query(0, description="资源分类ID"),
  24. rtype: str = Query("", description="作业资源分类"),
  25. created_at: str = Query("", description="YYYY-MM-DD"),
  26. order: OrderByField = Query("-created_at",
  27. description="排序字段,用逗号分隔,升降序以-判断,默认-created_at"),
  28. res: ReturnField = Query("", description="返回字段,默认列表展示字段,自定义: id,name"),
  29. db: AsyncSession = Depends(get_async_db),
  30. current_user: Admin = Depends(get_current_user)):
  31. # 判断资源类型
  32. if ctype not in RESOURCE_TYPES:
  33. return {"errcode": 400, "mess": "资源类型不存在!"}
  34. else:
  35. crud = RESOURCE_CRUDS[ctype]
  36. model = RESOURCE_MODES[ctype]
  37. # 筛选条件
  38. _q = []
  39. if name:
  40. _q.append(model.name.like(f"%{name}%"))
  41. if year:
  42. _q.append(model.year == year)
  43. if sid:
  44. _q.append(model.school_id == sid)
  45. if ctgid:
  46. _q.append(model.category_id == ctgid)
  47. if ctype and rtype:
  48. _q.append(model.rtype == rtype)
  49. if created_at:
  50. _q.append(model.created_at >= datetime.datetime.strptime(created_at, "%Y-%m-%d"))
  51. offset = (page - 1) * size
  52. # 查询
  53. if isinstance(order, str):
  54. order = [text(order)]
  55. total, items = await crud.find_all(db,
  56. filters=_q,
  57. offset=offset,
  58. limit=size,
  59. order_by=order,
  60. return_fields=res)
  61. if (not res) or (res and ("attach_url" in res)):
  62. for item in items:
  63. item.attach_url = item.attach_url.split(";")
  64. return {"data": items, "total": total}
  65. async def create_resource(info: NewResource,
  66. db: AsyncSession = Depends(get_async_db),
  67. current_user: Admin = Depends(get_current_user)):
  68. # 判断提交参数
  69. info_dict = info.dict(exclude_none=True)
  70. if not info_dict:
  71. return {"errcode": 400, "mess": "提交参数为空!"}
  72. # 是否有附件
  73. if not info_dict.get("attach_url", ""):
  74. return {"errcode": 400, "mess": "缺少附件URL!"}
  75. else:
  76. info.attach_url = ";".join(info_dict.get("attach_url"))
  77. # 判断资源类型
  78. if info_dict["ctype"] not in RESOURCE_TYPES:
  79. return {"errcode": 400, "mess": "资源类型不存在!"}
  80. db_category = await CATEGORY_CRUDS[info_dict["ctype"]
  81. ].find_one(db, filters={"id": info_dict["category_id"]})
  82. if not db_category:
  83. return {"errcode": 404, "mess": "资源分类不存在!"}
  84. info.subject = db_category.subject
  85. info.category_name = db_category.name
  86. # 如果是考试资源,先判断学校是否存在
  87. if info_dict["ctype"] == "exam":
  88. if not info_dict.get("school_id", None):
  89. return {"errcode": 400, "mess": "缺少学校ID或名称"}
  90. db_school = await crud_school.find_one(db, filters={"id": info_dict["school_id"]})
  91. if not db_school:
  92. return {"errcode": 404, "mess": "学校不存在!"}
  93. else:
  94. info.school_name = db_school.name
  95. # 创建
  96. info.creator_id = info.editor_id = current_user.id
  97. info.creator_name = info.editor_name = current_user.username
  98. delattr(info, "ctype")
  99. db_obj = await RESOURCE_CRUDS[info_dict["ctype"]].insert_one(db, info)
  100. db_obj.attach_url = db_obj.attach_url.split(";")
  101. return {"data": db_obj}
  102. async def get_resource(rid: int = Path(..., description="资源ID"),
  103. ctype: str = Query(..., description="资源分类,exam/work"),
  104. db: AsyncSession = Depends(get_async_db),
  105. current_user: Admin = Depends(get_current_user)):
  106. # 判断资源类型
  107. if ctype not in RESOURCE_TYPES:
  108. return {"errcode": 400, "mess": "资源类型不存在!"}
  109. db_obj = await RESOURCE_CRUDS[ctype].find_one(db, filters={"id": rid})
  110. db_obj.attach_url = db_obj.attach_url.split(";")
  111. return {"data": db_obj}
  112. async def update_resource(info: UpdateResource,
  113. bgtask: BackgroundTasks,
  114. rid: int = Path(..., description="资源ID"),
  115. db: AsyncSession = Depends(get_async_db),
  116. current_user: Admin = Depends(get_current_user)):
  117. # 判断提交参数
  118. info_dict = info.dict(exclude_none=True)
  119. if not info_dict:
  120. return {"errcode": 400, "mess": "提交参数为空!"}
  121. # 判断资源类型
  122. if info_dict["ctype"] not in RESOURCE_TYPES:
  123. return {"errcode": 400, "mess": "资源类型不存在!"}
  124. # 判断资源是否存在
  125. db_obj = await RESOURCE_CRUDS[info_dict["ctype"]].find_one(db, filters={"id": rid})
  126. if not db_obj:
  127. return {"errcode": 404, "mess": "资源不存在!"}
  128. # 判断资源分类是否存在
  129. if ("category_id" in info_dict) and (db_obj.category_id != info_dict["category_id"]):
  130. db_category = await CATEGORY_CRUDS[info_dict["ctype"]
  131. ].find_one(db, filters={"id": info_dict["category_id"]})
  132. if not db_category:
  133. return {"errcode": 404, "mess": "资源分类不存在!"}
  134. info.subject = db_category.subject
  135. info.category_name = db_category.name
  136. # 如果是考试资源,判断学校是否存在
  137. if info_dict["ctype"] == "exam":
  138. if ("school_id" in info_dict) and (db_obj.school_id != info_dict["school_id"]):
  139. db_school = await crud_school.find_one(db, filters={"id": info_dict["school_id"]})
  140. if not db_school:
  141. return {"errcode": 404, "mess": "学校不存在!"}
  142. else:
  143. info.school_name = db_school.name
  144. # 上传文件
  145. if info_dict.get("attach_url", ""):
  146. info.attach_url = ";".join(info_dict.get("attach_url"))
  147. # 删除旧的附件
  148. bgtask.add_task(bgtask_delete_remote_file, db_obj.attach_url)
  149. # 开始更新
  150. info_dict["editor_id"] = current_user.id
  151. info_dict["editor_name"] = current_user.username
  152. info = UpdateResource(**info_dict)
  153. db_obj = await RESOURCE_CRUDS[info_dict["ctype"]].update(db, db_obj, info)
  154. db_obj.attach_url = db_obj.attach_url.split(";")
  155. return {"data": db_obj}
  156. async def delete_resource(bgtask: BackgroundTasks,
  157. rid: int = Path(..., description="资源ID"),
  158. ctype: str = Query(..., description="资源分类,exam/work"),
  159. db: AsyncSession = Depends(get_async_db),
  160. current_user: Admin = Depends(get_current_user)):
  161. # 判断资源类型
  162. if ctype not in RESOURCE_TYPES:
  163. return {"errcode": 400, "mess": "资源类型不存在!"}
  164. # 删除
  165. db_obj = await RESOURCE_CRUDS[ctype].find_one(db, filters={"id": rid})
  166. if not db_obj:
  167. return {"errcode": 404, "mess": "资源不存在!"}
  168. else:
  169. await RESOURCE_CRUDS[ctype].delete(db, obj_id=rid)
  170. bgtask.add_task(bgtask_delete_remote_file, db_obj.attach_url)
  171. return {"data": None}