正式考试完成
This commit is contained in:
parent
94ee6f844f
commit
27123fb3ec
|
@ -132,4 +132,12 @@ export function exportTest(query) {
|
|||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function exportwTest(id,data) {
|
||||
return request({
|
||||
url: `/examtest/examtest/${id}/exportw/`,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
</el-select>
|
||||
<el-select
|
||||
v-model="listQuery.type"
|
||||
placeholder="模考类型"
|
||||
placeholder="考试类型"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
class="filter-item"
|
||||
|
@ -85,6 +85,9 @@
|
|||
<el-table-column align="left" label="押题卷">
|
||||
<template slot-scope="scope">{{ scope.row.paper_name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" label="所属考试">
|
||||
<template slot-scope="scope">{{ scope.row.exam_name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" label="得分" sortable='custom' prop="score">
|
||||
<template slot-scope="scope">{{ scope.row.score }}</template>
|
||||
</el-table-column>
|
||||
|
@ -94,14 +97,20 @@
|
|||
<el-table-column align="left" label="答题时间">
|
||||
<template slot-scope="scope">{{ scope.row.start_time }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="操作">
|
||||
<el-table-column align="center" label="操作" fixed="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
v-if="scope.row.type=='正式考试'"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleDetail(scope)"
|
||||
icon="el-icon-more"
|
||||
></el-button>
|
||||
@click="handleExport(scope)"
|
||||
>生成Word</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.type=='正式考试'"
|
||||
type="warning"
|
||||
size="small"
|
||||
@click="handleExport2(scope)"
|
||||
>重新生成</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -116,7 +125,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { getExamTestlist, exportTest } from "@/api/examtest";
|
||||
import { getExamTestlist, exportTest, exportwTest } from "@/api/examtest";
|
||||
import checkPermission from "@/utils/permission";
|
||||
import Pagination from "@/components/Pagination";
|
||||
|
||||
|
@ -138,6 +147,7 @@ export default {
|
|||
typeOptions: [
|
||||
{ key: "自助模考", label: "自助模考", value: "自助模考" },
|
||||
{ key: "押卷模考", label: "押卷模考", value: "押卷模考"},
|
||||
{ key: "正式考试", label: "正式考试", value: "正式考试"},
|
||||
],
|
||||
passOptions: [
|
||||
{ key: true, label: "通过", value: true },
|
||||
|
@ -186,10 +196,19 @@ export default {
|
|||
value:'setTimeRange',
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
this.getQuery();
|
||||
},
|
||||
methods: {
|
||||
checkPermission,
|
||||
getQuery() {
|
||||
if(this.$route.params.exam){
|
||||
this.listQuery.exam = this.$route.params.exam;
|
||||
this.getList()
|
||||
}else{
|
||||
this.getList()
|
||||
}
|
||||
|
||||
},
|
||||
getList() {
|
||||
this.listLoading = true;
|
||||
getExamTestlist(this.listQuery).then(response => {
|
||||
|
@ -210,9 +229,17 @@ export default {
|
|||
this.value = []
|
||||
this.getList();
|
||||
},
|
||||
handleDetail(scope) {
|
||||
// this.dialogVisible = true
|
||||
// this.question = scope.row
|
||||
handleExport(scope) {
|
||||
const loading = this.$loading({text: '正在生成word...',});
|
||||
exportwTest(scope.row.id).then(res=>{
|
||||
loading.close()
|
||||
}).catch(e=>{loading.close()})
|
||||
},
|
||||
handleExport2(scope) {
|
||||
const loading = this.$loading({text: '正在重新生成word...',});
|
||||
exportwTest(scope.row.id, {anew:true}).then(res=>{
|
||||
loading.close()
|
||||
}).catch(e=>{loading.close()})
|
||||
},
|
||||
exportTest() {
|
||||
const loading = this.$loading();
|
||||
|
|
|
@ -242,6 +242,7 @@ export default {
|
|||
});
|
||||
},
|
||||
handleView(scope){
|
||||
this.$router.push({name:'ExamTest', params:{exam:scope.row.id}})
|
||||
|
||||
},
|
||||
async confirmexam(form) {
|
||||
|
|
|
@ -69,9 +69,9 @@ App({
|
|||
globalData: {
|
||||
userInfo: {},
|
||||
userinfo: {}, // 服务器传回的消费者信息
|
||||
//host: 'https://apitest.ahctc.cn',
|
||||
host: 'https://apitest.ahctc.cn',
|
||||
mediahost: 'https://apitest.ahctc.cn',
|
||||
host: 'http://127.0.0.1:8000',
|
||||
//host: 'http://127.0.0.1:8000',
|
||||
//mediahost: 'http://127.0.0.1:8000',
|
||||
token : '',
|
||||
}
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
"pages/material/video",
|
||||
"pages/qtest/form",
|
||||
"pages/main/start",
|
||||
"pages/exam/index"
|
||||
"pages/exam/index",
|
||||
"pages/exam/note"
|
||||
],
|
||||
"window": {
|
||||
"backgroundTextStyle": "light",
|
||||
|
|
|
@ -34,10 +34,14 @@ Page({
|
|||
})
|
||||
let exam = res.data.exam
|
||||
api.request(`/examtest/exam/${exam}/init/`,'POST', data).then(res=>{
|
||||
console.log(res.data)
|
||||
wx.hideLoading({
|
||||
success: (res) => {},
|
||||
})
|
||||
wx.hideLoading()
|
||||
try {
|
||||
wx.setStorageSync('examtest', res.data)
|
||||
} catch (e) { }
|
||||
wx.navigateTo({
|
||||
url: '/pages/exam/note',
|
||||
})
|
||||
|
||||
}).catch(e=>{
|
||||
wx.hideLoading({
|
||||
success: (res) => {},
|
||||
|
@ -55,7 +59,11 @@ Page({
|
|||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
wx.showLoading({
|
||||
title: '获取信息...',
|
||||
})
|
||||
api.request('/crm/consumer/info/','GET').then(res=>{
|
||||
wx.hideLoading()
|
||||
getApp().globalData.userinfo = res.data.userinfo
|
||||
this.setData(
|
||||
{
|
||||
|
@ -65,7 +73,7 @@ Page({
|
|||
},
|
||||
}
|
||||
)
|
||||
})
|
||||
}).catch(e=>{wx.hideLoading()})
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,9 +32,8 @@
|
|||
<label class="weui-label">部门</label>
|
||||
</view>
|
||||
<view class="weui-cell__bd">
|
||||
<span wx:if="{{userinfo.deptname}}">{{userinfo.deptname}}</span>
|
||||
<input wx:else class="weui-input" placeholder="填写您的部门" placeholder-class="weui-input__placeholder" bindinput="deptInput" >
|
||||
{{userinfo.deptname}}
|
||||
<!-- <span wx:if="{{userinfo.deptname}}">{{userinfo.deptname}}</span> -->
|
||||
<input class="weui-input" placeholder="填写您的部门" placeholder-class="weui-input__placeholder" bindinput="deptInput" value="{{form.deptname}}">
|
||||
</input>
|
||||
</view>
|
||||
</view>
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
// pages/exam/note.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
try {
|
||||
var value = wx.getStorageSync('examtest')
|
||||
if (value) {
|
||||
let examtest = value
|
||||
delete examtest['questions']
|
||||
this.setData(examtest)
|
||||
}
|
||||
} catch (e) { }
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage: function () {
|
||||
|
||||
},
|
||||
startTest: function () {
|
||||
wx.reLaunch({
|
||||
url: '/pages/test/test',
|
||||
})
|
||||
},
|
||||
})
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"usingComponents": {},
|
||||
"navigationBarTitleText": "考试须知"
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<view class="page">
|
||||
<view class="page__bd">
|
||||
<view class="weui-article">
|
||||
<view class="weui-article__h1" style="text-align:center">正式考试须知</view>
|
||||
<view class="weui-article__h2">1.考试信息</view>
|
||||
<view>名称:<span style="color:blue">{{exam_.name}}</span></view>
|
||||
<view>监考人:<span style="color:blue">{{exam_.proctor_name}}/{{exam_.proctor_phone}}</span></view>
|
||||
<view class="weui-article__h2">2.试卷信息</view>
|
||||
<view>答卷时长:<span style="color:red">{{limit}}分钟</span></view>
|
||||
<view wx:if="{{danxuan_count>0}}">{{danxuan_count}}道单选题,每题{{danxuan_score}}分</view>
|
||||
<view wx:if="{{duoxuan_count>0}}">{{duoxuan_count}}道多选题,每题{{duoxuan_score}}分</view>
|
||||
<view wx:if="{{panduan_count>0}}">{{panduan_count}}道判断题,每题{{panduan_score}}分</view>
|
||||
<view >多选题漏选每个正确选项得1分,错选0分</view>
|
||||
<view >满分{{total_score}};<span style="color:blue">{{pass_score}}</span>以上通过</view>
|
||||
<view class="weui-article__h2">3.答题须知</view>
|
||||
<view style="color:red">进入答题后请不要后退或返回桌面</view>
|
||||
<view>用户可点击上一题/下一题进行切换答题</view>
|
||||
<view>可点击答题卡复查</view>
|
||||
<view>请合理安排时间答题,可提前交卷,超时会自动提交</view>
|
||||
</view>
|
||||
<a class="weui-btn weui-btn_primary" bindtap="startTest">开始考试</a>
|
||||
</view>
|
||||
|
||||
</view>
|
|
@ -0,0 +1 @@
|
|||
/* pages/exam/note.wxss */
|
|
@ -18,7 +18,12 @@ Page({
|
|||
onLoad: function (options) {
|
||||
var that = this
|
||||
var query = {'examtest':options.id}
|
||||
wx.showLoading({
|
||||
title: '加载中...',
|
||||
mask:true
|
||||
})
|
||||
api.request('/examtest/answerdetail/', 'GET', query).then(res => {
|
||||
wx.hideLoading()
|
||||
for (var i = 0; i < res.data.length; i++) {
|
||||
if(res.data[i].img){
|
||||
res.data[i].img = getApp().globalData.mediahost + res.data[i].img
|
||||
|
@ -29,7 +34,7 @@ Page({
|
|||
that.setData({
|
||||
tmtotal:res.data.length
|
||||
})
|
||||
})
|
||||
}).catch(e=>{wx.hideLoading()})
|
||||
try {
|
||||
const res = wx.getSystemInfoSync()
|
||||
that.setData({
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// pages/lianxi/index.js
|
||||
const api = require("../../utils/request.js");
|
||||
var util = require('../../utils/util.js')
|
||||
Page({
|
||||
|
||||
/**
|
||||
|
@ -36,6 +37,9 @@ Page({
|
|||
getList: function () {
|
||||
var that = this
|
||||
api.request('/examtest/examtest/self/', 'GET', that.data.query).then(res => {
|
||||
for(var i=0;i<res.data.results.length;i++){
|
||||
res.data.results[i].took = util.formatSecond(res.data.results[i].took)
|
||||
}
|
||||
if (that.data.query.page == 1) {
|
||||
that.data.results = res.data.results
|
||||
} else {
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
<view class="weui-media-box__bd weui-media-box__bd_in-appmsg">
|
||||
<view class="weui-media-box__title">{{item.name}}</view>
|
||||
<view class="weui-media-box__desc">
|
||||
<span style="font-weight:bold;color:darkblue">{{item.type}}</span>
|
||||
<span style="font-weight:bold;color:brown;" wx:if="{{item.type=='正式考试'}}">{{item.type}}</span>
|
||||
<span style="font-weight:bold;color:darkblue" wx:else>{{item.type}}</span>
|
||||
<span>-</span>
|
||||
<span style="font-weight:bold;color:green;" wx:if="{{item.is_pass}}">通过</span>
|
||||
<span style="font-weight:bold;color:red;" wx:else>未通过</span>
|
||||
|
@ -18,7 +19,7 @@
|
|||
<span style="font-weight:bold">{{item.total_score}})</span>
|
||||
</view>
|
||||
<view class="weui-media-box__desc">
|
||||
耗时:{{item.took}}s
|
||||
耗时:{{item.took}}
|
||||
开始答题:{{item.start_time}}
|
||||
</view>
|
||||
</view>
|
||||
|
|
|
@ -150,6 +150,9 @@ Page({
|
|||
for(var i=0;i<tm_current.user_answer.length;i++){
|
||||
if(tm_current.right.indexOf(tm_current.user_answer[i])!=-1){
|
||||
score = score + 1
|
||||
if(score==2){
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
score = 0
|
||||
break;
|
||||
|
|
|
@ -2,8 +2,13 @@ from openpyxl.workbook import Workbook
|
|||
from django.conf import settings
|
||||
from datetime import datetime
|
||||
from openpyxl.styles import Font, Fill
|
||||
|
||||
|
||||
from rest_framework.serializers import Serializer
|
||||
from .models import ExamTest, AnswerDetail
|
||||
from django.http import HttpResponse
|
||||
from docxtpl import DocxTemplate
|
||||
from io import BytesIO
|
||||
from .serializers import ExamTestDetailSerializer
|
||||
import os
|
||||
BASE_DIR = settings.BASE_DIR
|
||||
|
||||
def export_test(tests):
|
||||
|
@ -23,3 +28,24 @@ def export_test(tests):
|
|||
path = '/media/export/' + filename
|
||||
wb.save((BASE_DIR + path).replace('\\', '/'))
|
||||
return path
|
||||
|
||||
def exportw_test(obj, bool):
|
||||
"""
|
||||
导出个人考试记录word版本
|
||||
"""
|
||||
filename = obj.exam.name + '-' + obj.consumer.name + '-' + obj.consumer.username + '.doc'
|
||||
path = '/media/export/' + filename
|
||||
fullpath = BASE_DIR + path
|
||||
if bool or (not os.path.exists(fullpath)):
|
||||
data = ExamTestDetailSerializer(instance=obj).data
|
||||
#开始生成word
|
||||
doc = DocxTemplate(BASE_DIR + "/tmp/examtest.docx")
|
||||
doc.render(data)
|
||||
doc.save(fullpath)
|
||||
# output = BytesIO()
|
||||
# doc.save(output)
|
||||
# output.seek(0)
|
||||
# res = HttpResponse(content_type='application/msword')
|
||||
# res['Content-Disposition'] = 'attachment;filename='+filename+'.docx'
|
||||
# res.write(output.getvalue())
|
||||
return path
|
|
@ -0,0 +1,25 @@
|
|||
# Generated by Django 3.0.4 on 2021-03-21 01:40
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('question', '0012_question_img'),
|
||||
('examtest', '0025_auto_20210314_1716'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='answerdetail',
|
||||
name='examtest',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='answerdetail_examtest', to='examtest.ExamTest'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='examtest',
|
||||
name='detail',
|
||||
field=models.ManyToManyField(through='examtest.AnswerDetail', to='question.Question', verbose_name='答题记录'),
|
||||
),
|
||||
]
|
|
@ -20,7 +20,8 @@ class Exam(CommonModel):
|
|||
proctor_phone = models.CharField('监考人联系方式', max_length=100)
|
||||
create_admin = models.ForeignKey(UserProfile, on_delete=models.SET_NULL, null=True, blank=True, related_name='exam_create_admin')
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class ExamTest(CommonModel):
|
||||
|
@ -43,7 +44,7 @@ class ExamTest(CommonModel):
|
|||
took = models.IntegerField(default=0, verbose_name='耗时(秒)')
|
||||
start_time = models.DateTimeField(verbose_name='开始答题时间')
|
||||
end_time = models.DateTimeField(verbose_name='结束答题时间')
|
||||
detail = models.ManyToManyField(Question, related_name='答题记录', through='AnswerDetail')
|
||||
detail = models.ManyToManyField(Question, verbose_name='答题记录', through='AnswerDetail')
|
||||
is_pass = models.BooleanField(default=True, verbose_name='是否通过')
|
||||
|
||||
exam = models.ForeignKey(Exam, verbose_name='关联的正式考试', null=True, blank=True, related_name='examtest_exam', on_delete= models.SET_NULL)
|
||||
|
@ -53,7 +54,7 @@ class ExamTest(CommonModel):
|
|||
|
||||
|
||||
class AnswerDetail(SoftCommonModel):
|
||||
examtest = models.ForeignKey(ExamTest, on_delete=models.CASCADE)
|
||||
examtest = models.ForeignKey(ExamTest, on_delete=models.CASCADE, related_name='answerdetail_examtest')
|
||||
question = models.ForeignKey(Question, on_delete=models.CASCADE)
|
||||
user_answer = JSONField(null=True,blank=True)
|
||||
score = models.FloatField(default=0, verbose_name='本题得分')
|
||||
|
|
|
@ -61,6 +61,7 @@ class ExamTestListSerializer(serializers.ModelSerializer):
|
|||
end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
|
||||
workscope_name = serializers.StringRelatedField(source='workscope', read_only=True)
|
||||
paper_name = serializers.StringRelatedField(source='paper', read_only=True)
|
||||
exam_name = serializers.StringRelatedField(source='exam', read_only=True)
|
||||
consumer_name = serializers.SerializerMethodField()
|
||||
took_format = serializers.SerializerMethodField()
|
||||
consumer_company_name = serializers.SerializerMethodField()
|
||||
|
@ -83,7 +84,7 @@ class ExamTestListSerializer(serializers.ModelSerializer):
|
|||
@staticmethod
|
||||
def setup_eager_loading(queryset):
|
||||
""" Perform necessary eager loading of data. """
|
||||
queryset = queryset.select_related('consumer','paper', 'workscope')
|
||||
queryset = queryset.select_related('consumer','paper', 'workscope', 'exam')
|
||||
return queryset
|
||||
from question.serializers import QuestionSerializer
|
||||
class AnswerDetailSerializer(serializers.ModelSerializer):
|
||||
|
@ -173,4 +174,45 @@ class ExamListSerializer(serializers.ModelSerializer):
|
|||
workscope_name = serializers.StringRelatedField(source='workscope')
|
||||
class Meta:
|
||||
model = Exam
|
||||
fields = '__all__'
|
||||
fields = '__all__'
|
||||
|
||||
class ExamSimpleSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Exam
|
||||
exclude = ('create_admin',)
|
||||
|
||||
class ConsumerSimpleSerializer(serializers.ModelSerializer):
|
||||
comanyname = serializers.StringRelatedField(source='company', read_only=True)
|
||||
class Meta:
|
||||
model = Consumer
|
||||
fields = ['id', 'name', 'ID_number1', 'comanyname', 'deptname', 'username']
|
||||
class ExamTestDetailSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
考试详情序列化(导出用)
|
||||
"""
|
||||
workscope_name = serializers.StringRelatedField(source='workscope', read_only=True)
|
||||
paper_name = serializers.StringRelatedField(source='paper', )
|
||||
took_format = serializers.SerializerMethodField()
|
||||
detail_ = serializers.SerializerMethodField()
|
||||
exam_ = ExamSimpleSerializer(source='exam', read_only=True)
|
||||
consumer_ = ConsumerSimpleSerializer(source='consumer', read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = ExamTest
|
||||
exclude = ('detail',)
|
||||
|
||||
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_detail_(self, obj):
|
||||
objs = obj.answerdetail_examtest.order_by('question__type')
|
||||
return AnswerDetailSerializer(instance=objs, many=True).data
|
||||
|
||||
@staticmethod
|
||||
def setup_eager_loading(queryset):
|
||||
""" Perform necessary eager loading of data. """
|
||||
queryset = queryset.select_related('consumer','paper', 'workscope', 'exam')
|
||||
queryset = queryset.prefetch_related('answerdetail_examtest')
|
||||
return queryset
|
|
@ -2,6 +2,7 @@ from datetime import datetime
|
|||
|
||||
from django.db.models import Avg
|
||||
from django.db.models.query import QuerySet
|
||||
from django.utils.translation import get_language_from_request
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from openpyxl import Workbook, load_workbook
|
||||
from rest_framework import status
|
||||
|
@ -10,6 +11,7 @@ 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.serializers import Serializer
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
|
||||
|
@ -20,14 +22,14 @@ from server import settings
|
|||
from utils.custom import CommonPagination
|
||||
from utils.mixins import OptimizationMixin
|
||||
|
||||
from .exports import export_test
|
||||
from .exports import export_test, exportw_test
|
||||
from .models import AnswerDetail, Banner, ExamTest, Exam
|
||||
from .models_paper import Paper, PaperQuestions, TestRule, WorkScope
|
||||
from .serializers import (
|
||||
AnswerDetailCreateSerializer, AnswerDetailSerializer, BannerSerializer,
|
||||
ExamTestListSerializer, MoniTestSerializer, PaperDetailSerializer,
|
||||
PaperQuestionsCreateSerializer, PaperSerializer, TestRuleSerializer,
|
||||
WorkScopeSerializer, ExamCreateUpdateSerializer, ExamListSerializer)
|
||||
WorkScopeSerializer, ExamCreateUpdateSerializer, ExamListSerializer, ExamTestDetailSerializer)
|
||||
from django.utils import timezone
|
||||
# Create your views here.
|
||||
|
||||
|
@ -77,8 +79,6 @@ class ExamViewSet(ModelViewSet):
|
|||
"""
|
||||
参加考试
|
||||
"""
|
||||
if request.user.role.name in ['游客', '注册用户']:
|
||||
return Response({'error':'无权参加考试,请联系老师'})
|
||||
if request.data.get('deptname', None):
|
||||
request.user.deptname = request.data['deptname']
|
||||
request.user.save()
|
||||
|
@ -87,6 +87,8 @@ class ExamViewSet(ModelViewSet):
|
|||
now = timezone.now()
|
||||
try:
|
||||
exam = Exam.objects.get(code=code, opentime__lt=now, closetime__gt=now)
|
||||
if ExamTest.objects.filter(exam=exam, consumer=request.user).exists():
|
||||
return Response({'error':'您已参加过该场考试'})
|
||||
return Response({'exam':exam.pk})
|
||||
except:
|
||||
return Response({'error':'考试编号不存在'})
|
||||
|
@ -103,7 +105,8 @@ class ExamViewSet(ModelViewSet):
|
|||
if workscope.name in ['医学Ⅲ类', '非医学Ⅲ类']:
|
||||
ret['name'] = obj.name
|
||||
ret['type'] = '正式考试' # 正式考试
|
||||
ret['exam'] = ExamListSerializer(instance=obj).data
|
||||
ret['exam'] = kwargs['pk']
|
||||
ret['exam_'] = ExamListSerializer(instance=obj).data
|
||||
ret['workscope'] = workscope.id
|
||||
ret['limit'] = 60
|
||||
ret['total_score'] = 120
|
||||
|
@ -347,7 +350,7 @@ class ExamTestViewSet(ModelViewSet):
|
|||
ordering = ['-create_time']
|
||||
search_fields = ('consumer__name', 'consumer__company__name')
|
||||
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
|
||||
filterset_fields = ['type','is_pass']
|
||||
filterset_fields = ['type','is_pass', 'exam']
|
||||
|
||||
def get_queryset(self):
|
||||
assert self.queryset is not None, (
|
||||
|
@ -431,6 +434,16 @@ class ExamTestViewSet(ModelViewSet):
|
|||
serializer = ExamTestListSerializer(instance=queryset, many=True)
|
||||
path = export_test(serializer.data)
|
||||
return Response({'path': path})
|
||||
|
||||
@action(methods=['post'], detail = True ,perms_map=[{'post':'export_test'}])
|
||||
def exportw(self, request, *args, **kwargs):
|
||||
obj = self.get_object()
|
||||
if 'anew' in request.data and request.data['anew']:
|
||||
# 是否需要重新生成
|
||||
path = exportw_test(obj, True)
|
||||
else:
|
||||
path = exportw_test(obj, False)
|
||||
# return res
|
||||
|
||||
class PaperViewSet(ModelViewSet):
|
||||
"""
|
||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue