diff --git a/test_client/src/api/analyse.js b/test_client/src/api/analyse.js
index b452ad7..6e85016 100644
--- a/test_client/src/api/analyse.js
+++ b/test_client/src/api/analyse.js
@@ -6,3 +6,4 @@ export function getBasicCount() {
method: 'get',
})
}
+
diff --git a/test_client/src/api/crm.js b/test_client/src/api/crm.js
index ce162f7..6149046 100644
--- a/test_client/src/api/crm.js
+++ b/test_client/src/api/crm.js
@@ -61,4 +61,11 @@ export function importConsumer(data) {
method: 'post',
data
})
+}
+export function exportConsumer(query) {
+ return request({
+ url: '/crm/consumer/export',
+ method: 'get',
+ params: query
+ })
}
\ No newline at end of file
diff --git a/test_client/src/api/examtest.js b/test_client/src/api/examtest.js
index 1b58d07..53879b5 100644
--- a/test_client/src/api/examtest.js
+++ b/test_client/src/api/examtest.js
@@ -117,4 +117,11 @@ export function deletePaper(id) {
url: `/examtest/paper/${id}/`,
method: 'delete',
})
+}
+export function exportTest(query) {
+ return request({
+ url: '/examtest/examtest/export',
+ method: 'get',
+ params: query
+ })
}
\ No newline at end of file
diff --git a/test_client/src/utils/request.js b/test_client/src/utils/request.js
index 51e1d27..e29d814 100644
--- a/test_client/src/utils/request.js
+++ b/test_client/src/utils/request.js
@@ -7,7 +7,7 @@ import { getToken } from '@/utils/auth'
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
- timeout: 10000, // request timeout
+ timeout: 30000, // request timeout
})
// request interceptor
diff --git a/test_client/src/views/analyse/examtest.vue b/test_client/src/views/analyse/examtest.vue
index 44582aa..b501288 100644
--- a/test_client/src/views/analyse/examtest.vue
+++ b/test_client/src/views/analyse/examtest.vue
@@ -31,12 +31,23 @@
:value="item.value"
/>
+
+
刷新重置
+ 导出Excel
@@ -67,7 +78,7 @@
{{ scope.row.score }}
- {{ scope.row.took }}
+ {{ scope.row.took_format }}
{{ scope.row.start_time }}
@@ -94,7 +105,7 @@
diff --git a/test_client/src/views/crm/consumer.vue b/test_client/src/views/crm/consumer.vue
index c5b594f..e42f199 100644
--- a/test_client/src/views/crm/consumer.vue
+++ b/test_client/src/views/crm/consumer.vue
@@ -32,7 +32,7 @@
/>
-->
上传导入
- Excel导入
+ Excel导入
+导出Excel
{
+ loading.close()
+ window.open(response.data.path, "_blank");
+ });
}
}
};
diff --git a/test_server/crm/exports.py b/test_server/crm/exports.py
new file mode 100644
index 0000000..624a786
--- /dev/null
+++ b/test_server/crm/exports.py
@@ -0,0 +1,26 @@
+from openpyxl.workbook import Workbook
+from django.conf import settings
+from datetime import datetime
+from openpyxl.styles import Font, Fill
+
+
+BASE_DIR = settings.BASE_DIR
+
+def export_consumer(users):
+ '''
+ params: serializer users
+ return: xlsx path
+ '''
+ wb = Workbook()
+ ws1 = wb.active
+ ws1.title = '用户表'
+ ws1.append(['姓名','手机号', '单位', '微信昵称', '工作类别', '创建日期'])
+ row = ws1.row_dimensions[1]
+ row.font = Font(bold=True)
+ for i in users:
+ ws1.append([i['name'], i['username'], i['company_name'], i['nickname'], i['workscope_name'], i['create_time']])
+ filename = 'users' + datetime.now().strftime("%Y%m%d%H%M%S") +'.xlsx'
+ path = '/media/export/' + filename
+ wb.save((BASE_DIR + path).replace('\\', '/'))
+ return path
+
diff --git a/test_server/crm/views.py b/test_server/crm/views.py
index d6769a6..48b5fdf 100644
--- a/test_server/crm/views.py
+++ b/test_server/crm/views.py
@@ -5,6 +5,7 @@ from calendar import timegm
from datetime import datetime
import requests
+from django.db.models import Q
from django_filters.rest_framework import DjangoFilterBackend
from openpyxl import Workbook, load_workbook
from rest_framework import status
@@ -15,7 +16,8 @@ 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 rest_framework_jwt.serializers import jwt_encode_handler, jwt_payload_handler
+from rest_framework_jwt.serializers import (jwt_encode_handler,
+ jwt_payload_handler)
from rest_framework_jwt.settings import api_settings
from crm.zhenzismsclient import ZhenziSmsClient
@@ -25,6 +27,7 @@ from question.serializers import QuestionSerializer
from server import settings
from utils.custom import CommonPagination
+from .exports import export_consumer
from .models import Company, Consumer, PaySubject, SendCode
from .serializers import CompanySerializer, ConsumerSerializer
@@ -229,10 +232,13 @@ class ConsumerViewSet(ModelViewSet):
return Response(status=status.HTTP_200_OK)
@action(methods=['get'], detail=False,
- url_path='export', url_name='export_consumer')
+ url_path='export', url_name='export_consumer', perms_map=[{'*':'export_consumer'}])
def export(self, request):
queryset = self.filter_queryset(self.queryset)
- print(queryset)
+ queryset = ConsumerSerializer.setup_eager_loading(queryset) # 性能优化
+ serializer = ConsumerSerializer(instance=queryset, many=True)
+ path = export_consumer(serializer.data)
+ return Response({'path': path})
class ConsumerMPLoginView(APIView):
"""
diff --git a/test_server/examtest/exports.py b/test_server/examtest/exports.py
new file mode 100644
index 0000000..532c084
--- /dev/null
+++ b/test_server/examtest/exports.py
@@ -0,0 +1,26 @@
+from openpyxl.workbook import Workbook
+from django.conf import settings
+from datetime import datetime
+from openpyxl.styles import Font, Fill
+
+
+BASE_DIR = settings.BASE_DIR
+
+def export_test(tests):
+ '''
+ params: serializer tests
+ return: xlsx path
+ '''
+ wb = Workbook()
+ ws1 = wb.active
+ ws1.title = '用户表'
+ ws1.append(['类型','用户姓名', '用户单位', '工作类别', '押题卷', '得分', '耗时', '答题时间'])
+ row = ws1.row_dimensions[1]
+ row.font = Font(bold=True)
+ for i in tests:
+ ws1.append([i['type'], i['consumer_name'], i['consumer_company_name'], i['workscope_name'], i['paper_name'], i['score'], i['took_format'], i['start_time']])
+ filename = 'tests' + datetime.now().strftime("%Y%m%d%H%M%S") +'.xlsx'
+ path = '/media/export/' + filename
+ wb.save((BASE_DIR + path).replace('\\', '/'))
+ return path
+
diff --git a/test_server/examtest/serializers.py b/test_server/examtest/serializers.py
index 8de9e76..1dc3b21 100644
--- a/test_server/examtest/serializers.py
+++ b/test_server/examtest/serializers.py
@@ -62,6 +62,8 @@ class ExamTestListSerializer(serializers.ModelSerializer):
workscope_name = serializers.StringRelatedField(source='workscope', read_only=True)
paper_name = serializers.StringRelatedField(source='paper', read_only=True)
consumer_name = serializers.SerializerMethodField()
+ took_format = serializers.SerializerMethodField()
+ consumer_company_name = serializers.SerializerMethodField()
class Meta:
model = ExamTest
exclude = ('detail',)
@@ -69,6 +71,21 @@ class ExamTestListSerializer(serializers.ModelSerializer):
def get_consumer_name(self, obj):
return obj.consumer.name
+ def get_took_format(self, obj):
+ m, s = divmod(obj.took, 60)
+ h, m = divmod(m, 60)
+ return "%02d:%02d:%02d" % (h, m, s)
+
+ def get_consumer_company_name(self, obj):
+ if obj.consumer.company:
+ return obj.consumer.company.name
+
+ @staticmethod
+ def setup_eager_loading(queryset):
+ """ Perform necessary eager loading of data. """
+ queryset = queryset.select_related('consumer','paper', 'workscope')
+ return queryset
+
class AnswerDetailSerializer(serializers.ModelSerializer):
class Meta:
model = AnswerDetail
diff --git a/test_server/examtest/views.py b/test_server/examtest/views.py
index 6062afa..6de6ed5 100644
--- a/test_server/examtest/views.py
+++ b/test_server/examtest/views.py
@@ -18,6 +18,7 @@ from question.serializers import QuestionSerializer
from server import settings
from utils.custom import CommonPagination
+from .exports import export_test
from .models import AnswerDetail, Banner, ExamTest
from .models_paper import Paper, PaperQuestions, TestRule, WorkScope
from .serializers import (
@@ -258,8 +259,15 @@ class ExamTestViewSet(ModelViewSet):
return Response({'error':'答题记录不存在'})
else:
return Response(serializer.errors)
-
-
+
+ @action(methods=['get'], detail=False,
+ url_path='export', url_name='export_test', perms_map=[{'*':'export_test'}])
+ def export(self, request):
+ queryset = self.filter_queryset(self.queryset)
+ queryset = ExamTestListSerializer.setup_eager_loading(queryset) # 性能优化
+ serializer = ExamTestListSerializer(instance=queryset, many=True)
+ path = export_test(serializer.data)
+ return Response({'path': path})
class PaperViewSet(ModelViewSet):
"""
押题卷增删改查
diff --git a/test_server/question/views.py b/test_server/question/views.py
index 9bc9fd9..6295a80 100644
--- a/test_server/question/views.py
+++ b/test_server/question/views.py
@@ -1,22 +1,26 @@
-from rest_framework.filters import SearchFilter, OrderingFilter
-from rest_framework.permissions import IsAuthenticated
-from rest_framework.views import APIView
-from rest_framework.viewsets import ModelViewSet
-from rest_framework.generics import GenericAPIView
-from rest_framework.response import Response
-from rest_framework.decorators import action
-from rest_framework import status
-from django_filters.rest_framework import DjangoFilterBackend
-from openpyxl import Workbook, load_workbook
-from rest_framework_jwt.authentication import JSONWebTokenAuthentication
import json
-from utils.custom import CommonPagination
-from .models import Questioncat, Question
-from .serializers import QuestioncatSerializer, QuestionSerializer, SubjectSerializer, QuestioncatSerializerDefault
-from server import settings
+from django_filters.rest_framework import DjangoFilterBackend
+from openpyxl import Workbook, load_workbook
+from rest_framework import status
+from rest_framework.decorators import action
+from rest_framework.filters import OrderingFilter, SearchFilter
+from rest_framework.generics import GenericAPIView
+from rest_framework.permissions import 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 PaySubject
from examtest.models import WorkScope
+from server import settings
+from utils.custom import CommonPagination
+
+
+from .models import Question, Questioncat
+from .serializers import (QuestioncatSerializer, QuestioncatSerializerDefault,
+ QuestionSerializer, SubjectSerializer)
class SubjectViewSet(ModelViewSet):
@@ -240,4 +244,4 @@ class ExerciseView(APIView):
i['is_collect'] = True
else:
i['is_collect'] = False
- return Response({'count':count, 'results':results})
\ No newline at end of file
+ return Response({'count':count, 'results':results})
diff --git a/test_server/utils/file.py b/test_server/utils/file.py
index 47afae1..9ae732f 100644
--- a/test_server/utils/file.py
+++ b/test_server/utils/file.py
@@ -15,7 +15,7 @@ class UploadFileView(APIView):
def post(self, request, *args, **kwargs):
fileobj = request.FILES['file']
file_name = fileobj.name.encode('utf-8').decode('utf-8')
- file_name_new = str(uuid.uuid1()) + '.' + file_name.split('.')[1]
+ file_name_new = str(uuid.uuid1()) + '.' + file_name.split('.')[-1]
subfolder = os.path.join('media', datetime.now().strftime("%Y%m%d"))
if not os.path.exists(subfolder):
os.mkdir(subfolder)