diff --git a/server/apps/exam/test.py b/server/apps/exam/parse_word.py similarity index 89% rename from server/apps/exam/test.py rename to server/apps/exam/parse_word.py index 9fadc1e..3819af1 100644 --- a/server/apps/exam/test.py +++ b/server/apps/exam/parse_word.py @@ -1,4 +1,4 @@ -import pandas as pd + from docx import Document from openpyxl import load_workbook import re @@ -31,7 +31,7 @@ def match_text(text, pattern): return '' # 解析word文档 -def interpret_text(start:int, excel_path:str, doc_path:str): +def interpret_text(start:int, excel_path:str, doc_path:str, field=None): wordfile = Document(doc_path) correct_dict = {} option_dict = {} @@ -48,7 +48,7 @@ def interpret_text(start:int, excel_path:str, doc_path:str): # 题目类型 # 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] # 题目类型 + q_type = p.text[1:3] # 题目类型 question_type.setdefault("question_type", []).append(q_type) if p.text[-2]=='分': #(3分) question_text = p.text[5:-4].strip() @@ -65,7 +65,10 @@ def interpret_text(start:int, excel_path:str, doc_path:str): 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)) + if field: + fill_excel(field, excel_path, 'B'+str(start+v)) + else: + 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)) @@ -87,6 +90,7 @@ def interpret_text(start:int, excel_path:str, doc_path:str): elif key == "I": for v in range(len(value)): fill_excel(value[v], excel_path, 'I'+str(start+v)) + return 'OK' if __name__ == '__main__': diff --git a/server/apps/exam/views.py b/server/apps/exam/views.py index c95036b..ef0822f 100644 --- a/server/apps/exam/views.py +++ b/server/apps/exam/views.py @@ -22,9 +22,12 @@ from apps.system.mixins import CreateUpdateCustomMixin from apps.edu.serializers import CertificateSerializer from utils.queryset import get_child_queryset2 from apps.system.permission import has_permission -from datetime import datetime +from apps.exam.parse_word import interpret_text +import os +import shutil # Create your views here. +EXCEL_PATH = os.path.join(settings.BASE_DIR, "media/default/question.xlsx") def enctry(s): k = 'ez9z3a4m*$%srn9ve_t71yd!v+&xn9@0k(e(+l6#g1h=e5i4da' @@ -62,22 +65,7 @@ class QuestionViewSet(CreateUpdateCustomMixin, ModelViewSet): serializer_class = QuestionSerializer 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) @@ -286,6 +274,140 @@ class PaperViewSet(ModelViewSet): PaperQuestion.objects.bulk_create(q_list) return Response() + @action(methods=['post'], detail=False, perms_map={'post': 'question'}, serializer_class=Serializer) + def upload_paper(self, request): + doc_path = request.data.get('doc_path') + excel_path = settings.BASE_DIR + "media/default/question.xlsx" + timenow = timezone.now().strftime('%Y%m%d%H%M%S') + question_excel_name = "question_excel_"+timenow + question_excel = os.path.join(os.path.dirname(excel_path), question_excel_name) + if not os.path.exists(question_excel): + os.makedirs(question_excel) + shutil.copy(excel_path, question_excel) + excel_save_path = os.path.join(question_excel, os.path.basename(EXCEL_PATH)) + # 解析word文档到excel + res = interpret_text(3, excel_save_path, doc_path) + ids = [] + if res: + # 将excel 入库并返回 queston_id + wb = load_workbook(excel_save_path) + sheet = wb.worksheets[0] + qlist = ['A', 'B', 'C', 'D', 'E', 'F'] + leveldict = {'低': '低', '中': '中', '高': '高'} + # 验证文件内容 + if sheet['a2'].value != '题目类型': + return Response({"error": "类型列错误!"}) + if sheet['b2'].value != '分类': + return Response({"error": "分类列错误!"}) + if sheet['c2'].value != '题目': + return Response({"error": "题目列错误!"}) + questioncatdict = {} + questioncats = Questioncat.objects.all() + for i in questioncats: + questioncatdict[i.name] = i.id + i = 3 + while sheet['c'+str(i)].value: + type = sheet['a'+str(i)].value.replace(' ', '') + questioncat = sheet['b'+str(i)].value + if questioncat: + questioncat = questioncat.replace(' ', '') + else: + return Response(str(i)+'行没有分类', status=400) + name = sheet['c'+str(i)].value + + answer = {} + if sheet['d'+str(i)].value: + answer['A'] = sheet['d'+str(i)].value + if sheet['e'+str(i)].value: + answer['B'] = sheet['e'+str(i)].value + if sheet['f'+str(i)].value: + answer['C'] = sheet['f'+str(i)].value + if sheet['g'+str(i)].value: + answer['D'] = sheet['g'+str(i)].value + if sheet['h'+str(i)].value: + answer['E'] = sheet['h'+str(i)].value + if sheet['i'+str(i)].value: + answer['F'] = sheet['i'+str(i)].value + right = sheet['j'+str(i)].value + if right: + right = right.replace(' ', '') + else: + return Response(str(i)+'行没有答案', status=400) + resolution = sheet['k'+str(i)].value + level = sheet['l'+str(i)].value + year = sheet['m' + str(i)].value + if level: + level = level.replace(' ', '') + cateobj = None + if questioncat not in questioncatdict: + return Response(str(i)+"行不存在分类("+questioncat+")!请先新建", status=400) + else: + cateobj = Questioncat.objects.get( + id=questioncatdict[questioncat]) + if type == '单选': + if right in ['A', 'B', 'C', 'D', 'E', 'F']: + obj = Question() + obj.type = '单选' + if cateobj: + obj.questioncat = cateobj + obj.name = name + obj.options = answer + obj.right = right + obj.resolution = resolution if resolution else '' + obj.year = year if year else None + if level in leveldict: + obj.level = leveldict[level] + else: + obj.level = '低' + obj.save() + ids.append(obj.id) + elif type == '多选': + right = list(right.strip()) + if [False for c in right if c not in qlist]: + pass + else: + obj = Question() + obj.type = '多选' + obj.questioncat = cateobj + obj.name = name + obj.options = answer + obj.right = right + obj.resolution = resolution if resolution else '' + obj.year = year if year else None + if level in leveldict: + obj.level = leveldict[level] + else: + obj.level = '低' + obj.save() + ids.append(obj.id) + elif type == '判断': + if right == 'A' or right == '对' or right == '正确': + right = 'A' + else: + right = 'B' + obj = Question() + obj.type = '判断' + obj.questioncat = cateobj + obj.name = name + obj.options = {'A': '对', 'B': '错'} + obj.right = right + obj.resolution = resolution if resolution else '' + obj.year = year if year else None + if level in leveldict: + obj.level = leveldict[level] + else: + obj.level = '低' + obj.save() + ids.append(obj.id) + i = i + 1 + else: + raise ParseError('excel解析失败') + if ids: + questions = Question.objects.filter(pk__in=ids) + Serializer = QuestionSerializer(questions, many=True) + Serializer.data + return Response(Serializer.data, status=200) + class ExamViewSet(CreateUpdateCustomMixin, ModelViewSet): perms_map = {'get': '*', 'post':'exam', 'put':'exam', 'delete':'exam'}