307 lines
13 KiB
Python
307 lines
13 KiB
Python
import json
|
||
|
||
from django_filters.rest_framework import DjangoFilterBackend
|
||
from openpyxl import Workbook, load_workbook
|
||
from rest_framework import status
|
||
from rest_framework.decorators import action, permission_classes
|
||
from rest_framework.filters import OrderingFilter, SearchFilter
|
||
from rest_framework.generics import GenericAPIView
|
||
from rest_framework.permissions import IsAdminUser, IsAuthenticated
|
||
from rest_framework.response import Response
|
||
from rest_framework.views import APIView
|
||
from rest_framework.viewsets import ModelViewSet
|
||
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
|
||
|
||
from crm.models import Consumer, PaySubject
|
||
from examtest.models import WorkScope
|
||
from server import settings
|
||
from utils.custom import CommonPagination
|
||
from .exports import export_question
|
||
|
||
|
||
from .models import Question, Questioncat
|
||
from .serializers import (QuestioncatSerializer, QuestioncatSerializerDefault,
|
||
QuestionSerializer, SubjectSerializer)
|
||
|
||
|
||
class SubjectViewSet(ModelViewSet):
|
||
"""
|
||
学科分类:增删改查
|
||
"""
|
||
perms_map = (
|
||
{'get': '*'}, {'post': 'subject_create'},
|
||
{'put': 'subject_update'}, {'delete': 'subject_delete'})
|
||
queryset = Questioncat.objects.filter(is_subject=True,is_delete=0).all().order_by("id")
|
||
serializer_class = SubjectSerializer
|
||
pagination_class = None
|
||
ordering_fields = ('id',)
|
||
ordering = ['id']
|
||
search_fields = ('^name',)
|
||
|
||
|
||
class QuestioncatViewSet(ModelViewSet):
|
||
"""
|
||
题库分类:增删改查
|
||
"""
|
||
perms_map = (
|
||
{'get': '*'}, {'post': 'questioncat_create'},
|
||
{'put': 'questioncat_update'}, {'delete': 'questioncat_delete'})
|
||
queryset = Questioncat.objects.filter(is_delete=0,is_subject=False).all()
|
||
serializer_class = QuestioncatSerializerDefault
|
||
pagination_class = CommonPagination
|
||
ordering_fields = ['id']
|
||
ordering = ['type','id']
|
||
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
|
||
filterset_fields = ['pid']
|
||
search_fields = ['name']
|
||
|
||
@action(methods=['get'], detail=False,
|
||
url_path='all', url_name='all_questioncat')
|
||
def all(self, request):
|
||
"""
|
||
题库分类全,不分页
|
||
"""
|
||
queryset = Questioncat.objects.filter(is_delete=0).all()
|
||
if request.query_params.get('pid',None):
|
||
queryset = queryset.filter(pid = request.query_params.get('pid'))
|
||
serializer = QuestioncatSerializer(instance=queryset,many=True)
|
||
return Response(serializer.data)
|
||
|
||
@action(methods=['get'], detail=False,
|
||
url_path='subject', url_name='questioncat_subject', pagination_class = None, permission_classes=[])
|
||
def subject(self, request):
|
||
"""
|
||
学科下的全部分类
|
||
"""
|
||
queryset = Questioncat.objects.filter(is_delete=0, pid=request.query_params.get('id')).all()
|
||
serializer = QuestioncatSerializer(instance=queryset,many=True)
|
||
return Response(serializer.data)
|
||
|
||
@action(methods=['get'], detail=False,
|
||
url_path='workscope', url_name='questioncat_workscope', pagination_class = None, permission_classes=[])
|
||
def workscope(self, request):
|
||
"""
|
||
工作类别下的全部分类
|
||
"""
|
||
queryset = WorkScope.objects.get(id=request.query_params.get('id')).questioncat.all().order_by('pk')
|
||
serializer = QuestioncatSerializer(instance=queryset,many=True)
|
||
return Response(serializer.data)
|
||
|
||
from django.db.models import Q
|
||
class QuestionViewSet(ModelViewSet):
|
||
"""
|
||
题目:增删改查
|
||
"""
|
||
perms_map = (
|
||
{'get': 'question_view'}, {'post': 'question_create'},
|
||
{'put': 'question_update'}, {'delete': 'question_delete'})
|
||
queryset = Question.objects.filter(is_delete=0).all()
|
||
serializer_class = QuestionSerializer
|
||
pagination_class = CommonPagination
|
||
ordering_fields = ['id', 'name']
|
||
ordering = ['-create_time']
|
||
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
|
||
filterset_fields = ['questioncat','level', 'type']
|
||
search_fields = ['name', 'options', 'resolution']
|
||
|
||
@action(methods=['post'], detail=False,
|
||
url_path='count', url_name='question_count')
|
||
def count(self, request):
|
||
ret = {'danxuan':0,'duoxuan':0,'panduan':0}
|
||
queryset = self.queryset
|
||
if request.data.get('ids',None):
|
||
queryset = queryset.filter(questioncat__in = request.data.get('ids'))
|
||
ret['danxuan'] = queryset.filter(type='单选').count()
|
||
ret['duoxuan'] = queryset.filter(type='多选').count()
|
||
ret['panduan'] = queryset.filter(type='判断').count()
|
||
return Response(ret)
|
||
|
||
def get_queryset(self):
|
||
user = self.request.user
|
||
if isinstance(user, Consumer):
|
||
questioncats = user.workscope.questioncat.all()
|
||
self.queryset = self.queryset.filter(questioncat__in = questioncats)
|
||
return super().get_queryset()
|
||
|
||
@action(methods=['get'], detail=False,
|
||
url_path='export', url_name='export_question', perms_map=[{'*':'export_question'}])
|
||
def export(self, request):
|
||
queryset = self.filter_queryset(self.get_queryset())
|
||
path = export_question(queryset)
|
||
return Response({'path': path})
|
||
|
||
@action(methods=['get'], detail=False,
|
||
url_path='correct', url_name='correct_question', permission_classes=[IsAuthenticated])
|
||
def correct(self, request):
|
||
# for i in Question.objects.all():
|
||
# options = i.options
|
||
# for k in options:
|
||
# options[k] = str(options[k]).replace('<p>','').replace('</p>','')\
|
||
# .replace('×','×').replace('β','β').replace('α','α')\
|
||
# .replace('γ','γ').replace(' ',' ')
|
||
# i.options = options
|
||
# i.save()
|
||
for i in Question.objects.filter(Q(options__A__contains='μ')|Q(options__B__contains='μ')|Q(options__C__contains='μ')|Q(options__D__contains='μ')|Q(options__E__contains='μ')|Q(options__F__contains='μ')):
|
||
print(i)
|
||
options = i.options
|
||
for k in options:
|
||
options[k] = str(options[k]).replace('μ','μ')
|
||
i.options = options
|
||
i.save()
|
||
return Response()
|
||
|
||
@action(methods=['post'], detail=False, perms_map=[{'*':'question_delete'}])
|
||
def deletes(self, request):
|
||
"""
|
||
批量删除
|
||
"""
|
||
ids = request.data.get('ids', [])
|
||
if request.user.is_superuser:
|
||
Question.objects.filter(id__in=ids).update(is_delete=True)
|
||
return Response()
|
||
return Response({'error':'权限不足'})
|
||
|
||
@action(methods=['post'], detail=False, url_name='enable_question', permission_classes=[IsAuthenticated])
|
||
def enable(self, request):
|
||
ids = request.data.get('ids',None)
|
||
if ids:
|
||
Question.objects.filter(pk__in=ids).update(enabled=True)
|
||
return Response(status=status.HTTP_200_OK)
|
||
|
||
@action(methods=['post'], detail=False,
|
||
url_path='import', url_name='import_question',perms_map=[{'post':'question_import'}])
|
||
def import_question(self, request):
|
||
"""
|
||
导入题目
|
||
"""
|
||
xlsxpath = request.data['path']
|
||
fullpath = settings.BASE_DIR + xlsxpath
|
||
wb = load_workbook(fullpath)
|
||
sheet = wb.worksheets[0]
|
||
qlist = ['A','B','C','D','E','F']
|
||
leveldict = {'低':'低','中':'中','高':'高'}
|
||
notinlist = []
|
||
# 验证文件内容
|
||
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.filter(is_delete=0)
|
||
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.replace(' ', '')
|
||
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.replace(' ', '')
|
||
resolution = sheet['k'+str(i)].value
|
||
level = sheet['l'+str(i)].value
|
||
if level:
|
||
level = level.replace(' ', '')
|
||
if questioncat not in questioncatdict:
|
||
return Response({"error":"不存在分类("+questioncat+")!请先新建"})
|
||
else:
|
||
cateobj = Questioncat.objects.get(id=questioncatdict[questioncat])
|
||
if type == '单选':
|
||
if Question.objects.filter(type='单选',name=name, is_delete=0, questioncat=cateobj).exists():
|
||
notinlist.append(i)
|
||
else:
|
||
if right in ['A','B','C','D','E','F']:
|
||
obj = Question()
|
||
obj.type = '单选'
|
||
obj.questioncat = cateobj
|
||
obj.name = name
|
||
obj.options=answer
|
||
obj.right = right
|
||
obj.resolution = resolution if resolution else ''
|
||
if level in leveldict:
|
||
obj.level = leveldict[level]
|
||
else:
|
||
obj.level = '低'
|
||
obj.save()
|
||
elif type == '多选':
|
||
right = list(right)
|
||
if Question.objects.filter(type='多选', name=name, is_delete=0, questioncat=cateobj).exists():
|
||
notinlist.append(i)
|
||
else:
|
||
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 ''
|
||
if level in leveldict:
|
||
obj.level = leveldict[level]
|
||
else:
|
||
obj.level = '低'
|
||
obj.save()
|
||
elif type == '判断':
|
||
if right == 'A' or right == '对' or right == '正确':
|
||
right = 'A'
|
||
else:
|
||
right = 'B'
|
||
if Question.objects.filter(type='判断',name=name, is_delete=0, questioncat=cateobj).exists():
|
||
notinlist.append(i)
|
||
else:
|
||
obj = Question()
|
||
obj.type = '判断'
|
||
obj.questioncat = cateobj
|
||
obj.name = name
|
||
obj.options={'A':'对','B':'错'}
|
||
obj.right = right
|
||
obj.resolution = resolution if resolution else ''
|
||
if level in leveldict:
|
||
obj.level = leveldict[level]
|
||
else:
|
||
obj.level = '低'
|
||
obj.save()
|
||
i = i +1
|
||
return Response(status=status.HTTP_200_OK)
|
||
|
||
class ExerciseView(APIView):
|
||
perms_map=[{'post':'exercise'}]
|
||
def post(self, request):
|
||
questioncat = request.data['questioncat']
|
||
queryset = Question.objects.filter(is_delete=0,questioncat=questioncat,enabled=True).order_by('type','pk', 'name')
|
||
if 'ydtms' in request.data and request.data['ydtms']:
|
||
queryset = queryset.exclude(id__in = request.data['ydtms'])
|
||
if 'ydtms_' in request.data and request.data['ydtms_']:
|
||
consumer = request.user
|
||
process = consumer.process
|
||
process['cat'+str(questioncat)] = request.data['ydtms_']
|
||
consumer.process = process
|
||
consumer.save()
|
||
count = queryset.count()
|
||
pg = CommonPagination()
|
||
p = pg.paginate_queryset(queryset=queryset,request=request,view=self)
|
||
serializer = QuestionSerializer(instance=p,many=True)
|
||
collects = request.user.collects.all().values_list('id',flat=True) #当前用户收藏的题目
|
||
results = serializer.data
|
||
for i in results:
|
||
if i['id'] in collects:
|
||
i['is_collect'] = True
|
||
else:
|
||
i['is_collect'] = False
|
||
return Response({'count':count, 'results':results})
|