123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- import datetime
- from typing import Union
- from fastapi import Query, Depends, Path, Body
- from sqlalchemy import text, update, between
- from sqlalchemy.ext.asyncio import AsyncSession
- from common.const import RESOURCE_TYPES
- from crud.resource import RESOURCE_CRUDS, crud_collection
- from models.resource import RESOURCE_MODES
- from models.user import Teacher, Student
- from schemas.app.resource import NewResourceCollect, CollectInfo
- from schemas.base import OrderByField
- from utils.depends import get_async_db, get_current_user
- from utils.fileuploader import ossfile_uploader
- async def get_resources(page: int = 1,
- size: int = 10,
- name: str = "",
- year: int = 0,
- area: str = "",
- sid: int = Query(0, description="学校ID,获取考试资源时才传此参数"),
- ctype: str = Query(..., description="资源分类名称,exam/work"),
- ctgid: int = Query(0, description="资源分类ID"),
- rtype: str = Query("", description="作业资源分类"),
- isnew: int = Query(0, description="最新资源,是=1,否=0"),
- hot: int = Query(0, description="是否热点资源?是=1,否=0"),
- order: OrderByField = Query("-id", description="排序字段,用逗号分隔,升降序以-判断"),
- db: AsyncSession = Depends(get_async_db),
- current_user: Union[Teacher, Student] = Depends(get_current_user)):
- # 判断资源类型
- if ctype not in RESOURCE_TYPES:
- return {"errcode": 400, "mess": "资源类型不存在!"}
- else:
- model = RESOURCE_MODES[ctype]
- # 筛选条件
- _q = []
- if area and area != "0":
- _q.append(model.area == area)
- if name:
- _q.append(model.name.like(f"%{name}%"))
- if year:
- _q.append(model.year == year)
- if (ctype == "exam") and sid:
- _q.append(model.school_id == sid)
- if ctgid:
- _q.append(model.category_id == ctgid)
- if ctype and rtype:
- _q.append(model.rtype == rtype)
- if hot:
- _q.append(model.hot == hot)
- now_time = datetime.datetime.now()
- if isnew:
- start_time = now_time - datetime.timedelta(days=3)
- _q.append(between(model.created_at, start_time, now_time))
- offset = (page - 1) * size
- # 查询
- total, db_resources = await RESOURCE_CRUDS[ctype].find_all(db,
- filters=_q,
- offset=offset,
- limit=size,
- order_by=order)
- # 判断是否最新资源
- for item in db_resources:
- item.attach_url = item.attach_url.split(";")
- if (now_time - item.created_at).days <= 3:
- item.isnew = True
- else:
- item.isnew = False
- delattr(item, "attach_url")
- return {"data": db_resources, "total": total}
- async def download_resource(rid: int = Path(..., description="资源ID"),
- ctype: str = Query(..., description="资源分类名称,exam/work"),
- db: AsyncSession = Depends(get_async_db),
- current_user: Union[Teacher, Student] = Depends(get_current_user)):
- # 判断资源类型
- if ctype not in RESOURCE_TYPES:
- return {"errcode": 400, "mess": "资源类型不存在!"}
- else:
- model = RESOURCE_MODES[ctype]
- crud = RESOURCE_CRUDS[ctype]
- # 查询
- db_resource = await crud.find_one(db,
- filters={"id": rid},
- return_fields=["download", "attach_url"])
- # 更新下载量
- download = db_resource.download + 1
- stmt = (update(model).where(model.id == rid).values(download=download))
- await crud.execute_v2(db, stmt)
- return {"data": {"urls": db_resource.attach_url.split(";"), "download": download}}
- async def collect_resource(rid: int = Path(..., description="资源ID"),
- ctype: str = Query(..., description="资源分类名称,exam/work"),
- opt: CollectInfo = Body(..., description="操作类型,0=取消收藏,1=添加收藏"),
- db: AsyncSession = Depends(get_async_db),
- current_user: Union[Teacher, Student] = Depends(get_current_user)):
- # 判断资源类型
- if ctype not in RESOURCE_TYPES:
- return {"errcode": 400, "mess": "资源类型不存在!"}
- else:
- model = RESOURCE_MODES[ctype]
- crud = RESOURCE_CRUDS[ctype]
- # 判断资源是否存在
- db_obj = await crud.find_one(db, filters={"id": rid}, return_fields=["collect"])
- if not db_obj:
- return {"errcode": 404, "mess": "资源不存在!"}
- # 更新收藏量
- if opt.opt:
- collect_num = db_obj.collect + 1
- else:
- collect_num = db_obj.collect - 1
- stmt = (update(model).where(model.id == rid).values(collect=collect_num))
- await crud.execute_v2(db, stmt)
- # 写入收藏表
- utype = 1 if isinstance(current_user, Teacher) else 2
- if opt.opt:
- info = NewResourceCollect(rid=rid, ctype=ctype, uid=current_user.id, utype=utype)
- await crud_collection.insert_one(db, info)
- else:
- await crud_collection.delete(db,
- where_clauses={
- "rid": rid,
- "ctype": ctype,
- "uid": current_user.id,
- "utype": utype
- })
- return {"data": {"collect": collect_num}}
- async def preview_resource(rid: int = Path(..., description="资源ID"),
- ctype: str = Query(..., description="资源分类名称,exam/work"),
- db: AsyncSession = Depends(get_async_db),
- current_user: Union[Teacher, Student] = Depends(get_current_user)):
- # 判断资源类型
- if ctype not in RESOURCE_TYPES:
- return {"errcode": 400, "mess": "资源类型不存在!"}
- else:
- model = RESOURCE_MODES[ctype]
- crud = RESOURCE_CRUDS[ctype]
- # 判断资源是否存在
- db_obj = await crud.find_one(db, filters={"id": rid}, return_fields=["visit", "attach_url"])
- if not db_obj:
- return {"errcode": 400, "mess": "资源不存在!"}
- # 更新浏览量
- visit_num = db_obj.visit + 1
- stmt = (update(model).where(model.id == rid).values(visit=visit_num))
- await crud.execute_v2(db, stmt)
- # 向oss发起预览请求
- preview_url = ossfile_uploader.get_preview_url(db_obj.attach_url)
- return {"data": {"urls": [preview_url], "visit": visit_num}}
- async def get_collected_resource(page: int = 1,
- size: int = 10,
- name: str = "",
- ctype: str = Query(None, description="资源分类名称,exam/work"),
- db: AsyncSession = Depends(get_async_db),
- current_user: Union[Teacher, Student] = Depends(get_current_user)):
- # 判断资源类型
- if ctype and (ctype not in RESOURCE_TYPES):
- return {"errcode": 400, "mess": "资源类型不存在!"}
- # 筛选条件
- _q = {"uid": current_user.id, "utype": current_user.utype}
- if ctype:
- _q["ctype"] = ctype
- offset = (page - 1) * size
- total = 0 # 总数
- collect_info = {} # 收藏列表
- work_rids = [] # 作业资源
- exam_rids = [] # 考试资源
- return_fields = ["id", "ctype", "rid", "created_at"]
- _, db_collections = await crud_collection.find_all(db,
- filters=_q,
- return_fields=return_fields,
- limit=size,
- offset=offset)
- for item in db_collections:
- if item[1] == "work":
- work_rids.append(str(item.rid))
- else:
- exam_rids.append(str(item.rid))
- collect_info[f"{item.ctype}-{item.rid}"] = [item.id, item.created_at]
- # 分别查询作业资源和考试资源
- data = []
- return_fields = [
- "id", "name", "area", "year", "collect", "download", "visit", "category_id", "attach_url"
- ]
- for item in [(work_rids, "work"), (exam_rids, "exam")]:
- if not item[0]:
- continue
- model = RESOURCE_MODES[item[1]]
- crud = RESOURCE_CRUDS[item[1]]
- _q = [model.id.in_(item[0])]
- if name:
- _q.append(model.name.like(f"{name}%"))
- total, db_resources = await crud.find_all(db, filters=_q, return_fields=return_fields)
- for resource in db_resources:
- total += 1
- temp = {
- "cid": collect_info[f"{item[1]}-{resource.id}"][0],
- "rid": resource.id,
- "name": resource.name,
- "area": resource.area,
- "year": resource.year,
- "collect": resource.collect,
- "download": resource.download,
- "visit": resource.visit,
- "category_id": resource.category_id,
- "attach_url": resource.attach_url,
- "ctype": item[1],
- "created_at": collect_info[f"{item[1]}-{resource.id}"][1]
- }
- data.append(temp)
- data.sort(key=lambda x: x["created_at"], reverse=True)
- return {"data": data, "total": total}
|