#!/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 from sqlalchemy.ext.asyncio import AsyncSession from common.const import RESOURCE_TYPES from crud.resource import crud_work_resource, crud_exam_resource, crud_collect from models.resource import WorkResource, ExamResource 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 async def get_resources( page: int = 1, size: int = 10, name: str = "", year: int = 0, 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(None, 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": "资源类型不存在!"} now = datetime.datetime.now() # 筛选条件 filters = [] if name: filters.append(text(f"name LIKE '%{name}%'")) if year: filters.append(text(f"year = {year}")) if (ctype == "exam") and sid: filters.append(text(f"school_id = {sid}")) if ctgid: filters.append(text(f"category_id = {ctgid}")) if ctype and rtype: filters.append(text(f"rtype = '{rtype}'")) if hot: filters.append(text(f"hot = {hot}")) if isinstance(order, str): order = [text(order)] if isnew: start_time = now - datetime.timedelta(days=3) now_str = now.strftime("%Y-%m-%d %H:%M:%S") start_time_str = start_time.strftime("%Y-%m-%d %H:%M:%S") filters.append( text(f"created_at BETWEEN '{start_time_str}' AND '{now_str}'")) offset = (page - 1) * size # 查询 crud = crud_work_resource if ctype == "work" else crud_exam_resource total, items = await crud.find_all(db, filters=filters, offset=offset, limit=size, order_by=order) # 判断是否最新资源 for item in items: item.attach_url = item.attach_url.split(";") if (now - item.created_at).days <= 3: item.isnew = True else: item.isnew = False delattr(item, "attach_url") return {"data": items, "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": "资源类型不存在!"} # 查询 if ctype == "work": crud = crud_work_resource table = WorkResource else: crud = crud_exam_resource table = ExamResource item = await crud.find_one(db, filters={"id": rid}, return_fields=["download", "attach_url"]) # 更新下载量 download_num = item.download + 1 stmt = (update(table).where(table.id == rid).values(download=download_num)) await crud.increase(db, stmt) return { "data": { "urls": item.attach_url.split(";"), "download": download_num } } 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": "资源类型不存在!"} # 查询 if ctype == "work": crud = crud_work_resource table = WorkResource else: crud = crud_exam_resource table = ExamResource # 判断资源是否存在 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(table).where(table.id == rid).values(collect=collect_num)) await crud.increase(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_collect.insert_one(db, info) else: await crud_collect.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": "资源类型不存在!"} # 查询 if ctype == "work": crud = crud_work_resource table = WorkResource else: crud = crud_exam_resource table = ExamResource # 判断资源是否存在 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(table).where(table.id == rid).values(visit=visit_num)) await crud.increase(db, stmt) return {"data": {"urls": db_obj.attach_url.split(";"), "visit": visit_num}}