resource.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. from fastapi import Depends, Query, Path
  4. from sqlalchemy import text
  5. from sqlalchemy.ext.asyncio import AsyncSession
  6. from starlette.background import BackgroundTasks
  7. from bgtask.tasks import delete_remote_file
  8. from common.const import RESOURCE_TYPES
  9. from crud.resource import (crud_work_category, crud_exam_category,
  10. crud_exam_resource, crud_work_resource)
  11. from crud.school import crud_school
  12. from models.user import SysUser
  13. from schemas.base import OrderByField, ReturnField
  14. from schemas.resource.resource import NewResource, UpdateResource
  15. from utils.depends import get_async_db, get_current_user
  16. async def get_resources(
  17. 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: SysUser = Depends(get_current_user)):
  31. # 判断资源类型
  32. if ctype not in RESOURCE_TYPES:
  33. return {"errcode": 400, "mess": "资源类型不存在!"}
  34. # 筛选条件
  35. filters = []
  36. if name:
  37. filters.append(text(f"name LIKE '%{name}%'"))
  38. if year:
  39. filters.append(text(f"year = {year}"))
  40. if sid:
  41. filters.append(text(f"school_id = {sid}"))
  42. if ctgid:
  43. filters.append(text(f"category_id = {ctgid}"))
  44. if ctype and rtype:
  45. filters.append(text(f"rtype = '{rtype}'"))
  46. if created_at:
  47. filters.append(text(f"created_at > '{created_at}'"))
  48. offset = (page - 1) * size
  49. # 查询
  50. crud = crud_work_resource if ctype == "work" else crud_exam_resource
  51. if isinstance(order, str):
  52. order = [text(order)]
  53. total, items = await crud.find_all(db,
  54. filters=filters,
  55. offset=offset,
  56. limit=size,
  57. order_by=order,
  58. return_fields=res)
  59. if (not res) or (res and ("attach_url" in res)):
  60. for item in items:
  61. item.attach_url = item.attach_url.split(";")
  62. return {"data": items, "total": total}
  63. async def create_resource(info: NewResource,
  64. db: AsyncSession = Depends(get_async_db),
  65. current_user: SysUser = Depends(get_current_user)):
  66. # 判断提交参数
  67. info_dict = info.dict(exclude_none=True)
  68. if not info_dict:
  69. return {"errcode": 400, "mess": "提交参数为空!"}
  70. # 是否有附件
  71. if not info_dict.get("attach_url", ""):
  72. return {"errcode": 400, "mess": "缺少附件URL!"}
  73. else:
  74. info.attach_url = ";".join(info_dict.get("attach_url"))
  75. # 判断资源类型
  76. if info_dict["ctype"] not in RESOURCE_TYPES:
  77. return {"errcode": 400, "mess": "资源类型不存在!"}
  78. # 资源分类, 判断分类是否存在
  79. if info_dict["ctype"] == "work":
  80. crud_category = crud_work_category
  81. crud_resource = crud_work_resource
  82. else:
  83. crud_category = crud_exam_category
  84. crud_resource = crud_exam_resource
  85. existed = await crud_category.count(
  86. db, filters={"id": info_dict["category_id"]})
  87. if not existed:
  88. return {"errcode": 404, "mess": "资源分类不存在!"}
  89. # 如果是考试资源,先判断学校是否存在
  90. if info_dict["ctype"] == "exam":
  91. if not info_dict.get("school_id", None):
  92. return {"errcode": 400, "mess": "缺少学校ID或名称"}
  93. db_school = await crud_school.find_one(
  94. db, filters={"id": info_dict["school_id"]})
  95. if not existed:
  96. return {"errcode": 404, "mess": "学校不存在!"}
  97. else:
  98. info.school_name = db_school.name
  99. # 创建
  100. info.creator_id = info.editor_id = current_user.id
  101. info.creator_name = info.editor_name = current_user.username
  102. info.visit = info.download = info.collect = 0
  103. delattr(info, "ctype")
  104. db_obj = await crud_resource.insert_one(db, info)
  105. db_obj.attach_url = db_obj.attach_url.split(";")
  106. return {"data": db_obj}
  107. async def get_resource(rid: int = Path(..., description="资源ID"),
  108. ctype: str = Query(..., description="资源分类,exam/work"),
  109. db: AsyncSession = Depends(get_async_db),
  110. current_user: SysUser = Depends(get_current_user)):
  111. # 判断资源类型
  112. if ctype not in RESOURCE_TYPES:
  113. return {"errcode": 400, "mess": "资源类型不存在!"}
  114. crud = crud_work_resource if ctype == "work" else crud_exam_resource
  115. db_obj = await crud.find_one(db, {"id": rid})
  116. db_obj.attach_url = db_obj.attach_url.split(";")
  117. return {"data": db_obj}
  118. async def update_resource(info: UpdateResource,
  119. bg_task: BackgroundTasks,
  120. rid: int = Path(..., description="资源ID"),
  121. db: AsyncSession = Depends(get_async_db),
  122. current_user: SysUser = Depends(get_current_user)):
  123. # 判断提交参数
  124. info_dict = info.dict(exclude_none=True)
  125. if not info_dict:
  126. return {"errcode": 400, "mess": "提交参数为空!"}
  127. # 判断资源类型
  128. if info_dict["ctype"] not in RESOURCE_TYPES:
  129. return {"errcode": 400, "mess": "资源类型不存在!"}
  130. # 判断资源是否存在
  131. if info_dict["ctype"] == "work":
  132. crud_category = crud_work_category
  133. crud_resource = crud_work_resource
  134. else:
  135. crud_category = crud_exam_category
  136. crud_resource = crud_exam_resource
  137. db_obj = await crud_resource.find_one(db, filters={"id": rid})
  138. if not db_obj:
  139. return {"errcode": 404, "mess": "资源不存在!"}
  140. # 判断资源分类是否存在
  141. if ("category_id"
  142. in info_dict) and (db_obj.category_id != info_dict["category_id"]):
  143. existed = await crud_category.count(
  144. db, filters={"id": info_dict["category_id"]})
  145. if not existed:
  146. return {"errcode": 404, "mess": "资源分类不存在!"}
  147. # 如果是考试资源,判断学校是否存在
  148. if info_dict["ctype"] == "exam":
  149. if ("school_id"
  150. in info_dict) and (db_obj.school_id != info_dict["school_id"]):
  151. db_school = await crud_school.find_one(
  152. db, filters={"id": info_dict["school_id"]})
  153. if not db_school:
  154. return {"errcode": 404, "mess": "学校不存在!"}
  155. else:
  156. info.school_name = db_school.name
  157. # 上传文件
  158. if info_dict.get("attach_url", ""):
  159. info.attach_url = ";".join(info_dict.get("attach_url"))
  160. # 删除旧的附件
  161. bg_task.add_task(delete_remote_file, db_obj.attach_url)
  162. # 开始更新
  163. info_dict["editor_id"] = current_user.id
  164. info_dict["editor_name"] = current_user.username
  165. info = UpdateResource(**info_dict)
  166. db_obj = await crud_resource.update(db, db_obj, info)
  167. db_obj.attach_url = db_obj.attach_url.split(";")
  168. return {"data": db_obj}
  169. async def delete_resource(bg_task: BackgroundTasks,
  170. rid: int = Path(..., description="资源ID"),
  171. ctype: str = Query(..., description="资源分类,exam/work"),
  172. db: AsyncSession = Depends(get_async_db),
  173. current_user: SysUser = Depends(get_current_user)):
  174. # 判断资源类型
  175. if ctype not in RESOURCE_TYPES:
  176. return {"errcode": 400, "mess": "资源类型不存在!"}
  177. # 删除
  178. crud = crud_work_resource if ctype == "work" else crud_exam_resource
  179. db_obj = await crud.find_one(db, {"id": rid})
  180. if not db_obj:
  181. return {"errcode": 404, "mess": "资源不存在!"}
  182. else:
  183. await crud.delete(db, obj_id=rid)
  184. # bg_task.add_task(delete_remote_file, db_obj.attach_url)
  185. return {"data": None}