diff --git a/server/apps/exam/test.py b/server/apps/exam/test.py new file mode 100644 index 0000000..9fadc1e --- /dev/null +++ b/server/apps/exam/test.py @@ -0,0 +1,95 @@ +import pandas as pd +from docx import Document +from openpyxl import load_workbook +import re + + +QUES_CLASS = '安全领域' + +OPTION_LIST=[ + [r"A:\s*(\S+)", "D"], + [r"B:\s*(\S+)", "E"], + [r"C:\s*(\S+)", "F"], + [r"D:\s*(\S+)", "G"], + [r"E:\s*(\S+)", "H"], + [r"F:\s*(\S+)", "I"], +] + +def fill_excel(matches, excel_path, local): + wb = load_workbook(excel_path) + ws = wb.active + if matches: + ws[local] = matches + wb.save(excel_path) + + +def match_text(text, pattern): + matches = re.search(pattern, text) + if matches: + results = matches.group(1) + return results + return '' + +# 解析word文档 +def interpret_text(start:int, excel_path:str, doc_path:str): + wordfile = Document(doc_path) + correct_dict = {} + option_dict = {} + question_type = {} + ques_text = {} + for index, p in enumerate(wordfile.paragraphs): + correct_answer = match_text(p.text, r"正确答案:\s*(\S+)") # 匹配正确答案 + if correct_answer: + correct_dict.setdefault("correct_answer", []).append(correct_answer) + for e in OPTION_LIST: # 匹配选项 + result = match_text(p.text, e[0]) + if result: + option_dict.setdefault(e[1], []).append(result) + # 题目类型 + # fill_excel(QUES_CLASS, excel_path, 'B'+str(index+start)) + if p.text[:1]=='【' and p.text[4:5]=='】': + q_type = p.text[1:4] # 题目类型 + question_type.setdefault("question_type", []).append(q_type) + if p.text[-2]=='分': #(3分) + question_text = p.text[5:-4].strip() + result = bool(re.match(r'\d+、', question_text)) # 处理题目前的序号 + if result: + question = re.sub(r'\d+、', '',question_text) + ques_text.setdefault("question_text", []).append(question) + dict_list = [correct_dict,ques_text,option_dict,question_type] + for d in dict_list: + for key,value in d.items(): + if key == "correct_answer": + for v in range(len(value)): + fill_excel(value[v], excel_path, 'J'+str(start+v)) + elif key == "question_type": + for v in range(len(value)): + fill_excel(value[v], excel_path, 'A'+str(start+v)) + fill_excel(QUES_CLASS, excel_path, 'B'+str(start+v)) + elif key == "question_text": + for v in range(len(value)): + fill_excel(value[v], excel_path, 'C'+str(start+v)) + elif key == "D": + for v in range(len(value)): + fill_excel(value[v], excel_path, 'D'+str(start+v)) + elif key == "E": + for v in range(len(value)): + fill_excel(value[v], excel_path, 'E'+str(start+v)) + elif key == "F": + for v in range(len(value)): + fill_excel(value[v], excel_path, 'F'+str(start+v)) + elif key == "G": + for v in range(len(value)): + fill_excel(value[v], excel_path, 'G'+str(start+v)) + elif key == "H": + for v in range(len(value)): + fill_excel(value[v], excel_path, 'H'+str(start+v)) + elif key == "I": + for v in range(len(value)): + fill_excel(value[v], excel_path, 'I'+str(start+v)) + + +if __name__ == '__main__': + doc_path = "C:\code\data\\test.docx" + excel_path = "C:\code\data\question.xlsx" + interpret_text(3, excel_path, doc_path) \ No newline at end of file diff --git a/server/apps/exam/views.py b/server/apps/exam/views.py index 8ab2781..c95036b 100644 --- a/server/apps/exam/views.py +++ b/server/apps/exam/views.py @@ -63,6 +63,22 @@ class QuestionViewSet(CreateUpdateCustomMixin, ModelViewSet): filterset_fields = ['level', 'type', 'year'] search_fields = ['name', 'options', 'resolution'] + @action(methods=['post'], detail=False, perms_map={'post': 'question'}, serializer_class=Serializer) + def generate_paper(self, request): + """ + 生成试卷 + + 生成试卷 + """ + print(request.data) + data = request.data.get('ids') + if data: + questions = Question.objects.filter(pk__in=data) + Serializer = QuestionSerializer(questions, many=True) + Serializer.data + return Response(Serializer.data, status=200) + + @action(methods=['get'], detail=False, url_path='export', url_name='export_question', perms_map=[{'get': '*'}], serializer_class=Serializer) def export_question(self, request): @@ -102,6 +118,7 @@ class QuestionViewSet(CreateUpdateCustomMixin, ModelViewSet): qlist = ['A', 'B', 'C', 'D', 'E', 'F'] leveldict = {'低': '低', '中': '中', '高': '高'} notinlist = [] + ids = [] # 验证文件内容 if sheet['a2'].value != '题目类型': return Response({"error": "类型列错误!"}) @@ -171,6 +188,7 @@ class QuestionViewSet(CreateUpdateCustomMixin, ModelViewSet): else: obj.level = '低' obj.save() + ids.append(obj.id) elif type == '多选': right = list(right.strip()) if Question.objects.filter(type='多选', name=name, year=year, options=answer, questioncat=cateobj).exists(): @@ -192,12 +210,13 @@ class QuestionViewSet(CreateUpdateCustomMixin, ModelViewSet): else: obj.level = '低' obj.save() + ids.append(obj.id) elif type == '判断': if right == 'A' or right == '对' or right == '正确': right = 'A' else: right = 'B' - if Question.objects.filter(type='判断', name=name, is_delete=0, options={'A': '对', 'B': '错'}, questioncat=cateobj).exists(): + if Question.objects.filter(type='判断', name=name, is_deleted=0, options={'A': '对', 'B': '错'}, questioncat=cateobj).exists(): notinlist.append(i) else: obj = Question() @@ -213,8 +232,9 @@ class QuestionViewSet(CreateUpdateCustomMixin, ModelViewSet): else: obj.level = '低' obj.save() + ids.append(obj.id) i = i + 1 - return Response(notinlist, status=200) + return Response(notinlist, ids, status=200) class PaperViewSet(ModelViewSet): @@ -358,7 +378,7 @@ class ExamRecordViewSet(ListModelMixin, DestroyModelMixin, RetrieveModelMixin, G # return qs # else: # return qs.filter(belong_dept__in=get_child_queryset2(self.request.user.dept)) - if has_permission('ability_review_jygl', self.request.user): + if has_permission('ctc_manager', self.request.user): return qs return qs.filter(belong_dept__in=get_child_queryset2(self.request.user.dept)) @@ -407,6 +427,7 @@ class ExamRecordViewSet(ListModelMixin, DestroyModelMixin, RetrieveModelMixin, G if er.create_by != request.user: raise ParseError('提交人有误') exam = er.exam + paper = er.paper if not exam: raise ParseError('暂不支持') if now > exam.close_time + timedelta(minutes=30): @@ -434,7 +455,8 @@ class ExamRecordViewSet(ListModelMixin, DestroyModelMixin, RetrieveModelMixin, G except Exception as e: raise ParseError('判卷失败, 请检查试卷:' + str(e)) er.score = total_score - if er.score > 0.6*er.total_score: + # if er.score > 0.6*er.total_score: + if er.score >= paper.pass_score: er.is_pass = True # 如果是自动发证 if exam.certificate: diff --git a/server/apps/information/views.py b/server/apps/information/views.py index e8cc945..32fc756 100644 --- a/server/apps/information/views.py +++ b/server/apps/information/views.py @@ -62,9 +62,7 @@ class ImpMixin: def gen_imp_view(self, request, start: int, mySerializer): if 'file' not in request.data: raise ParseError('请提供文件') - path = request.data['file'] - print(path, "---------ssss") - + path = request.data['file'] if not str(path).endswith('.xlsx'): raise ParseError('请提供xlsx格式文件') fullpath = settings.BASE_DIR + str(path)