resource.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import datetime
  4. from typing import Union
  5. from fastapi import Query, Depends, Path, Body
  6. from sqlalchemy import text, update
  7. from sqlalchemy.ext.asyncio import AsyncSession
  8. from common.const import RESOURCE_TYPES
  9. from crud.resource import crud_work_resource, crud_exam_resource, crud_collect
  10. from models.resource import WorkResource, ExamResource
  11. from models.user import Teacher, Student
  12. from schemas.app.resource import NewResourceCollect, CollectInfo
  13. from schemas.base import OrderByField
  14. from utils.depends import get_async_db, get_current_user
  15. async def get_resources(
  16. page: int = 1,
  17. size: int = 10,
  18. name: str = "",
  19. year: int = 0,
  20. sid: int = Query(0, description="学校ID,获取考试资源时才传此参数"),
  21. ctype: str = Query(..., description="资源分类名称,exam/work"),
  22. ctgid: int = Query(0, description="资源分类ID"),
  23. rtype: str = Query("", description="作业资源分类"),
  24. isnew: int = Query(0, description="最新资源,是=1,否=0"),
  25. hot: int = Query(0, description="是否热点资源?是=1,否=0"),
  26. order: OrderByField = Query(None, description="排序字段,用逗号分隔,升降序以-判断"),
  27. db: AsyncSession = Depends(get_async_db),
  28. current_user: Union[Teacher, Student] = Depends(get_current_user)):
  29. # 判断资源类型
  30. if ctype not in RESOURCE_TYPES:
  31. return {"errcode": 400, "mess": "资源类型不存在!"}
  32. now = datetime.datetime.now()
  33. # 筛选条件
  34. filters = []
  35. if name:
  36. filters.append(text(f"name LIKE '%{name}%'"))
  37. if year:
  38. filters.append(text(f"year = {year}"))
  39. if (ctype == "exam") and sid:
  40. filters.append(text(f"school_id = {sid}"))
  41. if ctgid:
  42. filters.append(text(f"category_id = {ctgid}"))
  43. if ctype and rtype:
  44. filters.append(text(f"rtype = '{rtype}'"))
  45. if hot:
  46. filters.append(text(f"hot = {hot}"))
  47. if isinstance(order, str):
  48. order = [text(order)]
  49. if isnew:
  50. start_time = now - datetime.timedelta(days=3)
  51. now_str = now.strftime("%Y-%m-%d %H:%M:%S")
  52. start_time_str = start_time.strftime("%Y-%m-%d %H:%M:%S")
  53. filters.append(
  54. text(f"created_at BETWEEN '{start_time_str}' AND '{now_str}'"))
  55. offset = (page - 1) * size
  56. # 查询
  57. crud = crud_work_resource if ctype == "work" else crud_exam_resource
  58. total, items = await crud.find_all(db,
  59. filters=filters,
  60. offset=offset,
  61. limit=size,
  62. order_by=order)
  63. # 判断是否最新资源
  64. for item in items:
  65. item.attach_url = item.attach_url.split(";")
  66. if (now - item.created_at).days <= 3:
  67. item.isnew = True
  68. else:
  69. item.isnew = False
  70. delattr(item, "attach_url")
  71. return {"data": items, "total": total}
  72. async def download_resource(
  73. rid: int = Path(..., description="资源ID"),
  74. ctype: str = Query(..., description="资源分类名称,exam/work"),
  75. db: AsyncSession = Depends(get_async_db),
  76. current_user: Union[Teacher, Student] = Depends(get_current_user)):
  77. # 判断资源类型
  78. if ctype not in RESOURCE_TYPES:
  79. return {"errcode": 400, "mess": "资源类型不存在!"}
  80. # 查询
  81. if ctype == "work":
  82. crud = crud_work_resource
  83. table = WorkResource
  84. else:
  85. crud = crud_exam_resource
  86. table = ExamResource
  87. item = await crud.find_one(db,
  88. filters={"id": rid},
  89. return_fields=["download", "attach_url"])
  90. # 更新下载量
  91. download_num = item.download + 1
  92. stmt = (update(table).where(table.id == rid).values(download=download_num))
  93. await crud.increase(db, stmt)
  94. return {
  95. "data": {
  96. "urls": item.attach_url.split(";"),
  97. "download": download_num
  98. }
  99. }
  100. async def collect_resource(
  101. rid: int = Path(..., description="资源ID"),
  102. ctype: str = Query(..., description="资源分类名称,exam/work"),
  103. opt: CollectInfo = Body(..., description="操作类型,0=取消收藏,1=添加收藏"),
  104. db: AsyncSession = Depends(get_async_db),
  105. current_user: Union[Teacher, Student] = Depends(get_current_user)):
  106. # 判断资源类型
  107. if ctype not in RESOURCE_TYPES:
  108. return {"errcode": 400, "mess": "资源类型不存在!"}
  109. # 查询
  110. if ctype == "work":
  111. crud = crud_work_resource
  112. table = WorkResource
  113. else:
  114. crud = crud_exam_resource
  115. table = ExamResource
  116. # 判断资源是否存在
  117. db_obj = await crud.find_one(db,
  118. filters={"id": rid},
  119. return_fields=["collect"])
  120. if not db_obj:
  121. return {"errcode": 404, "mess": "资源不存在!"}
  122. # 更新收藏量
  123. if opt.opt:
  124. collect_num = db_obj.collect + 1
  125. else:
  126. collect_num = db_obj.collect - 1
  127. stmt = (update(table).where(table.id == rid).values(collect=collect_num))
  128. await crud.increase(db, stmt)
  129. # 写入收藏表
  130. utype = 1 if isinstance(current_user, Teacher) else 2
  131. if opt.opt:
  132. info = NewResourceCollect(rid=rid,
  133. ctype=ctype,
  134. uid=current_user.id,
  135. utype=utype)
  136. await crud_collect.insert_one(db, info)
  137. else:
  138. await crud_collect.delete(db,
  139. where_clauses={
  140. "rid": rid,
  141. "ctype": ctype,
  142. "uid": current_user.id,
  143. "utype": utype
  144. })
  145. return {"data": {"collect": collect_num}}
  146. async def preview_resource(
  147. rid: int = Path(..., description="资源ID"),
  148. ctype: str = Query(..., description="资源分类名称,exam/work"),
  149. db: AsyncSession = Depends(get_async_db),
  150. current_user: Union[Teacher, Student] = Depends(get_current_user)):
  151. # 判断资源类型
  152. if ctype not in RESOURCE_TYPES:
  153. return {"errcode": 400, "mess": "资源类型不存在!"}
  154. # 查询
  155. if ctype == "work":
  156. crud = crud_work_resource
  157. table = WorkResource
  158. else:
  159. crud = crud_exam_resource
  160. table = ExamResource
  161. # 判断资源是否存在
  162. db_obj = await crud.find_one(db,
  163. filters={"id": rid},
  164. return_fields=["visit", "attach_url"])
  165. if not db_obj:
  166. return {"errcode": 400, "mess": "资源不存在!"}
  167. # 更新浏览量
  168. visit_num = db_obj.visit + 1
  169. stmt = (update(table).where(table.id == rid).values(visit=visit_num))
  170. await crud.increase(db, stmt)
  171. return {"data": {"urls": db_obj.attach_url.split(";"), "visit": visit_num}}