exam_service/mooc/api/v1/endpoints/wxapp.py
jieyuu 1f91ddc1db feat(crud): part3基础实现
- 为 Cdkey、Exercise、Gift、Paper、Test 等模型添加了多个新的查询方法
2025-02-28 23:22:23 +08:00

1766 lines
62 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import copy
import html
import math
import re
from datetime import datetime
from typing import Optional, Dict, Any, List
import phpserialize
from fastapi import APIRouter, Depends, Request
from pydantic import BaseModel
from sqlalchemy.orm import Session
from mooc.crud.crud_goouc_fullexam import (
CRUDSetting,
CRUDGift,
CRUDPaper,
CRUDPaperTest,
CRUDCdkeys,
CRUDCdkey,
CRUDXueshen,
CRUDTestType,
CRUDTest,
CRUDSonSimple,
CRUDExercise
)
from mooc.crud.crud_goouc_fullexam_user import (
CRUDUserDoexam,
CRUDUserExamAnswer,
CRUDUserWrongPraction,
CRUDUserCollectionPraction,
CRUDUserGift,
CRUDUser,
CRUDUserDoOtherExam,
CRUDUserPool,
CRUDUserMember,
CRUDUserSequence,
CRUDUserSpecial,
CRUDUserQtype
)
from mooc.db.database import get_db
from mooc.models.goouc_fullexam import (
Setting,
Gift,
Paper,
Cdkeys, Cdkey,
Test,
SonSimple,
Exercise, Xuesheng, TestType, PaperTest
)
from mooc.models.goouc_fullexam_user import (
UserDoexam,
UserExamAnswer,
UserWrongPraction,
UserCollectionPraction,
User,
UserGift,
UserDootherExam,
UserPool,
UserSpecial, UserMember, UserSequence, UserQtype
)
from mooc.schemas.goouc_fullexam import (
GiftResponse
)
wxapp_router = APIRouter()
class WxappRequest(BaseModel):
uid: Optional[str] = None
op: Optional[str] = None
m: Optional[str] = None
data: Dict[str, Any] = {}
@wxapp_router.post("/index")
async def handle_wxapp_request(
request: Request,
i: str,
t: Optional[str] = None,
v: Optional[str] = None,
c: Optional[str] = "entry",
a: Optional[str] = "wxapp",
do: Optional[str] = None,
db: Session = Depends(get_db)
):
# 获取表单数据
try:
form_data = await request.form()
print("Form data:", form_data)
# 将表单数据转换为字典
data = dict(form_data)
except Exception as e:
print("Error reading form data:", e)
# 如果没有表单数据尝试读取JSON
try:
data = await request.json()
print("JSON data:", data)
except Exception as e:
print("Error reading JSON:", e)
data = {}
print("Final data:", data)
print("Query params:", request.query_params)
# 初始化CRUD操作类传入对应的模型
user_doexam = CRUDUserDoexam(UserDoexam)
user_exam_answer = CRUDUserExamAnswer(UserExamAnswer)
user_wrong_praction = CRUDUserWrongPraction(UserWrongPraction)
user_collection = CRUDUserCollectionPraction(UserCollectionPraction)
user_mapper = CRUDUser(User)
user_gift_mapper = CRUDUserGift(UserGift)
setting_mapper = CRUDSetting(Setting)
gift_mapper = CRUDGift(Gift)
user_do_other_exam_mapper = CRUDUserDoOtherExam(UserDootherExam)
paper_mapper = CRUDPaper(Paper)
user_pool_mapper = CRUDUserPool(UserPool)
cdkeys_mapper = CRUDCdkeys(Cdkeys)
cdkey_mapper = CRUDCdkey(Cdkey)
user_member_mapper = CRUDUserMember(UserMember)
test_mapper = CRUDTest(Test)
xueshen_mapper = CRUDXueshen(Xuesheng)
user_sequence_mapper = CRUDUserSequence(UserSequence)
user_pool_mapper = CRUDUserPool(UserPool)
test_type_mapper = CRUDTestType(TestType)
users_special_mapper = CRUDUserSpecial(UserSpecial)
user_qtype_mapper = CRUDUserQtype(UserQtype)
son_simple_mapper = CRUDSonSimple(SonSimple)
exercise_mapper = CRUDExercise(Exercise)
paper_test_mapper = CRUDPaperTest(PaperTest)
# 根据do参数处理不同的业务逻辑
if do == "Setuserinfo":
return await handle_user_info(WxappRequest(**data), db)
elif do == "ExamOperation":
return await handle_exam_operation(WxappRequest(**data), db, user_doexam, user_exam_answer)
elif do == "Collection":
return await handle_collection(WxappRequest(**data), db, user_collection)
elif do == "WrongQuestion":
return await handle_wrong_question(WxappRequest(**data), db, user_wrong_praction)
elif do == "TotalqNum":
# 添加新的处理逻辑
return {"code": 0, "data": {"total": 100}, "msg": "success"}
elif do == "Index":
# 添加首页处理逻辑
return {"code": 0, "data": {}, "msg": "success"}
elif do == "Advert":
# 添加广告处理逻辑
return {"code": 0, "data": [], "msg": "success"}
# part 3
elif do == "ExchangeGiftList":
return await handle_exchange_gift_list(WxappRequest(**data), i, db, user_gift_mapper, gift_mapper)
elif do == "Aboutus":
return await handle_about_us(WxappRequest(**data), i, db, setting_mapper)
elif do == "Mockexam":
return await MockExam(WxappRequest(**data), db, i, user_mapper, setting_mapper, xueshen_mapper,
test_type_mapper, test_mapper, user_pool_mapper, cdkey_mapper, cdkeys_mapper,
paper_test_mapper, paper_mapper, user_exam_answer)
elif do == "PreExamInfo":
return await per_exam_info(WxappRequest(**data), i, db, setting_mapper, user_doexam, user_mapper,
user_do_other_exam_mapper)
elif do == "GetExamList":
return await get_exam_list(WxappRequest(**data), i, db, paper_mapper, paper_test_mapper, user_pool_mapper,
cdkeys_mapper, user_member_mapper, cdkey_mapper, user_doexam, test_mapper,
user_mapper)
elif do == "Sequence":
return await handle_sequence(WxappRequest(**data), db, i, user_mapper, xueshen_mapper, user_sequence_mapper,
test_mapper, setting_mapper, user_pool_mapper, test_type_mapper,
users_special_mapper, cdkeys_mapper,
cdkey_mapper, user_member_mapper, user_collection, user_qtype_mapper,
son_simple_mapper,
exercise_mapper, user_exam_answer, user_wrong_praction)
elif do == "TotalqNum":
return await TotalqNum(WxappRequest(**data), db, i, user_mapper, user_sequence_mapper, xueshen_mapper,
test_type_mapper, user_pool_mapper, test_mapper)
return {"code": 404, "msg": "接口未找到"}
async def handle_user_info(data: WxappRequest, db: Session):
"""处理用户信息相关操作"""
operations = {
"getinfo": get_user_info,
"update": update_user_info,
"bind": bind_user,
"unbind": unbind_user,
}
operation = operations.get(data.op)
if not operation:
return {
"code": 1,
"msg": f"Unsupported operation: {data.op}"
}
try:
result = await operation(data.uid, data.data, db)
return {
"code": 0,
"data": result,
"msg": "success"
}
except Exception as e:
return {
"code": 1,
"msg": str(e)
}
async def handle_exam_operation(
data: WxappRequest,
db: Session,
user_doexam: CRUDUserDoexam,
user_exam_answer: CRUDUserExamAnswer
):
"""处理考试相关操作"""
operations = {
"submit": submit_exam,
"get_history": get_exam_history,
"get_detail": get_exam_detail,
}
operation = operations.get(data.op)
if not operation:
return {
"code": 1,
"msg": f"Unsupported operation: {data.op}"
}
try:
result = await operation(data.uid, data.data, db, user_doexam, user_exam_answer)
return {
"code": 0,
"data": result,
"msg": "success"
}
except Exception as e:
return {
"code": 1,
"msg": str(e)
}
async def handle_collection(
data: WxappRequest,
db: Session,
user_collection: CRUDUserCollectionPraction
):
"""处理收藏相关操作"""
operations = {
"add": add_collection,
"remove": remove_collection,
"list": list_collections,
}
operation = operations.get(data.op)
if not operation:
return {
"code": 1,
"msg": f"Unsupported operation: {data.op}"
}
try:
result = await operation(data.uid, data.data, db, user_collection)
return {
"code": 0,
"data": result,
"msg": "success"
}
except Exception as e:
return {
"code": 1,
"msg": str(e)
}
async def handle_wrong_question(
data: WxappRequest,
db: Session,
user_wrong_praction: CRUDUserWrongPraction
):
"""处理错题相关操作"""
operations = {
"add": add_wrong_question,
"remove": remove_wrong_question,
"list": list_wrong_questions,
}
operation = operations.get(data.op)
if not operation:
return {
"code": 1,
"msg": f"Unsupported operation: {data.op}"
}
try:
result = await operation(data.uid, data.data, db, user_wrong_praction)
return {
"code": 0,
"data": result,
"msg": "success"
}
except Exception as e:
return {
"code": 1,
"msg": str(e)
}
async def handle_sequence(data: WxappRequest, db: Session, uniacid: str, user_mapper: CRUDUser,
xueshen_mapper: CRUDXueshen,
user_sequence_mapper: CRUDUserSequence,
test_mapper: CRUDTest,
setting_mapper: CRUDSetting,
user_pool_mapper: CRUDUserPool, test_type_mapper: CRUDTestType,
users_special_mapper: CRUDUserSpecial, cdkeys_mapper: CRUDCdkeys, cdkey_mapper: CRUDCdkey,
user_member_mapper: CRUDUserMember, user_collect_praction_mapper: CRUDUserCollectionPraction,
user_qtype_mapper: CRUDUserQtype, son_simple_mapper: CRUDSonSimple,
exercise_mapper: CRUDExercise, user_do_exam_mapper: CRUDUserDoexam,
user_exam_answer_mapper: CRUDUserExamAnswer,
user_wrong_praction_mapper: CRUDUserWrongPraction):
uid = data.uid
op = data.op
if uid is None:
return {"code": 1, "msg": "传递的参数不存在或失效", "data": "1001"}
user_info = user_mapper.get_user_info(db, uid, uniacid)
if user_info is None:
return {"code": 1, "msg": "用户不存在", "data": "1002"}
if user_info.status != 1:
return {"code": 1, "msg": "用户被禁用", "data": "1003"}
is_student = xueshen_mapper.get_xuesheng_id(db, uniacid, user_info.name, user_info.phone)
freepool = []
lib_id = data.data["lib_id"]
if op == "sequence":
last_id = user_sequence_mapper.get_last_id(db, uniacid, uid, lib_id)
question_list = test_mapper.get_question_list(db, uniacid, lib_id, 1, 9, 1)
total_qnum = len(question_list)
last_id = int(last_id)
if total_qnum < last_id:
last_id = total_qnum - 1
elif last_id == total_qnum - 1:
last_id = 0
if question_list is not None:
for question in question_list:
is_collect = user_collect_praction_mapper.get_is_collect(db, uniacid, uid, question["id"],
question["type"])
if is_collect is not None:
question["wrong_have"] = 1
else:
question["wrong_have"] = 2
question_list = Makeformat(db=db, itembank=question_list, uniacid=int(uniacid))
return {"code": 0,
"msg": "顺序练习试题,总题数,上次练习试题ID",
"data": {"list": question_list,
"total_qnum": total_qnum,
"last_id": last_id
}
}
else:
return {"code": 0, "msg": "暂无顺序练习试题数据", "data": {"list": [], "total_qnum": 0, "have": 2}}
elif op == "randoms":
question_list = test_mapper.get_randon_question_list(db, uniacid, lib_id, 9, 1, 1)
total_qnum = len(question_list)
if question_list is not None:
for question in question_list:
is_collect = user_collect_praction_mapper.get_is_collect(db, uniacid, uid, question["id"],
question["type"])
if is_collect is not None:
question["wrong_have"] = 1
else:
question["wrong_have"] = 2
question_list = Makeformat(question_list)
return {"code": 0,
"msg": "随机练习试题,总题数",
"data": {"list": question_list,
"total_qnum": total_qnum
}
}
else:
return {"code": 0, "msg": "暂无随机练习试题数据", "data": {"list": [], "total_qnum": 0, "have": 2}}
elif op == "getallspecial":
pay_open = setting_mapper.get_setting_by_weid(db, uniacid).pay_open
freepoolnum = setting_mapper.get_setting_by_weid(db, uniacid).freepoolnum
if is_student is not None:
test_type_list = test_type_mapper.get_all_special_if_is_student(db, uniacid, uid)
else:
test_type_list = test_type_mapper.get_all_special_without_is_student(db, uniacid, uid)
if test_type_list is not None and len(test_type_list) > 0:
for test_type in test_type_list:
son = test_type_mapper.get_son_by_pid(db, uniacid, test_type["id"], 1, 1)
if son is not None:
for v in son:
v["is_can"] = 0
if v["price"] > 0:
kid = user_pool_mapper.get_kid_id_by_poolid(db, uniacid, uid, v["id"])
if kid is not None:
v["is_can"] = 1
else:
v["is_can"] = 1
z_vip = user_member_mapper.get_by_field(db, "weid", int(uniacid))
v["vip_price"] = v["price"] * z_vip.scale
v["vip_price"] = round(v["vip_price"], 2)
is_member = user_mapper.get_user_is_member(db, uniacid, uid)
if is_member is not None and is_member["ismember"] == 1 and v["vip_price"] <= 0:
v["is_can"] = 1
now_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
cdkeys = cdkeys_mapper.get_code_id_list_by_kpool_id_and_type(db, uniacid, v["id"], 2)
if cdkeys is not None and len(cdkeys) > 0:
active = cdkey_mapper.get_user_active(db, uniacid, uid, now_time, cdkeys)
if active is not None:
v["is_can"] = 1
vson = test_type_mapper.get_son_by_pid(db, uniacid, v["id"], 1, 1)
if vson is not None and len(vson) > 0:
for k in vson:
is_can = 0
if v["is_can"] == 1:
is_can = 1
else:
if k["id"] < 1:
is_can = 1
k["is_can"] = is_can
v["son"] = copy.deepcopy(vson)
test_type["son"] = copy.deepcopy(son)
return {"code": 0,
"msg": "获取专项",
"data": {"list": test_type_list,
"pay_open": pay_open,
"freenum": freepoolnum
}
}
elif op == "special":
special_id = int(data.data["typeId"])
pid = test_type_mapper.get_test_type_by_special_id(db, uniacid, special_id)
pool = test_type_mapper.get_pool_by_id(db, uniacid, pid)
is_can = 0
if pool["price"] <= 0:
is_can = 1
else:
kid_id = user_pool_mapper.get_kid_id_by_poolid(db, uniacid, uid, pool["id"])
if kid_id is not None:
is_can = 1
if is_can == 1:
question_list = test_mapper.get_question_list(db, uniacid, special_id, 1, 9, 1)
total_qnum = len(question_list)
else:
freepoolnum = setting_mapper.get_setting_by_weid(db, uniacid).freepoolnum
question_list = test_mapper.get_question_list_with_limit(db, uniacid, special_id, 1, 9, 1, freepoolnum)
total_qnum = len(question_list)
last_id = users_special_mapper.get_last_id_by_special_id(db, uniacid, uid, special_id)
last_id = int(last_id)
if last_id is not None and total_qnum <= last_id:
last_id = total_qnum - 1
elif last_id == total_qnum - 1:
last_id = 0
if question_list is not None and len(question_list) > 0:
for question in question_list:
is_collect = user_collect_praction_mapper.get_is_collect(db, uniacid, uid, question["id"],
question["type"])
if is_collect is not None and is_collect != 0:
question["wrong_have"] = 1
else:
question["wrong_have"] = 2
question_list = Makeformat(db=db, itembank=question_list, uniacid=int(uniacid))
return {"code": 0, "msg": "知识点专项练习试题,总题数,进度下标",
"data": {"list": question_list, "total_qnum": total_qnum, "last_id": last_id}}
else:
return {"code": 0, "msg": "暂无该知识点试题数据", "data": {"list": [], "total_qnum": 0, "last_id": 0}}
elif op == "getalltypes":
type_list = []
type_list.insert(1, "单选题")
type_list.insert(2, "多选题")
type_list.insert(3, "判断题")
type_list.insert(4, "填空题")
type_list.insert(5, "语音题")
type_list.insert(6, "完形填空")
type_list.insert(7, "阅读理解")
type_list.insert(8, "简答题")
typelist = []
for index, value in enumerate(type_list):
if index == 5:
q_have = test_mapper.get_q_have_by_type_and_lib_id(db, uniacid, index, lib_id, 1, 1, 1)
if q_have == 0:
continue
else:
# 没有son
q_have = test_mapper.get_q_have_by_type_and_lib_id(db, uniacid, index, lib_id, 1, None, 1)
if q_have == 0:
continue
typelist.append({"id": index, "name": value})
type_list_t = son_simple_mapper.get_type_list(db, uniacid)
if type_list is not None and len(type_list) > 0:
son = 2
if type_list_t is not None and len(type_list_t) > 0:
son = 1
return {
"code": 0,
"msg": "获取题型",
"data": {
"type_list": type_list,
"son": son
}
}
else:
return {
"code": 0,
"msg": "暂无题型",
"data": {
"type_list": [],
"son": 2
}
}
elif op == "getallsimple":
psize = 20
pindex = max(1, data.data["page"])
type_list_t = son_simple_mapper.get_type_list_page(db, uniacid, pindex, psize)
total = son_simple_mapper.get_total(db, uniacid)
total = len(total) + 1
# todo 后续验证
# if (!empty($type_list_t)) {
# foreach($type_list as $key = > $value) {
# array_unshift($type_list_t, $value);
# }
# foreach($type_list_t as $k = > $v) {
# $type_list_t[$k]["son_title"] = $v["son_title"];
# }
# }
# 将 type_list 中的每个元素插入到 type_list_t 的开头
# 定义 type_list
type_list = [{"id": "0", "son_title": "简答题"}]
# 将 type_list 中的每个元素插入到 type_list_t 的开头
type_list_t = type_list + type_list_t
if type_list_t is not None and len(type_list_t) > 0:
return {
"code": 0,
"msg": "获取题型",
"data": {
"type_list": type_list_t,
"total": total,
"psize": psize,
}
}
else:
return {
"code": 0,
"msg": "暂无题型",
"data": {
"type_list": [],
}
}
elif op == "qtype":
if data.data["typeId"] is None or uid is None:
return {
"code": 1,
"msg": "传递的参数不存在或失效",
"data": "1009",
}
qtype = int(data.data["typeId"])
uid = int(uid)
last_id = user_qtype_mapper.get_last_id_by_type_id_and_uid(db, uniacid, uid, qtype, 1)
question_list = test_mapper.get_qtye_question_list(db, uniacid, 1, qtype, 1, lib_id)
total_qnum = len(question_list)
last_id = int(last_id)
if total_qnum <= last_id:
last_id = total_qnum - 1
elif last_id == total_qnum - 1:
last_id = 0
if question_list is not None and len(question_list) > 0:
for question in question_list:
is_collect = user_collect_praction_mapper.get_is_collect(db, uniacid, uid, question["id"],
question["type"])
if is_collect:
question["wrong_have"] = 1
else:
question["wrong_have"] = 2
question_list = Makeformat(question_list)
return {
"code": 0,
"msg": "题型练习试题,总题数",
"data": {
"list": question_list,
"total_qnum": total_qnum,
"last_id": last_id,
},
}
else:
return {
"code": 0,
"msg": "暂无该题型试题数据",
"data": {
"list": [],
"total_qnum": 0,
"have": 2,
},
}
elif op == "simple_type":
if data.data["qtype"] is None or uid is None:
return {
"code": 1,
"msg": "传递的参数不存在或失效",
"data": "1009",
}
qtype = int(data.data["qtype"])
son_type = int(data.data["son_type"])
last_id = user_qtype_mapper.get_last_id_by_type_id_and_uid(db, uniacid, uid, qtype, 1)
question_list = test_mapper.get_question_list_by_son_type(db, uniacid, qtype, lib_id, 1, son_type, 1)
total_qnum = len(question_list)
last_id = int(last_id)
if total_qnum <= last_id:
last_id = total_qnum - 1
elif last_id == total_qnum - 1:
last_id = 0
if question_list is not None and len(question_list) > 0:
for question in question_list:
is_collect = user_collect_praction_mapper.get_is_collect(db, uniacid, uid, question["id"],
question["type"])
if is_collect is not None:
question["wrong_have"] = 1
else:
question["wrong_have"] = 2
pass
question_list = Makeformat(question_list)
return {
"code": 0,
"msg": "题型练习试题,总题数",
"data": {"list": question_list, "total_qnum": total_qnum, "last_id": last_id}}
else:
return {
"code": 0,
"msg": "暂无该题型试题数据",
"data": {
"list": [],
"total_qnum": 0,
"have": 2,
},
}
elif op == "notdone":
testid_arr = exercise_mapper.get_testid_list(db, uniacid, uid)
newid_arr = []
if testid_arr is not None and len(testid_arr) > 0:
for testid in testid_arr:
newid_arr.append(testid["testid"])
# 把newid_arr传进去
question_list = test_mapper.get_question_list(db, uniacid, lib_id, 1, 8, 1)
if question_list is not None and len(question_list) > 0:
for question in question_list:
if question["type"] == 5:
son_list = test_mapper.get_testson_by_pid(db, uniacid, question["id"])
for son in son_list:
have_do = exercise_mapper.get_exercise_have_do(db, uniacid, uid, son.id)
if have_do is not None:
question_list.remove(question)
break
if question_list is not None and len(question_list) > 0:
for question in question_list:
is_collect = user_collect_praction_mapper.get_is_collect(db, uniacid, uid, question["id"],
question["type"])
if is_collect is not None:
question["wrong_have"] = 1
else:
question["wrong_have"] = 2
question_list = Makeformat(question_list)
have = 1
else:
question_list = []
have = 2
total_qnum = len(question_list)
return {
"code": 0,
"msg": "未做练习试题,总题数",
"data": {"list": question_list, "total_qnum": total_qnum, "have": have}
}
else:
return {
"code": 0,
"msg": "暂无未做练习试题",
"data": {
"list": [],
"total_qnum": 0,
"have": 2,
},
}
else:
question_list = test_mapper.get_question_list(db, uniacid, lib_id, 1, 8, 1)
if question_list is not None and len(question_list) > 0:
for question in question_list:
is_collect = user_collect_praction_mapper.get_is_collect(db, uniacid, uid, question["id"],
question["type"])
if is_collect is not None:
question["wrong_have"] = 1
else:
question["wrong_have"] = 2
question_list = Makeformat(db=db, itembank=question_list, uniacid=int(uniacid))
have = 1
total_qnum = len(question_list)
return {
"code": 0,
"msg": "未做练习试题,总题数",
"data": {"list": question_list, "total_qnum": total_qnum, "have": have}
}
else:
return {
"code": 0,
"msg": "暂无未做练习试题",
"data": {
"list": [],
"total_qnum": 0,
"have": 2,
},
}
elif op == "todayerr_question":
# 获取当前日期的开始时间戳00:00:00
# 获取当前日期
current_date = datetime.now().date() # 返回一个 date 对象,格式为 YYYY-MM-DD
# 将日期转换为时间戳Unix 时间戳)
start = datetime.combine(current_date, datetime.min.time()).timestamp()
id_list = user_wrong_praction_mapper.get_id_list_with_time(db, uniacid, uid, int(start))
err_id_list = user_wrong_praction_mapper.get_err_id_list_order_by_createtime(db, uniacid, uid)
if id_list is None or len(id_list) == 0:
return {
"code": 1,
"msg": "今日暂无错题",
"data": "1004"
}
else:
err_list = []
errid_list = []
for id in err_id_list:
if id["test_type"] > 4:
pid = test_mapper.get_pid_by_id(db, uniacid, id["testid"])
if pid not in errid_list:
errid_list.append(pid)
temp = test_mapper.get_question(db, uniacid, pid)
if temp is not None:
err_list.append(temp)
else:
temp = test_mapper.get_err_list_order_by_id(db, uniacid, id["testid"])
if temp is not None:
err_list.append(temp)
for err in err_list:
is_collect = user_collect_praction_mapper.get_is_collect(db, uniacid, uid, err["id"], err["type"])
if is_collect is not None:
err["wrong_have"] = 1
else:
err["wrong_have"] = 2
err_list = Makeformat(err_list)
total = len(err_list)
return {
"code": 0,
"msg": "今日错题",
"data": {"list": err_list, "total": total}
}
elif op == "allerr_question":
err_id_list = user_wrong_praction_mapper.get_err_id_list_order_by_createtime(db, uniacid, uid)
if err_id_list is None or len(err_id_list) <= 0:
return {
"code": 1,
"msg": "暂无错题",
"data": "1004"
}
err_list = []
errid_list = []
for err_id in err_id_list:
if err_id["test_type"] > 4:
pid = test_mapper.get_pid_by_id(db, uniacid, err_id["testid"])
if pid not in errid_list:
errid_list.append(pid)
temp = test_mapper.get_question(db, uniacid, pid)
if temp is not None:
err_list.append(temp)
else:
temp = test_mapper.get_question(db, uniacid, err_id["testid"])
if temp is not None:
err_list.append(temp)
for err in err_list:
is_collect = user_collect_praction_mapper.get_is_collect(db, uniacid, uid, err["id"], err["type"])
if is_collect is not None:
err["wrong_have"] = 1
else:
err["wrong_have"] = 2
err_list = Makeformat(db=db, itembank=err_list, uniacid=int(uniacid))
return {
"code": 0,
"msg": "全部错题",
"data": {"list": err_list}
}
elif op == "geterr_bytype":
typeId = int(data.data["typeId"])
id_arr = []
user_wrong_praction_mapper.get_id_list_order_by_createtime(db, uniacid, uid, typeId)
if id_arr is None or len(id_arr) <= 0:
return {
"code": 0,
"msg": "暂无该题型错题",
"data": "1005"
}
err_list = []
errid_list = []
for id in id_arr:
if id["test_type"] > 4:
pid = test_mapper.get_pid_by_id(db, uniacid, id["testid"])
if pid not in errid_list:
errid_list.append(pid)
temp = test_mapper.get_question(db, uniacid, pid)
if temp is not None:
err_list.append(temp)
else:
temp = test_mapper.get_question(db, uniacid, id["testid"])
if temp is not None:
err_list.append(temp)
for err in err_list:
is_collect = user_collect_praction_mapper.get_is_collect(db, uniacid, uid, err["id"], err["type"])
if is_collect is not None:
err["wrong_have"] = 1
else:
err["wrong_have"] = 2
err_list = Makeformat(err_list)
total = len(err_list)
return {
"code": 0,
"msg": "该题型错题列表,总数",
"data": {"list": err_list, "total": total}
}
elif op == "seeErr":
if data.data["paperid"] is None or uid is None:
return {"code": 1, "msg": "传递的参数不存在", "data": {"code": "1001"}}
paperid = int(data.data["paperid"])
uid = int(uid)
record_id = user_do_exam_mapper.get_user_recordid(db, uniacid, uid, paperid)
answer_list = user_exam_answer_mapper.get_user_exam_answer(db, uniacid, uid, paperid, record_id)
err_list = []
errid_list = []
# 拷贝
err_id_list = copy.deepcopy(answer_list)
for err_id in err_id_list:
if err_id["test_type"] > 4 and err_id["test_type"] < 8:
pid = 0
test_mapper.get_pid_by_id(db, uniacid, err_id["test_id"])
if pid not in errid_list:
errid_list.append(pid)
temp = test_mapper.get_question(db, uniacid, pid)
if temp is not None:
err_list.append(temp)
else:
temp = test_mapper.get_question(db, uniacid, err_id["test_id"])
if temp is not None:
err_list.append(temp)
for err in err_list:
is_collect = user_collect_praction_mapper.get_is_collect(db, uniacid, uid, err["id"], err["type"])
if is_collect is not None:
err["wrong_have"] = 1
else:
err["wrong_have"] = 2
err_list = Makeformat(db, err_list, uid=uid, paperid=paperid, uniacid=uniacid)
total = len(err_list)
return {"code": 0, "msg": "本次考试错题列表,总数", "data": {"list": err_list, "total": total}}
elif op == "collection_question":
id_list = user_collect_praction_mapper.get_id_list(db, uniacid, uid, 1)
if id_list is not None and len(id_list) > 0:
question_list = []
for id in id_list:
temp = test_mapper.get_question(db, uniacid, id["testid"])
question_list.append(temp)
if question_list is not None and len(question_list) > 0:
for question in question_list:
is_collect = user_collect_praction_mapper.get_is_collect(db, uniacid, question["id"],
question["type"])
if is_collect is not None:
question["wrong_have"] = 1
else:
question["wrong_have"] = 2
question_list = Makeformat(db=db, itembank=question_list, uniacid=int(uniacid))
return {"code": 0, "msg": "全部收藏", "data": {"list": question_list}}
else:
return {"code": 1, "msg": "暂无收藏", "data": "1004"}
async def handle_exchange_gift_list(
data: WxappRequest,
uniacid: str,
db: Session,
user_gift_mapper: CRUDUserGift,
gift_mapper: CRUDGift
):
uid = data.uid
if uid:
return {
"code": 1,
"msg": "传递的参数不存在或失效"
}
# [ giftid , createtime , status
# (1, 1634567890, 1),
# (2, 1634567900, 0)
# ]
user_gift_list = user_gift_mapper.get_user_gift_list(db, uniacid, uid)
data = []
if user_gift_list:
for user_gift in user_gift_list:
gift = gift_mapper.get_gift_by_id(db, user_gift[0], uniacid)
gift_dict = gift.__dict__
gift_dict['createtime'] = user_gift[1]
# 假设 attachurl 是一个字符串
# gift_dict['image'] = attachurl + gift.image
gift_dict['status'] = user_gift[2]
# 创建新的 Pydantic 模型实例
gift_vo = GiftResponse(**gift_dict)
data.append(gift_vo)
return {
"code": 0,
"msg": "兑换记录",
"data": data
}
return {
"code": 1,
"msg": "暂无兑换记录"
}
pass
async def handle_about_us(
data: WxappRequest,
uniacid: str,
db: Session,
setting: CRUDSetting
):
print(data)
info = setting.get_about_us(db, uniacid)
return {
"code": 0,
"data": info,
"msg": "success"
}
async def MockExam(data: WxappRequest,
db: Session,
uniacid: str,
user_mapper: CRUDUser,
setting_mapper: CRUDSetting,
xueshen_mapper: CRUDXueshen,
test_type_mapper: CRUDTestType,
test_mapper: CRUDTest,
user_pool_mapper: CRUDUserPool,
cdkey_mapper: CRUDCdkey,
cdkeys_mapper: CRUDCdkeys,
paper_test_mapper: CRUDPaperTest,
paper_mapper: CRUDPaper,
user_exam_answer_mapper: CRUDUserExamAnswer
):
uid = data.uid
exam_type = int(data.data["exam_type"])
paperid = int(data.data["paperid"])
if not uid:
return {
"code": 1,
"msg": "传递的参数不存在或失效",
"data": "1001"
}
if not exam_type:
return {
"code": 1,
"msg": "传递的参数不存在或失效",
"data": "1002"
}
user_info = user_mapper.get_user_info(db, uniacid, uid)
if not user_info:
return {
"code": 1,
"msg": "用户不存在",
"data": "1003"
}
if user_info.status != 1:
return {
"code": 1,
"msg": "用户被禁用",
"data": "1004"
}
is_student = xueshen_mapper.get_xuesheng_id(db, uniacid, user_info.name, user_info.phone)
freepool = []
fpool = []
if not is_student:
fpool = test_type_mapper.get_fpool(db, uniacid)
else:
fpool = test_type_mapper.get_fpool_with_student_check(db, uniacid)
if not fpool:
for val in fpool:
test_type_ids = test_type_mapper.get_test_type_ids(db, uniacid, val)
if not test_type_ids:
freepool.extend(test_type_ids)
pool = []
if not freepool:
for val in freepool:
pool.append(val)
userpool = []
# todo 使用了连接查询,这里需要测试是否正常工作
upool = user_pool_mapper.get_user_pool(db, uniacid, uid)
if upool:
for val in upool:
test_type_ids_ist = test_type_mapper.get_test_type_ids(db, uniacid, val[1])
if not test_type_ids_ist:
for val in test_type_ids_ist:
userpool.append(val[0])
if userpool:
for val in pool:
pool.append(val)
now_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
cdkey_list = cdkey_mapper.get_cdkey_list(db, uniacid, uid, int(now_time))
active_pool = []
for cdkey in cdkey_list:
pools = cdkeys_mapper.get_all_kpool_id(db, uniacid, cdkey.cid)
active_pool.extend(pools)
t_pools = []
for a_pool in active_pool:
t_pool = test_type_mapper.get_test_type_ids(db, a_pool)
t_pools.extend(t_pool)
active_pools = [val for val in t_pools]
pool.extend(active_pools)
# 去重
pool = list(set(pool))
# 拼接成字符串
# $poolstr = "";
# if (!empty($pool)) {
# $poolstr = implode(",", $pool);
# }
setting = setting_mapper.get_setting_by_weid(db, uniacid)
# $franction = unserialize($setting["franction"]);
franction = phpserialize.loads(setting.franction.encode('utf-8'), decode_strings=True)
paper_time = setting.paper_time
data = []
total_score = 0
total_qnum = 0
# 判断fraction不为空
if franction:
for key, val in enumerate(franction):
data[f"type_num_{key}"] = val[f"num_{key}"]
data[f"type_score_{key}"] = int(val[f"num_{key}"]) * int(val[f"franction_{key}"])
total_score += data[f"type_score_{key}"]
total_qnum += int(data[f"type_num_{key}"])
else:
return {
"code": 1,
"msg": "暂未设置考试信息",
"data": "1005"
}
question_list = []
if exam_type == 1:
if paperid:
return {
"code": 1,
"msg": "传递的参数不存在或失效",
"data": "1006"
}
paper = paper_mapper.get_paper_by_paperid(db, uniacid, paperid)
question_list = paper_test_mapper.get_questions_by_paperid(db, paper.id)
if question_list:
question_list = Makeformat(question_list)
return {
"code": 0,
"msg": "获取全真试卷失败",
"data": {
"paperid": paper.id,
"list": question_list,
"total_score": total_score,
"paper_time": paper_time,
"total_qnum": total_qnum
}
}
else:
return {"code": 0, "msg": "获取全真试卷失败", "data": {"list": [], "have": 2}}
elif exam_type == 2:
testid_arr = user_exam_answer_mapper.get_exam_answer_test_id(db, uniacid, 1)
newid_arr = [val for val in testid_arr]
if newid_arr:
i = 0
for val in data:
i += 1
if i <= 5:
temp = test_mapper.mock_exam_get_question_list(db, uniacid, pool, i, 1, data[f"type_num_{i}"])
question_list.extend(temp)
new_question = []
if question_list:
for question in question_list:
new_question.append(question)
new_question_list = Makeformat(new_question)
now_total = len(new_question_list)
if now_total != total_qnum:
return {"code": 0,
"msg": "获取优先未做试卷试题失败1",
"data": {"list": [], "have": 2}
}
else:
return {
"code": 0,
"msg": "优先未做试卷试题",
"data": {
"list": new_question_list,
"total_score": total_score,
"paper_time": paper_time,
"total_qnum": total_qnum,
"ceshi": 1
}
}
else:
return {
"code": 0,
"msg": "获取优先未做试卷试题失败2",
"data": {
"list": [],
"total_qnum": 0,
"have": 2
}
}
else:
i = 0
for value in data:
i += 1
if i <= 7:
temp = test_mapper.get_randon_question_list_batch(db, uniacid, i, 8, 1, 1, pool,
data[f"type_num_{i}"])
question_list.extend(temp)
new_question = []
if question_list is not None:
new_question.extend(question_list)
new_question = Makeformat(db=db, itembank=new_question, uniacid=int(uniacid))
now_total = len(new_question)
if now_total != total_qnum:
return {
"code": 0,
"msg": "获取优先未做试卷试题失败3",
"data": {
"list": [],
"have": 2
}
}
else:
return {
"code": 0,
"msg": "优先未做试卷试题",
"data": {
"list": new_question,
"total_score": total_score,
"paper_time": paper_time,
"total_qnum": total_qnum,
"ceshi": 2
}
}
else:
return {
"code": 0,
"msg": "获取优先未做试卷试题失败4",
"data": {
"list": [],
"total_qnum": 0,
"have": 2
}
}
elif exam_type == 3:
i = 0
for val in data:
i += 1
if i <= 7:
question_list.extend(
test_mapper.mock_exam_get_question_list_type3(db, uniacid, pool, i, 1, data[f"type_num_{i}"]))
new_question = []
if question_list is not None and len(question_list) > 0:
for val in question_list:
new_question.append(val)
new_question = Makeformat(db=db, itembank=new_question, uniacid=int(uniacid))
now_total = len(new_question)
if now_total != total_qnum:
return {
"code": 0,
"msg": "获取智能考试试卷试题失败1",
"data": {
"list": [],
"have": 2
}
}
else:
return {
"code": 0,
"msg": "智能考试试卷试题",
"data": {
"list": new_question,
"total_score": total_score,
"paper_time": paper_time,
"total_qnum": total_qnum,
}
}
else:
return {
"code": 0,
"msg": "获取智能考试试卷试题失败2",
"data": {
"list": [],
"total_qnum": 0,
"have": 2
}
}
def mb_rtrim(s, suffix):
while s.endswith(suffix):
s = s[:-len(suffix)]
return s
# todo $_W["attachurl"]需要解决
def Makeformat(db: Session, itembank: List, uid=None, paperid=None, uniacid=None):
attachurl = ""
test_mapper = CRUDTest(Test)
user_exam_answer_mapper = CRUDUserExamAnswer(UserExamAnswer)
paper_mapper = CRUDPaper(Paper)
for item in itembank:
# 处理qaudio
if item.get('qaudio'):
item['qaudio'] = attachurl + item['qaudio']
# 处理qimage
if item.get('qimage'):
try:
qimage = phpserialize.loads(item['qimage'].encode('utf-8'), decode_strings=True)
qimage_list = []
if isinstance(qimage, dict):
qimage = [qimage[k] for k in sorted(qimage.keys())]
for vv in qimage:
if not re.match(r'^(http://|https://)', vv, re.I):
vv = attachurl + vv
qimage_list.append(vv)
item['qimage'] = qimage_list
except Exception as e:
item['qimage'] = []
# 处理question
if item.get('question'):
item['question'] = html.unescape(item['question'])
# 处理aimage
if item.get('aimage'):
try:
aimage = phpserialize.loads(item['aimage'].encode('utf-8'), decode_strings=True)
aimage_list = []
if isinstance(aimage, dict):
aimage = [aimage[k] for k in sorted(aimage.keys())]
for vv in aimage:
if not re.match(r'^(http://|https://)', vv, re.I):
vv = attachurl + vv
aimage_list.append(vv)
item['aimage'] = aimage_list
except Exception as e:
item['aimage'] = []
# 处理analysis_audio
if item.get('analysis_audio'):
item['analysis_audio'] = attachurl + item['analysis_audio']
# 处理analysis
if item.get('analysis'):
item['analysis'] = html.unescape(item['analysis'])
# 处理option
if 'option' in item:
try:
option_data = phpserialize.loads(item['option'].encode('utf-8'), decode_strings=True)
options = []
if isinstance(option_data, dict):
for key in sorted(option_data.keys()):
vv = html.unescape(option_data[key])
if item.get('a_type', 0) != 0:
if vv and not re.match(r'^(http://|https://)', vv, re.I):
vv = attachurl + vv
options.append({'o': key, 'p': vv})
item['option'] = options
except Exception as e:
item['option'] = []
# 处理type=4
if item.get('type') == 4:
rightkey = item.get('rightkey', '')
if rightkey:
parts = rightkey.split('|')
rightarray = []
for part in parts:
part = mb_rtrim(part, '')
part = mb_rtrim(part, '')
rightarray.extend(part.split('】【'))
item['rightarray'] = rightarray
# 处理type5-7子题目
if 5 <= item.get('type', 0) <= 7:
son_list = test_mapper.get_testson_by_pid(db, uniacid, item['id'])
if son_list is not None and len(son_list) > 0:
son_dicts = [son.to_dict() for son in son_list]
item['list'] = Makeformat(db=db, itembank=son_dicts, uniacid=uniacid)
# 处理type=8用户答案
if item.get('type') == 8:
do_answer = user_exam_answer_mapper.get_do_answer(db, uniacid, uid, paperid, item['id'])
if not do_answer:
item['comments'] = '未填写评语',
else:
item['comments'] = do_answer.comments
item['uanswer'] = do_answer.uanswer
item["get_simple_scores"] = do_answer.simple_score
franction = paper_mapper.get_franction_by_paperid(db, uniacid, paperid)
if franction is not None:
try:
simples = phpserialize.loads(franction.encode('utf-8'), decode_strings=True)
item['simple_scores'] = simples.get('8', {}).get('franction_8', 0)
except:
item['simple_scores'] = 0
else:
item['simple_scores'] = 0
return itembank
async def TotalqNum(data: WxappRequest,
db: Session,
uniacid: str,
user_mapper: CRUDUser,
user_spequence_mapper: CRUDUserSequence,
xueshen_mapper: CRUDXueshen,
test_type_mapper: CRUDTestType,
user_pool_mapper: CRUDUserPool,
test_mapper: CRUDTest
):
uid = data.uid
if not uid:
user_info = user_mapper.get_user_info(db, uid, uniacid)
if user_info:
return {
"code": 1, "msg": "用户不存在", "data": "1002"
}
if user_info.status != 1:
return {
"code": 1, "msg": "用户被禁用", "data": "1003"
}
last_id = int(user_spequence_mapper.get_last_id(db, uid, uniacid))
is_student = xueshen_mapper.get_xuesheng_id(db, uniacid, user_info.name, user_info.phone)
freepool = []
fpool = []
if not is_student:
fpool = test_type_mapper.get_fpool(db, uniacid)
else:
fpool = test_type_mapper.get_fpool_with_student_check(db, uniacid)
if not fpool:
for val in fpool:
test_type_ids = test_type_mapper.get_test_type_ids(db, uniacid, val)
if not test_type_ids:
freepool.extend(test_type_ids)
pool = []
if not freepool:
for val in freepool:
pool.append(val)
userpool = []
# todo 使用了连接查询,这里需要测试是否正常工作
upool = user_pool_mapper.get_user_pool(db, uniacid, uid)
if not upool:
for val in upool:
test_type_ids_ist = test_type_mapper.get_test_type_ids(db, uniacid, val[1])
if not test_type_ids_ist:
for val in test_type_ids_ist:
userpool.append(val[0])
if not userpool:
for val in pool:
pool.append(val)
pool = list(dict.fromkeys(pool))
total = 0
if not pool:
total = test_mapper.get_test_count(db, uniacid, pool)
if total < last_id:
last_id = total
elif last_id == total - 1:
last_id = 0
if total > 0:
return {
"code": 0,
"msg": "总题数,进度ID",
"data": {
"total": int(total),
"last_id": int(last_id)
}
}
else:
return {
"code": 1,
"msg": "暂无试题",
"data": {
"total": 0, "last_id": 0, "is_can": 0
}
}
else:
return {
"code": 1,
"msg": "请先登录",
"data": {
"total": 0, "last_id": 0, "is_can": 2
}
}
async def per_exam_info(
data: WxappRequest,
uniacid: str,
db: Session,
setting: CRUDSetting,
user_doexam: CRUDUserDoexam,
user_mapper: CRUDUser,
user_do_other_exam: CRUDUserDoOtherExam
):
uid = int(data.uid)
if not uid:
return {
"code": 1,
"msg": "传递的参数不存在或失效",
"data": "1001"
}
user_info = user_mapper.get_user_info(db, uid, uniacid)
if not user_info:
return {
"code": 1,
"msg": "用户不存在",
"data": "1002"
}
if user_info.status != 1:
return {
"code": 1,
"msg": "用户被禁用",
"data": "1003"
}
quanzhen_highest = user_doexam.get_quanzhen_highest(db, uid, uniacid)
other_highest = user_do_other_exam.get_user_other_highest(db, uid, uniacid)
# 将空值转换为0确保可以正确参与比较
quanzhen_highest = quanzhen_highest if quanzhen_highest else 0
other_highest = other_highest if other_highest else 0
# 比较两个分数,取最大值
highest = max(quanzhen_highest, other_highest)
setting_info = setting.get_about_us(db, uniacid)
franction = phpserialize.loads(setting.franction.encode('utf-8'), decode_strings=True)
paper_time = setting_info.paper_time
data = []
total_score = 0
total_qnum = 0
if not franction:
for key, val in enumerate(franction):
data[f"type_num_{key}"] = val[f"num_{key}"]
data[f"type_score_{key}"] = int(val[f"num_{key}"]) * int(val[f"franction_{key}"])
total_score += data[f"type_score_{key}"]
total_qnum += int(data[f"type_num_{key}"])
pass_score = round(total_score * 0.6, 1)
return {
"code": 0,
"msg": "总分,时长,及格,历史最高",
"data": {"total_score": total_score,
"paper_time": paper_time,
"pass_score": pass_score,
"highest": highest
}
}
else:
return {
"code": 1,
"msg": "暂未设置考试信息",
"data": "1004"
}
async def get_exam_list(
data: WxappRequest,
uniacid: str,
db: Session,
paper_mapper: CRUDPaper,
paper_test: CRUDPaperTest,
user_pool: CRUDUserPool,
cdkeys_service: CRUDCdkeys,
user_member: CRUDUserMember,
cdkey_service: CRUDCdkey,
user_doexam_service: CRUDUserDoexam,
test_mapper: CRUDTest,
user_mapper: CRUDUser
):
uid = data.uid
page_index = int(data.data.page)
page_size = 10
paper_list = paper_mapper.get_page_list(db, uniacid, page_index, page_size)
total = paper_mapper.get_total(db, uniacid)
if paper_list:
have = 2
return {
"code": 0,
"msg": "暂无全真试卷",
"data": {"list": paper_list, "have": have}
}
for paper in paper_list:
value = paper.__dict__
value["name"] = value["title"]
value["qnum"] = paper_test.get_qnum(db, value["id"])
value["createtime"] = datetime.fromtimestamp(value["createtime"]).strftime('%Y-%m-%d')
value["is_can"] = 0
kid = ""
if value["price"] > 0:
kid = user_pool.get_kid_id_by_paperid(db, uniacid, uid, value["id"])
if not kid:
value["is_can"] = 1
else:
value["is_can"] = 1
user_mapper.get_user_is_member(db, uniacid, uid)
is_member = {}
z_vip = user_member.get_by_field(db, "weid", uniacid)
value["vip_price"] = value["price"] * z_vip.scale
value["vip_price"] = math.floor(value["vip_price"] * 100) / 100
value["simple"] = 2
if is_member == 1 and value["vip_price"] <= 0:
value["is_can"] = 1
now_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
cdkeys = cdkeys_service.get_all_cdkeys_code_ids(db, uniacid, value["id"])
if cdkeys is not None and len(cdkeys) > 0:
active = cdkey_service.get_user_active(db, uniacid, uid, now_time, cdkeys)
# todo查询用户是否有符合条件的激活记录
if active is not None:
value["is_can"] = 1
paper_test_id_list = paper_test.get_all_test_id(db, value["id"])
for paper_test_id in paper_test_id_list:
res = test_mapper.get_test_by_id_and_type(db, uniacid, 8, paper_test_id)
if res:
value["simple"] = 1
value["is_repeat"] = 2
break
# 查询用户做过的试卷数量
do_number = user_doexam_service.get_user_do_number(db, uniacid, uid, value["id"])
value["do_number"] = do_number
have = 1
return {
"code": 0,
"msg": "全真卷列表",
"data": {
"list": paper_list,
"have": have,
"total": total,
"psize": page_size
}
}
# 具体的操作函数实现...
# 用户信息相关
async def get_user_info(uid: str, data: Dict[str, Any], db: Session):
# 实现获取用户信息的逻辑
print("get_user_info", uid, data, db)
pass
async def update_user_info(uid: str, data: Dict[str, Any], db: Session):
# 实现更新用户信息的逻辑
print("update_user_info", uid, data, db)
pass
async def bind_user(uid: str, data: Dict[str, Any], db: Session):
# 实现绑定用户的逻辑
print("bind_user", uid, data, db)
pass
async def unbind_user(uid: str, data: Dict[str, Any], db: Session):
# 实现解绑用户的逻辑
print("unbind_user", uid, data, db)
pass
# 考试相关
async def submit_exam(uid: str, data: Dict[str, Any], db: Session, user_doexam, user_exam_answer):
# 实现提交考试的逻辑
print("submit_exam", uid, data, db, user_doexam, user_exam_answer)
pass
async def get_exam_history(uid: str, data: Dict[str, Any], db: Session, user_doexam, user_exam_answer):
# 实现获取考试历史的逻辑
print("get_exam_history", uid, data, db, user_doexam, user_exam_answer)
pass
async def get_exam_detail(uid: str, data: Dict[str, Any], db: Session, user_doexam, user_exam_answer):
# 实现获取考试详情的逻辑
print("get_exam_detail", uid, data, db, user_doexam, user_exam_answer)
pass
# 收藏相关
async def add_collection(uid: str, data: Dict[str, Any], db: Session, user_collection):
# 实现添加收藏的逻辑
print("add_collection", uid, data, db, user_collection)
pass
async def remove_collection(uid: str, data: Dict[str, Any], db: Session, user_collection):
# 实现移除收藏的逻辑
print("remove_collection", uid, data, db, user_collection)
pass
async def list_collections(uid: str, data: Dict[str, Any], db: Session, user_collection):
# 实现列出收藏的逻辑
print("list_collections", uid, data, db, user_collection)
pass
# 错题相关
async def add_wrong_question(uid: str, data: Dict[str, Any], db: Session, user_wrong_praction):
# 实现添加错题的逻辑
print("add_wrong_question", uid, data, db, user_wrong_praction)
pass
async def remove_wrong_question(uid: str, data: Dict[str, Any], db: Session, user_wrong_praction):
# 实现移除错题的逻辑
print("remove_wrong_question", uid, data, db, user_wrong_praction)
pass
async def list_wrong_questions(uid: str, data: Dict[str, Any], db: Session, user_wrong_praction):
# 实现列出错题的逻辑
print("list_wrong_questions", uid, data, db, user_wrong_praction)
pass
async def test(data: Dict[str, Any], db: Session):
test_mapper = CRUDTest(Test)
print(test_mapper.get_q_have_by_type_and_lib_id(db, "2", 1, 16, 1, None, 1))