正式考试完成

This commit is contained in:
caoqianming 2021-03-21 12:47:42 +08:00
parent 94ee6f844f
commit 27123fb3ec
22 changed files with 308 additions and 37 deletions

View File

@ -133,3 +133,11 @@ export function exportTest(query) {
params: query params: query
}) })
} }
export function exportwTest(id,data) {
return request({
url: `/examtest/examtest/${id}/exportw/`,
method: 'post',
data: data
})
}

View File

@ -18,7 +18,7 @@
</el-select> </el-select>
<el-select <el-select
v-model="listQuery.type" v-model="listQuery.type"
placeholder="考类型" placeholder="类型"
clearable clearable
style="width: 200px" style="width: 200px"
class="filter-item" class="filter-item"
@ -85,6 +85,9 @@
<el-table-column align="left" label="押题卷"> <el-table-column align="left" label="押题卷">
<template slot-scope="scope">{{ scope.row.paper_name }}</template> <template slot-scope="scope">{{ scope.row.paper_name }}</template>
</el-table-column> </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"> <el-table-column align="left" label="得分" sortable='custom' prop="score">
<template slot-scope="scope">{{ scope.row.score }}</template> <template slot-scope="scope">{{ scope.row.score }}</template>
</el-table-column> </el-table-column>
@ -94,14 +97,20 @@
<el-table-column align="left" label="答题时间"> <el-table-column align="left" label="答题时间">
<template slot-scope="scope">{{ scope.row.start_time }}</template> <template slot-scope="scope">{{ scope.row.start_time }}</template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="操作"> <el-table-column align="center" label="操作" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
v-if="scope.row.type=='正式考试'"
type="primary" type="primary"
size="small" size="small"
@click="handleDetail(scope)" @click="handleExport(scope)"
icon="el-icon-more" >生成Word</el-button>
></el-button> <el-button
v-if="scope.row.type=='正式考试'"
type="warning"
size="small"
@click="handleExport2(scope)"
>重新生成</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -116,7 +125,7 @@
</template> </template>
<script> <script>
import { getExamTestlist, exportTest } from "@/api/examtest"; import { getExamTestlist, exportTest, exportwTest } from "@/api/examtest";
import checkPermission from "@/utils/permission"; import checkPermission from "@/utils/permission";
import Pagination from "@/components/Pagination"; import Pagination from "@/components/Pagination";
@ -138,6 +147,7 @@ export default {
typeOptions: [ typeOptions: [
{ key: "自助模考", label: "自助模考", value: "自助模考" }, { key: "自助模考", label: "自助模考", value: "自助模考" },
{ key: "押卷模考", label: "押卷模考", value: "押卷模考"}, { key: "押卷模考", label: "押卷模考", value: "押卷模考"},
{ key: "正式考试", label: "正式考试", value: "正式考试"},
], ],
passOptions: [ passOptions: [
{ key: true, label: "通过", value: true }, { key: true, label: "通过", value: true },
@ -186,10 +196,19 @@ export default {
value:'setTimeRange', value:'setTimeRange',
}, },
created() { created() {
this.getList(); this.getQuery();
}, },
methods: { methods: {
checkPermission, checkPermission,
getQuery() {
if(this.$route.params.exam){
this.listQuery.exam = this.$route.params.exam;
this.getList()
}else{
this.getList()
}
},
getList() { getList() {
this.listLoading = true; this.listLoading = true;
getExamTestlist(this.listQuery).then(response => { getExamTestlist(this.listQuery).then(response => {
@ -210,9 +229,17 @@ export default {
this.value = [] this.value = []
this.getList(); this.getList();
}, },
handleDetail(scope) { handleExport(scope) {
// this.dialogVisible = true const loading = this.$loading({text: '正在生成word...',});
// this.question = scope.row 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() { exportTest() {
const loading = this.$loading(); const loading = this.$loading();

View File

@ -242,6 +242,7 @@ export default {
}); });
}, },
handleView(scope){ handleView(scope){
this.$router.push({name:'ExamTest', params:{exam:scope.row.id}})
}, },
async confirmexam(form) { async confirmexam(form) {

View File

@ -69,9 +69,9 @@ App({
globalData: { globalData: {
userInfo: {}, userInfo: {},
userinfo: {}, // 服务器传回的消费者信息 userinfo: {}, // 服务器传回的消费者信息
//host: 'https://apitest.ahctc.cn', host: 'https://apitest.ahctc.cn',
mediahost: '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', //mediahost: 'http://127.0.0.1:8000',
token : '', token : '',
} }

View File

@ -30,7 +30,8 @@
"pages/material/video", "pages/material/video",
"pages/qtest/form", "pages/qtest/form",
"pages/main/start", "pages/main/start",
"pages/exam/index" "pages/exam/index",
"pages/exam/note"
], ],
"window": { "window": {
"backgroundTextStyle": "light", "backgroundTextStyle": "light",

View File

@ -34,10 +34,14 @@ Page({
}) })
let exam = res.data.exam let exam = res.data.exam
api.request(`/examtest/exam/${exam}/init/`,'POST', data).then(res=>{ api.request(`/examtest/exam/${exam}/init/`,'POST', data).then(res=>{
console.log(res.data) wx.hideLoading()
wx.hideLoading({ try {
success: (res) => {}, wx.setStorageSync('examtest', res.data)
} catch (e) { }
wx.navigateTo({
url: '/pages/exam/note',
}) })
}).catch(e=>{ }).catch(e=>{
wx.hideLoading({ wx.hideLoading({
success: (res) => {}, success: (res) => {},
@ -55,7 +59,11 @@ Page({
* 生命周期函数--监听页面加载 * 生命周期函数--监听页面加载
*/ */
onLoad: function (options) { onLoad: function (options) {
wx.showLoading({
title: '获取信息...',
})
api.request('/crm/consumer/info/','GET').then(res=>{ api.request('/crm/consumer/info/','GET').then(res=>{
wx.hideLoading()
getApp().globalData.userinfo = res.data.userinfo getApp().globalData.userinfo = res.data.userinfo
this.setData( this.setData(
{ {
@ -65,7 +73,7 @@ Page({
}, },
} }
) )
}) }).catch(e=>{wx.hideLoading()})
}, },
/** /**

View File

@ -32,9 +32,8 @@
<label class="weui-label">部门</label> <label class="weui-label">部门</label>
</view> </view>
<view class="weui-cell__bd"> <view class="weui-cell__bd">
<span wx:if="{{userinfo.deptname}}">{{userinfo.deptname}}</span> <!-- <span wx:if="{{userinfo.deptname}}">{{userinfo.deptname}}</span> -->
<input wx:else class="weui-input" placeholder="填写您的部门" placeholder-class="weui-input__placeholder" bindinput="deptInput" > <input class="weui-input" placeholder="填写您的部门" placeholder-class="weui-input__placeholder" bindinput="deptInput" value="{{form.deptname}}">
{{userinfo.deptname}}
</input> </input>
</view> </view>
</view> </view>

View File

@ -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',
})
},
})

View File

@ -0,0 +1,4 @@
{
"usingComponents": {},
"navigationBarTitleText": "考试须知"
}

View File

@ -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>

View File

@ -0,0 +1 @@
/* pages/exam/note.wxss */

View File

@ -18,7 +18,12 @@ Page({
onLoad: function (options) { onLoad: function (options) {
var that = this var that = this
var query = {'examtest':options.id} var query = {'examtest':options.id}
wx.showLoading({
title: '加载中...',
mask:true
})
api.request('/examtest/answerdetail/', 'GET', query).then(res => { api.request('/examtest/answerdetail/', 'GET', query).then(res => {
wx.hideLoading()
for (var i = 0; i < res.data.length; i++) { for (var i = 0; i < res.data.length; i++) {
if(res.data[i].img){ if(res.data[i].img){
res.data[i].img = getApp().globalData.mediahost + res.data[i].img res.data[i].img = getApp().globalData.mediahost + res.data[i].img
@ -29,7 +34,7 @@ Page({
that.setData({ that.setData({
tmtotal:res.data.length tmtotal:res.data.length
}) })
}) }).catch(e=>{wx.hideLoading()})
try { try {
const res = wx.getSystemInfoSync() const res = wx.getSystemInfoSync()
that.setData({ that.setData({

View File

@ -1,5 +1,6 @@
// pages/lianxi/index.js // pages/lianxi/index.js
const api = require("../../utils/request.js"); const api = require("../../utils/request.js");
var util = require('../../utils/util.js')
Page({ Page({
/** /**
@ -36,6 +37,9 @@ Page({
getList: function () { getList: function () {
var that = this var that = this
api.request('/examtest/examtest/self/', 'GET', that.data.query).then(res => { 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) { if (that.data.query.page == 1) {
that.data.results = res.data.results that.data.results = res.data.results
} else { } else {

View File

@ -7,7 +7,8 @@
<view class="weui-media-box__bd weui-media-box__bd_in-appmsg"> <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__title">{{item.name}}</view>
<view class="weui-media-box__desc"> <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>-</span>
<span style="font-weight:bold;color:green;" wx:if="{{item.is_pass}}">通过</span> <span style="font-weight:bold;color:green;" wx:if="{{item.is_pass}}">通过</span>
<span style="font-weight:bold;color:red;" wx:else>未通过</span> <span style="font-weight:bold;color:red;" wx:else>未通过</span>
@ -18,7 +19,7 @@
<span style="font-weight:bold">{{item.total_score}})</span> <span style="font-weight:bold">{{item.total_score}})</span>
</view> </view>
<view class="weui-media-box__desc"> <view class="weui-media-box__desc">
耗时:{{item.took}}s 耗时:{{item.took}}
开始答题:{{item.start_time}} 开始答题:{{item.start_time}}
</view> </view>
</view> </view>

View File

@ -150,6 +150,9 @@ Page({
for(var i=0;i<tm_current.user_answer.length;i++){ for(var i=0;i<tm_current.user_answer.length;i++){
if(tm_current.right.indexOf(tm_current.user_answer[i])!=-1){ if(tm_current.right.indexOf(tm_current.user_answer[i])!=-1){
score = score + 1 score = score + 1
if(score==2){
break;
}
}else{ }else{
score = 0 score = 0
break; break;

View File

@ -2,8 +2,13 @@ from openpyxl.workbook import Workbook
from django.conf import settings from django.conf import settings
from datetime import datetime from datetime import datetime
from openpyxl.styles import Font, Fill 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 BASE_DIR = settings.BASE_DIR
def export_test(tests): def export_test(tests):
@ -23,3 +28,24 @@ def export_test(tests):
path = '/media/export/' + filename path = '/media/export/' + filename
wb.save((BASE_DIR + path).replace('\\', '/')) wb.save((BASE_DIR + path).replace('\\', '/'))
return path 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

View File

@ -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='答题记录'),
),
]

View File

@ -20,7 +20,8 @@ class Exam(CommonModel):
proctor_phone = models.CharField('监考人联系方式', max_length=100) 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') 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): class ExamTest(CommonModel):
@ -43,7 +44,7 @@ class ExamTest(CommonModel):
took = models.IntegerField(default=0, verbose_name='耗时(秒)') took = models.IntegerField(default=0, verbose_name='耗时(秒)')
start_time = models.DateTimeField(verbose_name='开始答题时间') start_time = models.DateTimeField(verbose_name='开始答题时间')
end_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='是否通过') 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) 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): 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) question = models.ForeignKey(Question, on_delete=models.CASCADE)
user_answer = JSONField(null=True,blank=True) user_answer = JSONField(null=True,blank=True)
score = models.FloatField(default=0, verbose_name='本题得分') score = models.FloatField(default=0, verbose_name='本题得分')

View File

@ -61,6 +61,7 @@ class ExamTestListSerializer(serializers.ModelSerializer):
end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S") end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
workscope_name = serializers.StringRelatedField(source='workscope', read_only=True) workscope_name = serializers.StringRelatedField(source='workscope', read_only=True)
paper_name = serializers.StringRelatedField(source='paper', 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() consumer_name = serializers.SerializerMethodField()
took_format = serializers.SerializerMethodField() took_format = serializers.SerializerMethodField()
consumer_company_name = serializers.SerializerMethodField() consumer_company_name = serializers.SerializerMethodField()
@ -83,7 +84,7 @@ class ExamTestListSerializer(serializers.ModelSerializer):
@staticmethod @staticmethod
def setup_eager_loading(queryset): def setup_eager_loading(queryset):
""" Perform necessary eager loading of data. """ """ Perform necessary eager loading of data. """
queryset = queryset.select_related('consumer','paper', 'workscope') queryset = queryset.select_related('consumer','paper', 'workscope', 'exam')
return queryset return queryset
from question.serializers import QuestionSerializer from question.serializers import QuestionSerializer
class AnswerDetailSerializer(serializers.ModelSerializer): class AnswerDetailSerializer(serializers.ModelSerializer):
@ -174,3 +175,44 @@ class ExamListSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Exam 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

View File

@ -2,6 +2,7 @@ from datetime import datetime
from django.db.models import Avg from django.db.models import Avg
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from django.utils.translation import get_language_from_request
from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework import DjangoFilterBackend
from openpyxl import Workbook, load_workbook from openpyxl import Workbook, load_workbook
from rest_framework import status 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.generics import GenericAPIView
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.serializers import Serializer
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from rest_framework_jwt.authentication import JSONWebTokenAuthentication from rest_framework_jwt.authentication import JSONWebTokenAuthentication
@ -20,14 +22,14 @@ from server import settings
from utils.custom import CommonPagination from utils.custom import CommonPagination
from utils.mixins import OptimizationMixin 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 import AnswerDetail, Banner, ExamTest, Exam
from .models_paper import Paper, PaperQuestions, TestRule, WorkScope from .models_paper import Paper, PaperQuestions, TestRule, WorkScope
from .serializers import ( from .serializers import (
AnswerDetailCreateSerializer, AnswerDetailSerializer, BannerSerializer, AnswerDetailCreateSerializer, AnswerDetailSerializer, BannerSerializer,
ExamTestListSerializer, MoniTestSerializer, PaperDetailSerializer, ExamTestListSerializer, MoniTestSerializer, PaperDetailSerializer,
PaperQuestionsCreateSerializer, PaperSerializer, TestRuleSerializer, PaperQuestionsCreateSerializer, PaperSerializer, TestRuleSerializer,
WorkScopeSerializer, ExamCreateUpdateSerializer, ExamListSerializer) WorkScopeSerializer, ExamCreateUpdateSerializer, ExamListSerializer, ExamTestDetailSerializer)
from django.utils import timezone from django.utils import timezone
# Create your views here. # 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): if request.data.get('deptname', None):
request.user.deptname = request.data['deptname'] request.user.deptname = request.data['deptname']
request.user.save() request.user.save()
@ -87,6 +87,8 @@ class ExamViewSet(ModelViewSet):
now = timezone.now() now = timezone.now()
try: try:
exam = Exam.objects.get(code=code, opentime__lt=now, closetime__gt=now) 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}) return Response({'exam':exam.pk})
except: except:
return Response({'error':'考试编号不存在'}) return Response({'error':'考试编号不存在'})
@ -103,7 +105,8 @@ class ExamViewSet(ModelViewSet):
if workscope.name in ['医学Ⅲ类', '非医学Ⅲ类']: if workscope.name in ['医学Ⅲ类', '非医学Ⅲ类']:
ret['name'] = obj.name ret['name'] = obj.name
ret['type'] = '正式考试' # 正式考试 ret['type'] = '正式考试' # 正式考试
ret['exam'] = ExamListSerializer(instance=obj).data ret['exam'] = kwargs['pk']
ret['exam_'] = ExamListSerializer(instance=obj).data
ret['workscope'] = workscope.id ret['workscope'] = workscope.id
ret['limit'] = 60 ret['limit'] = 60
ret['total_score'] = 120 ret['total_score'] = 120
@ -347,7 +350,7 @@ class ExamTestViewSet(ModelViewSet):
ordering = ['-create_time'] ordering = ['-create_time']
search_fields = ('consumer__name', 'consumer__company__name') search_fields = ('consumer__name', 'consumer__company__name')
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['type','is_pass'] filterset_fields = ['type','is_pass', 'exam']
def get_queryset(self): def get_queryset(self):
assert self.queryset is not None, ( assert self.queryset is not None, (
@ -432,6 +435,16 @@ class ExamTestViewSet(ModelViewSet):
path = export_test(serializer.data) path = export_test(serializer.data)
return Response({'path': path}) 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): class PaperViewSet(ModelViewSet):
""" """
押题卷增删改查 押题卷增删改查

Binary file not shown.

Binary file not shown.