123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- import datetime
- import json
- from fastapi import Depends, Query, Path
- from fastapi.background import BackgroundTasks
- from sqlalchemy import desc, update, asc
- from sqlalchemy.ext.asyncio import AsyncSession
- from bgtask.marktask import bgtask_create_student_mark_task
- from bgtask.problem import bgtask_create_class_error_statistic
- from bgtask.tasks import bgtask_delete_student_task_question
- from crud.marktask import crud_task, crud_student_task
- from crud.paper import crud_paper
- from crud.resource import crud_work_category
- from crud.school.school import crud_school, crud_grade, crud_class
- from crud.user import crud_student
- from models.marktask import StudentMarkTask, MarkTask
- from models.user import Admin
- from schemas.base import ReturnField, OrderByField
- from schemas.paper import NewMarkTask, UpdateMarkTaskInfo, MarkTaskInDB, StdAnsConfigInfo
- from utils.depends import get_async_db, get_current_user
- async def create_mark_task(info: NewMarkTask,
- bgtask: BackgroundTasks,
- db: AsyncSession = Depends(get_async_db),
- current_user: Admin = Depends(get_current_user)):
- info_dict = info.dict(exclude_none=True)
- if not info_dict:
- return {"errcode": 400, "mess": "请求参数为空!"}
- # 如果是创建作业阅卷任务,必须选择试卷
- if info_dict["mtype"] == "work":
- if not info_dict.get("pid", None):
- return {"errcode": 400, "mess": "请选择试卷!"}
- else:
- db_paper = await crud_paper.find_one(db, filters={"id": info_dict["pid"]})
- info_dict["name"] = db_paper.name
- info_dict["pno"] = db_paper.pno
- info_dict["pname"] = db_paper.name
- info_dict["pages"] = db_paper.pages
- info_dict["stdans_config"] = json.dumps({
- "std_x_list": db_paper.std_x_list,
- "std_y_list": db_paper.std_y_list
- })
- info_dict["ans_points"] = json.dumps(db_paper.ans_points)
- info_dict["std_points"] = json.dumps(db_paper.points)
- info_dict["category_id"] = db_paper.category_id
- info_dict["subject"] = db_paper.subject
- # 查询分类的科目
- db_category = await crud_work_category.find_one(db,
- filters={"id": db_paper.category_id},
- return_fields=["subject"])
- if db_category:
- info_dict["subject"] = db_category.subject
- # 试卷信息
- paper = {
- "id": db_paper.id,
- "pno": db_paper.pno,
- "pname": db_paper.name,
- "imgs": db_paper.imgs,
- "question_amount": db_paper.question_amount
- }
- else:
- if not info_dict.get("pid", None):
- return {"errcode": 400, "mess": "请选择试卷!"}
- db_paper = await crud_paper.find_one(db, filters={"id": info_dict["pid"]})
- info_dict["name"] = db_paper.name
- info_dict["pno"] = db_paper.pno
- info_dict["pname"] = db_paper.name
- info_dict["pages"] = db_paper.pages
- info_dict["stdans_config"] = json.dumps({
- "std_x_list": db_paper.std_x_list,
- "std_y_list": db_paper.std_y_list
- })
- info_dict["ans_points"] = json.dumps(db_paper.ans_points)
- info_dict["std_points"] = json.dumps(db_paper.points)
- info_dict["category_id"] = db_paper.category_id
- info_dict["subject"] = db_paper.subject
- # 查询分类的科目
- db_category = await crud_work_category.find_one(db,
- filters={"id": db_paper.category_id},
- return_fields=["subject"])
- if db_category:
- info_dict["subject"] = db_category.subject
- # 试卷信息
- paper = {
- "id": db_paper.id,
- "pno": db_paper.pno,
- "pname": db_paper.name,
- "imgs": db_paper.imgs,
- "question_amount": db_paper.question_amount
- }
- # 查询关联对象,组装阅卷任务对象,并写入数据库
- db_school = await crud_school.find_one(db, filters={"id": info_dict["school_id"]})
- db_grade = await crud_grade.find_one(db, filters={"id": info_dict["grade_id"]})
- db_class = await crud_class.find_one(db, filters={"id": info_dict["class_id"]})
- # 阅卷任务参数
- info_dict["year"] = datetime.date.today().year
- info_dict["school_name"] = db_school.name
- info_dict["grade_name"] = db_grade.name
- info_dict["class_name"] = db_class.name
- info_dict["student_amount"] = db_class.student_amount
- info_dict["creator_id"] = info_dict["editor_id"] = current_user.id
- info_dict["creator_name"] = info_dict["editor_name"] = current_user.username
- info_dict["pimgs"] = json.dumps(info_dict["pimgs"])
- obj_in = MarkTaskInDB(**info_dict)
- db_task = await crud_task.insert_one(db, obj_in)
- # 查询班级所有学生
- _, students = await crud_student.find_all(db,
- filters={"class_id": db_class.id},
- return_fields=[
- "id", "sno", "name", "school_id", "grade_id",
- "class_id", "school_name", "grade_name",
- "class_name"
- ])
- # 异步生成每个学生的阅卷任务
- bgtask.add_task(bgtask_create_student_mark_task, db_task.id, db_task.mtype, students, paper,
- current_user.id, current_user.name)
- # 创建本次阅卷任务的错题记录
- bgtask.add_task(bgtask_create_class_error_statistic, db_school.id, db_grade.id, db_task.id,
- db_task.name, db_task.mtype, db_class.id, db_class.student_amount, paper["id"],
- db_school.name, db_grade.name, db_class.name)
- return {"data": db_task}
- async def update_mark_task(info: UpdateMarkTaskInfo,
- tid: int = Path(..., description="阅卷任务ID"),
- db: AsyncSession = Depends(get_async_db),
- current_user: Admin = Depends(get_current_user)):
- info_dict = info.dict(exclude_none=True)
- if not info_dict:
- return {"errcode": 400, "mess": "请求参数为空!"}
- # 查询阅卷任务是否存在
- db_task = await crud_task.find_one(db, filters={"id": tid})
- if not db_task:
- return {"errcode": 400, "mess": "阅卷任务不存在!"}
- # 判断学校是否更新
- if ("school_id" in info_dict) and (info_dict["school_id"] != db_task.school_id):
- db_school = await crud_school.find_one(db, filters={"id": info_dict["school_id"]})
- if not db_school:
- return {"errcode": 404, "mess": "学校不存在!"}
- info_dict["school_name"] = db_school.name
- # 判断年级是否更新
- if ("grade_id" in info_dict) and (info_dict["grade_id"] != db_task.grade_id):
- db_grade = await crud_grade.find_one(db, filters={"id": info_dict["grade_id"]})
- if not db_grade:
- return {"errcode": 404, "mess": "年级不存在!"}
- info_dict["grade_name"] = db_grade.name
- # 判断班级是否更新
- if ("class_id" in info_dict) and (info_dict["class_id"] != db_task.class_id):
- db_class = await crud_class.find_one(db, filters={"id": info_dict["class_id"]})
- if not db_class:
- return {"errcode": 404, "mess": "班级不存在!"}
- info_dict["class_name"] = db_class.name
- info_dict["student_amount"] = db_class.student_amount
- # 判断试卷是否更新
- if ("pid" in info_dict) and (info_dict["pid"] != db_task.pid):
- db_paper = await crud_paper.find_one(db, filters={"id": info_dict["pid"]})
- if not db_paper:
- return {"errcode": 404, "mess": "试卷不存在!"}
- info_dict["pno"] = db_paper.pno
- info_dict["pname"] = db_paper.name
- # 更新
- info_dict["editor_id"] = current_user.id
- info_dict["editor_name"] = current_user.username
- db_task = await crud_task.update(db, db_task, info)
- # 更新student_task
- if ("pid" in info_dict) and (info_dict["pid"] != db_task.pid):
- stmt = (update(StudentMarkTask).where(StudentMarkTask.task_id == db_task.id).values(
- pid=db_task.pid, pno=db_task.pno, pname=db_task.pname))
- await crud_student_task.execute_v2(db, stmt)
- return {"data": db_task}
- async def delete_mark_task(bgtask: BackgroundTasks,
- tid: int = Path(..., description="阅卷任务ID"),
- db: AsyncSession = Depends(get_async_db),
- current_user: Admin = Depends(get_current_user)):
- existed = await crud_task.count(db, filters={"id": tid})
- if not existed:
- return {"errcode": 400, "mess": "阅卷任务不存在!"}
- await crud_task.delete(db, obj_id=tid)
- # 删除学生阅卷任务
- bgtask.add_task(bgtask_delete_student_task_question, tid)
- return {"data": None}
- async def get_mark_task(tid: int = Path(..., description="阅卷任务ID"),
- db: AsyncSession = Depends(get_async_db),
- current_user: Admin = Depends(get_current_user)):
- db_exist = await crud_task.find_one(db, filters={"id": tid})
- if not db_exist:
- return {"errcode": 400, "mess": "角色不存在!"}
- # 获取阅卷任务的学生
- students = await crud_student_task.fetch_all(db,
- filters={"task_id": db_exist.id},
- order_by=[desc("status")])
- db_exist.students = students
- cur_students = await crud_student_task.find_one(db,
- filters={
- "task_id": db_exist.id,
- "status": 1
- })
- cur_imgs = cur_students.pimgs if cur_students else []
- db_exist.cur_imgs = cur_imgs
- db_exist.total = len(students)
- # 已完成上传
- finish_students = filter(lambda x: x.pimgs, students)
- db_exist.finish = len(list(finish_students))
- db_exist.ftp_path = f"T{db_exist.id}-{db_exist.pno}"
- db_exist.stdans_config = json.loads(db_exist.stdans_config) if db_exist.stdans_config else {}
- return {"data": db_exist}
- async def get_mark_tasks(page: int = 1,
- size: int = 10,
- name: str = "",
- year: int = 0,
- status: int = 0,
- mtype: str = "",
- order: OrderByField = Query(
- "-created_at", description="排序字段,用逗号分隔,升降序以-判断,默认-created_at"),
- res: ReturnField = Query("", description="控制返回字段,字段逗号分隔"),
- db: AsyncSession = Depends(get_async_db),
- current_user: Admin = Depends(get_current_user)):
- _q = []
- if name:
- _q.append(MarkTask.name.like(f"{name}%"))
- if year:
- _q.append(MarkTask.year == year)
- if status:
- _q.append(MarkTask.status == status)
- if mtype:
- _q.append(MarkTask.mtype == mtype)
- # 排序
- order_fields = []
- if order:
- for x in order.split(","):
- field = x.strip()
- if field:
- if field.startswith("-"):
- order_fields.append(desc(getattr(MarkTask, field[1:])))
- else:
- order_fields.append(asc(getattr(MarkTask, field)))
- # 查询
- total, db_tasks = await crud_task.find_all(db,
- filters=_q,
- offset=(page - 1) * size,
- limit=size,
- order_by=order_fields,
- return_fields=res)
- return {"total": total, "data": db_tasks}
- async def update_stdans_config(info: StdAnsConfigInfo,
- tid: int = Path(..., description="阅卷任务ID"),
- db: AsyncSession = Depends(get_async_db),
- current_user: Admin = Depends(get_current_user)):
- info_dict = info.dict(exclude_none=True)
- if not info_dict:
- return {"errcode": 400, "mess": "请求参数为空!"}
- # 查询阅卷任务是否存在
- db_task = await crud_task.find_one(db, filters={"id": tid})
- info_dict["stdans_config"] = json.dumps(info_dict["stdans_config"])
- if not db_task:
- return {"errcode": 400, "mess": "阅卷任务不存在!"}
- db_task = await crud_task.update(db, db_task, info_dict)
- return {"data": db_task}
|