This commit is contained in:
caoqianming 2020-04-01 18:33:00 +08:00
parent b67903481b
commit ffa8f775c3
23 changed files with 479 additions and 123 deletions

View File

@ -104,4 +104,11 @@ export function createPaper(data) {
method: 'post', method: 'post',
data data
}) })
}
export function updatePaper(id, data) {
return request({
url: `/examtest/paper/${id}/`,
method: 'put',
data
})
} }

View File

@ -171,6 +171,13 @@ export const asyncRoutes = [
meta: { title: '新建押题试卷', noCache: true, icon: '', perms: ['paper_add']}, meta: { title: '新建押题试卷', noCache: true, icon: '', perms: ['paper_add']},
hidden: true hidden: true
}, },
{
path: 'paper/update',
name: 'UpdatePaper',
component: () => import('@/views/examtest/paperupdate.vue'),
meta: { title: '编辑押题试卷', noCache: true, icon: '', perms: ['paper_update']},
hidden: true
},
] ]
}, },
{ {

View File

@ -29,7 +29,7 @@
</div> </div>
<div> <div>
多选题 多选题
<span style="color:darkred;font-weight:bold">{{Form.danxuan_count}} </span> <span style="color:darkred;font-weight:bold">{{Form.duoxuan_count}} </span>
每道 每道
<el-input-number v-model="Form.duoxuan_score" :min="0"></el-input-number> <el-input-number v-model="Form.duoxuan_score" :min="0"></el-input-number>
</div> </div>
@ -172,18 +172,22 @@ export default {
panduan_count = 0, panduan_count = 0,
questions = []; questions = [];
for (var i = 0, len = this.questions.length; i < len; i++) { for (var i = 0, len = this.questions.length; i < len; i++) {
questions.push({id:this.questions[i].id,type:this.questions[i].type}) var total_score = 0
switch (this.questions[i].type) { switch (this.questions[i].type) {
case "单选": case "单选":
danxuan_count = danxuan_count + 1; danxuan_count = danxuan_count + 1;
total_score = this.Form.danxuan_score
break; break;
case "多选": case "多选":
duoxuan_count = duoxuan_count + 1; duoxuan_count = duoxuan_count + 1;
total_score = this.Form.duoxuan_score
break; break;
case "判断": case "判断":
panduan_count = panduan_count + 1; panduan_count = panduan_count + 1;
total_score = this.Form.panduan_score
break; break;
} }
questions.push({id:this.questions[i].id,type:this.questions[i].type,total_score:total_score})
} }
this.Form.danxuan_count = danxuan_count this.Form.danxuan_count = danxuan_count
this.Form.duoxuan_count = duoxuan_count this.Form.duoxuan_count = duoxuan_count

View File

@ -0,0 +1,209 @@
<template>
<div class="app-container">
<el-row>
<el-col :span="8">
<h3>基本信息</h3>
<el-form :model="Form" :rules="rules" ref="Form" label-width="100px" status-icon>
<el-form-item label="名称" prop="name">
<el-input v-model="Form.name" style="width:80%"></el-input>
</el-form-item>
<el-form-item label="工作类别">
<el-select v-model="Form.workscope" placeholder="工作类别" style="width:80%">
<el-option
v-for="item in workscopeData"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="时间限制" prop="limit">
<el-input-number v-model="Form.limit" :min="0"></el-input-number>分钟
</el-form-item>
<el-form-item label="试卷信息">
<div>
单选题
<span style="color:darkred;font-weight:bold">{{Form.danxuan_count}} </span>
每道
<el-input-number v-model="Form.danxuan_score" :min="0"></el-input-number>
</div>
<div>
多选题
<span style="color:darkred;font-weight:bold">{{Form.duoxuan_count}} </span>
每道
<el-input-number v-model="Form.duoxuan_score" :min="0"></el-input-number>
</div>
<div>
判断题
<span style="color:darkred;font-weight:bold">{{Form.panduan_count}} </span>
每道
<el-input-number v-model="Form.panduan_score" :min="0"></el-input-number>
</div>
<div>
总分
<span style="color:darkred;font-weight:bold">{{Form.total_score}}</span>
</div>
</el-form-item>
<el-form-item label="及格分数" prop="pass_score">
<el-input-number v-model="Form.pass_score" :min="0"></el-input-number>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('Form')" :loading="submitLoding">保存</el-button>
<el-button type="warning" @click="goBack()">返回</el-button>
</el-form-item>
</el-form>
</el-col>
<el-col :span="16">
<h3>选题信息</h3>
<el-button type="primary" @click="handleChoose" icon="el-icon-plus">选择试题</el-button>
<div v-for="(item, index) in questions">
<h4>
<el-button
type="danger"
size="small"
@click="handleDelete(index)"
icon="el-icon-delete"
></el-button>
{{ index+1 }} -
<el-tag>{{item.type}}</el-tag>
{{ item.name }}
<span>(正确答案:{{item.right}})</span>
</h4>
<div v-for="(value, name) in item.options">{{ name }}: {{ value }}</div>
</div>
</el-col>
</el-row>
<Questionchoose v-bind:chooseVisible="chooseVisible" @closeDg="closeDg" @choseQ="choseQ"></Questionchoose>
</div>
</template>
<script>
import { updatePaper, getWorkScopeAll, getPaperDetail } from "@/api/examtest";
import { genTree } from "@/utils";
import Questionchoose from "@/views/question/questionchoose";
export default {
components: { Questionchoose },
data() {
return {
questions: [],
Form: {
name: "",
workscope: null,
limit: 60,
total_score: 0,
pass_score: 72,
questions: [],
danxuan_score: 2,
danxuan_count: 0,
duoxuan_score: 4,
duoxuan_count: 0,
panduan_score: 2,
panduan_count: 0
},
submitLoding: false,
rules: {
name: [
{ required: true, message: "名称不能为空", trigger: "blur" }
// { min: 3, max: 5, message: ' 3 5 ', trigger: 'blur' }
],
limit: [
{ required: true, message: "时间限制不能为空" },
{ type: "number", message: "时间限制必须是数字" }
],
pass_score: [
{ required: true, message: "及格分数不能为空" },
{ type: "number", message: "及格分数必须是数字" }
]
},
workscopeData: [],
chooseVisible: false
};
},
watch: {
questions: "calScore"
},
created() {
this.getWorkScopeAll();
this.Form.id = this.$route.query.id //
this.getPaperDetail();
},
methods: {
getWorkScopeAll() {
getWorkScopeAll().then(response => {
this.workscopeData = genTree(response.data);
});
},
getPaperDetail() {
getPaperDetail(this.Form.id).then(response => {
this.Form = response.data ;
this.questions = response.data.questions
});
},
submitForm(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
this.submitLoding = true;
updatePaper(this.Form.id,this.Form).then(response => {
this.submitLoding = false;
this.$message({
type: "success",
message: "编辑成功!"
});
this.goBack();
});
} else {
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
goBack() {
this.$router.replace("/sjmanage/testpaper/");
},
handleChoose() {
this.chooseVisible = true;
},
closeDg(val) {
this.chooseVisible = val;
},
choseQ(val) {
this.questions = this.questions.concat(val);
},
handleDelete(val) {
this.questions.splice(val, 1);
},
calScore() {
let danxuan_count = 0,
duoxuan_count = 0,
panduan_count = 0,
questions = [];
for (var i = 0, len = this.questions.length; i < len; i++) {
var total_score = 0
switch (this.questions[i].type) {
case "单选":
danxuan_count = danxuan_count + 1;
total_score = this.Form.danxuan_score
break;
case "多选":
duoxuan_count = duoxuan_count + 1;
total_score = this.Form.duoxuan_score
break;
case "判断":
panduan_count = panduan_count + 1;
total_score = this.Form.panduan_score
break;
}
questions.push({id:this.questions[i].id,type:this.questions[i].type,total_score:total_score})
}
this.Form.danxuan_count = danxuan_count
this.Form.duoxuan_count = duoxuan_count
this.Form.panduan_count = panduan_count
let form = this.Form
let score = form.danxuan_count * form.danxuan_score + form.duoxuan_count * form.duoxuan_score + form.panduan_count * form.panduan_score
this.Form.total_score = score
this.Form.questions = questions
}
}
};
</script>

View File

@ -19,7 +19,7 @@
<template slot-scope="scope">{{ scope.row.name }}</template> <template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="图片"> <el-table-column label="图片">
<template scope="scope"> <template slot-scope="scope">
<img :src="scope.row.path" width="160" height="90" /> <img :src="scope.row.path" width="160" height="90" />
</template> </template>
</el-table-column> </el-table-column>

View File

@ -48,9 +48,9 @@ App({
globalData: { globalData: {
userInfo: null, userInfo: null,
userinfo: null, // 服务器传回的消费者信息 userinfo: null, // 服务器传回的消费者信息
// host: 'https://apitest.ctcshe.com', host: 'https://apitest.ctcshe.com',
mediahost: 'https://apitest.ctcshe.com', mediahost: 'https://apitest.ctcshe.com',
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 : '',
subject:null, subject:null,

View File

@ -8,7 +8,7 @@ Page({
*/ */
data: { data: {
Hei:0, Hei:0,
background: [], background: [app.globalData.mediahost + '/media/banner/1.jpg'],
indicatorDots: true, indicatorDots: true,
vertical: false, vertical: false,
autoplay: true, autoplay: true,

View File

@ -40,7 +40,7 @@
<view class="weui-grid__icon" > <view class="weui-grid__icon" >
<image src="/images/yati.svg" alt></image> <image src="/images/yati.svg" alt></image>
</view> </view>
<view class="weui-grid__label">押题考试</view> <view class="weui-grid__label">押卷模考</view>
</a> </a>
<a class="weui-grid" bindtap="testList"> <a class="weui-grid" bindtap="testList">
<view class="weui-grid__icon" > <view class="weui-grid__icon" >

View File

@ -79,7 +79,7 @@ Page({
}) })
api.request('/examtest/workscope/' + this.data.workId + '/monitest', 'GET').then(res => { api.request('/examtest/workscope/' + this.data.workId + '/monitest', 'GET').then(res => {
try { try {
wx.setStorageSync('monitest', res.data) wx.setStorageSync('examtest', res.data)
} catch (e) { } } catch (e) { }
wx.redirectTo({ wx.redirectTo({
url: 'note', url: 'note',

View File

@ -13,11 +13,11 @@ Page({
*/ */
onLoad: function () { onLoad: function () {
try { try {
var value = wx.getStorageSync('monitest') var value = wx.getStorageSync('examtest')
if (value) { if (value) {
let monitest = value let examtest = value
delete monitest['questions'] delete examtest['questions']
this.setData(monitest) this.setData(examtest)
} }
} catch (e) { } } catch (e) { }

View File

@ -32,7 +32,7 @@ Page({
* 生命周期函数--监听页面显示 * 生命周期函数--监听页面显示
*/ */
onShow: function () { onShow: function () {
api.request('/examtest/myexamtestfx', 'GET').then(res => { api.request('/examtest/examtest/fx/', 'GET').then(res => {
this.setData(res.data) this.setData(res.data)
}) })
}, },

View File

@ -36,7 +36,7 @@
>无</view> >无</view>
</view> </view>
<view class="weui-cell"> <view class="weui-cell">
<view class="weui-cell__bd">自助模考数</view> <view class="weui-cell__bd">模考数</view>
<view class="weui-cell__ft" style="font-weight:bold;color:darkblue">{{total}}</view> <view class="weui-cell__ft" style="font-weight:bold;color:darkblue">{{total}}</view>
</view> </view>
<view class="weui-cell"> <view class="weui-cell">

View File

@ -35,7 +35,7 @@ Page({
}, },
getList: function () { getList: function () {
var that = this var that = this
api.request('/examtest/myexamtest/', 'GET', that.data.query).then(res => { api.request('/examtest/examtest/self', 'GET', that.data.query).then(res => {
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

@ -27,9 +27,10 @@ Page({
onLoad: function () { onLoad: function () {
var that = this var that = this
try { try {
var value = wx.getStorageSync('monitest') var value = wx.getStorageSync('examtest')
console.log(value)
if (value) { if (value) {
that.data.monitest = value that.data.examtest = value
that.data.tms = value.questions that.data.tms = value.questions
that.setData({ that.setData({
tm_total:value.questions.length tm_total:value.questions.length
@ -50,7 +51,7 @@ Page({
that.data.ctms = value that.data.ctms = value
} }
} catch (e) { } } catch (e) { }
let mil = that.data.monitest.limit * 60 * 1000 let mil = that.data.examtest.limit * 60 * 1000
let starttimes = (new Date()).getTime() //时间戳 let starttimes = (new Date()).getTime() //时间戳
let endtimes = starttimes + mil let endtimes = starttimes + mil
that.data.starttimes = starttimes that.data.starttimes = starttimes
@ -244,20 +245,20 @@ Page({
that.data.tms[i].score = tm_result.score that.data.tms[i].score = tm_result.score
score = score + tm_result.score score = score + tm_result.score
} }
that.data.monitest.score = score that.data.examtest.score = score
if (score >= that.data.monitest.pass_score){ if (score >= that.data.examtest.pass_score){
that.data.monitest.is_pass = true that.data.examtest.is_pass = true
}else{ }else{
that.data.monitest.is_pass = false that.data.examtest.is_pass = false
} }
that.data.monitest.questions = that.data.tms that.data.examtest.questions = that.data.tms
that.data.monitest.start_time = util.formatTime(new Date(that.data.starttimes)) that.data.examtest.start_time = util.formatTime(new Date(that.data.starttimes))
that.data.monitest.end_time = util.formatTime(new Date()) that.data.examtest.end_time = util.formatTime(new Date())
that.data.monitest.took = Math.floor(((new Date()).getTime() - this.data.starttimes) / 1000) that.data.examtest.took = Math.floor(((new Date()).getTime() - this.data.starttimes) / 1000)
api.request('/examtest/monitest/', 'POST', that.data.monitest).then(res => { api.request('/examtest/examtest/', 'POST', that.data.examtest).then(res => {
getApp().globalData.testData = res.data getApp().globalData.testData = res.data
try { try {
wx.removeStorageSync('monitest') wx.removeStorageSync('examtest')
} catch (e) { } catch (e) {
} }
wx.redirectTo({ wx.redirectTo({

View File

@ -108,9 +108,17 @@ Page({
}, },
startLianxi: function (e) { startYati: function (e) {
wx.navigateTo({ wx.showLoading({
url: 'main?questioncat=' + e.currentTarget.id, title: '正在准备考试',
})
api.request('/examtest/paper/' + e.currentTarget.id +'/monitest/', 'GET').then(res => {
try {
wx.setStorageSync('examtest', res.data)
} catch (e) { }
wx.redirectTo({
url: '/pages/moni/note',
})
}) })
}, },
}) })

View File

@ -16,7 +16,7 @@
道 --> 道 -->
</view> </view>
<view class="weui-media-box__desc"> <view class="weui-media-box__desc">
<a class="weui-btn weui-btn_mini weui-btn_primary" bindtap="startYati" id="{{item.id}}" >开始考试</a> <a class="weui-btn weui-btn_mini weui-btn_primary" bindtap="startYati" id="{{item.id}}" >选择</a>
</view> </view>
</view> </view>
</view> </view>

View File

@ -0,0 +1,33 @@
# Generated by Django 3.0.4 on 2020-04-01 04:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('examtest', '0019_auto_20200331_1616'),
]
operations = [
migrations.RenameField(
model_name='paperquestions',
old_name='score',
new_name='total_score',
),
migrations.AlterField(
model_name='paper',
name='danxuan_score',
field=models.FloatField(default=2, verbose_name='单选分数'),
),
migrations.AlterField(
model_name='paper',
name='duoxuan_score',
field=models.FloatField(default=4, verbose_name='多选分数'),
),
migrations.AlterField(
model_name='paper',
name='panduan_score',
field=models.FloatField(default=2, verbose_name='判断分数'),
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 3.0.4 on 2020-04-01 08:16
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('examtest', '0020_auto_20200401_1210'),
]
operations = [
migrations.AlterModelOptions(
name='paper',
options={'verbose_name': '押题卷', 'verbose_name_plural': '押题卷'},
),
]

View File

@ -52,8 +52,13 @@ class Paper(SoftCommonModel):
duoxuan_score = models.FloatField(default=4, verbose_name='多选分数') duoxuan_score = models.FloatField(default=4, verbose_name='多选分数')
panduan_count = models.IntegerField(default=0, verbose_name='判断数量') panduan_count = models.IntegerField(default=0, verbose_name='判断数量')
panduan_score = models.FloatField(default=2, verbose_name='判断分数') panduan_score = models.FloatField(default=2, verbose_name='判断分数')
class Meta:
verbose_name = '押题卷'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class PaperQuestions(CommonModel): class PaperQuestions(CommonModel):
paper = models.ForeignKey(Paper, on_delete=models.CASCADE, verbose_name='试卷') paper = models.ForeignKey(Paper, on_delete=models.CASCADE, verbose_name='试卷')
question = models.ForeignKey(Question, on_delete=models.CASCADE, verbose_name='试题') question = models.ForeignKey(Question, on_delete=models.CASCADE, verbose_name='试题')
score = models.FloatField(default=0, verbose_name='满分') total_score = models.FloatField(default=0, verbose_name='满分')

View File

@ -3,7 +3,7 @@ from question.models import Questioncat
from crm.models import Consumer from crm.models import Consumer
from .models import ExamTest, AnswerDetail, Banner from .models import ExamTest, AnswerDetail, Banner
from .models_paper import TestRule, WorkScope, Paper, PaperQuestions from .models_paper import TestRule, WorkScope, Paper, PaperQuestions
from question.serializers import QuestionSerializer
class BannerSerializer(serializers.ModelSerializer): class BannerSerializer(serializers.ModelSerializer):
""" """
@ -35,7 +35,7 @@ class WorkScopeSerializer(serializers.ModelSerializer):
class MoniTestSerializer(serializers.ModelSerializer): class MoniTestSerializer(serializers.ModelSerializer):
""" """
自助模考序列化 模考序列化
""" """
start_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S") start_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S") end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
@ -81,8 +81,30 @@ class PaperSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Paper model = Paper
exclude = ('questions',) exclude = ('questions',)
class PaperQuestionsDetailSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(source='question.id')
name = serializers.ReadOnlyField(source='question.name')
options = serializers.ReadOnlyField(source='question.options')
right = serializers.ReadOnlyField(source='question.right')
type = serializers.ReadOnlyField(source='question.type')
level = serializers.ReadOnlyField(source='question.level')
class Meta:
model = PaperQuestions
fields = ('id','name','options','right','type','level','total_score')
class PaperDetailSerializer(serializers.ModelSerializer):
create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
workscope_name = serializers.StringRelatedField(source='workscope', read_only=True)
questions = PaperQuestionsDetailSerializer(source='paperquestions_set', many=True, read_only=True)
class Meta:
model = Paper
fields = '__all__'
class PaperQuestionsCreateSerializer(serializers.ModelSerializer): class PaperQuestionsCreateSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = PaperQuestions model = PaperQuestions
fields = '__all__' fields = '__all__'

View File

@ -1,5 +1,5 @@
from django.urls import path,include from django.urls import path,include
from .views import TestRuleViewSet, MoniTestView, MyExamTestView, AnswerDetailView, MyExamTestFxView, WorkScopeViewSet, BannerViewSet, ExamTestViewSet, PaperViewSet from .views import TestRuleViewSet, AnswerDetailView, WorkScopeViewSet, BannerViewSet, ExamTestViewSet, PaperViewSet
from rest_framework import routers from rest_framework import routers
@ -11,9 +11,6 @@ router.register('examtest', ExamTestViewSet, basename='examtest')
router.register('paper', PaperViewSet, basename='paper') router.register('paper', PaperViewSet, basename='paper')
urlpatterns = [ urlpatterns = [
path('monitest/',MoniTestView.as_view()),
path('myexamtest/',MyExamTestView.as_view()),
path('myexamtestfx/',MyExamTestFxView.as_view()),
path('answerdetail/', AnswerDetailView.as_view()), path('answerdetail/', AnswerDetailView.as_view()),
path('', include(router.urls)), path('', include(router.urls)),
] ]

View File

@ -17,67 +17,16 @@ from rbac.permission import RbacPermission
from question.models import Question from question.models import Question
from question.serializers import QuestionSerializer from question.serializers import QuestionSerializer
from .models import ExamTest, AnswerDetail, Banner from .models import ExamTest, AnswerDetail, Banner
from .models_paper import TestRule, WorkScope, Paper from .models_paper import TestRule, WorkScope, Paper, PaperQuestions
from .serializers import (TestRuleSerializer, MoniTestSerializer, AnswerDetailSerializer, from .serializers import (TestRuleSerializer, MoniTestSerializer, AnswerDetailSerializer,
ExamTestListSerializer, AnswerDetailCreateSerializer, WorkScopeSerializer, ExamTestListSerializer, AnswerDetailCreateSerializer, WorkScopeSerializer,
BannerSerializer, PaperSerializer, PaperQuestionsCreateSerializer) BannerSerializer, PaperSerializer, PaperQuestionsCreateSerializer, PaperDetailSerializer)
from server import settings from server import settings
from crm.authentication import ConsumerTokenAuthentication from crm.authentication import ConsumerTokenAuthentication
from utils.custom import CommonPagination from utils.custom import CommonPagination
# Create your views here. # Create your views here.
class MoniTestView(APIView):
authentication_classes = [ConsumerTokenAuthentication]
permission_classes = []
def post(self, request, *args, **kwargs):
serializer = MoniTestSerializer(data = request.data)
if serializer.is_valid():
instance = serializer.save(consumer = request.user)
if 'questions' in request.data:
questions = []
for i in request.data['questions']:
question = {}
question['question'] = i['id']
question['examtest'] = instance.id
question['score'] = i['score']
if 'user_answer' in i:
question['user_answer'] = i['user_answer']
question['is_right'] = i['is_right']
questions.append(question)
serializer_detail = AnswerDetailCreateSerializer(data=questions, many=True)
if serializer_detail.is_valid():
serializer_detail.save()
return Response(MoniTestSerializer(instance).data,status=status.HTTP_200_OK)
else:
return Response(serializer_detail.errors)
else:
return Response({'error':'答题记录不存在'})
else:
return Response(serializer.errors)
class MyExamTestView(APIView):
authentication_classes = [ConsumerTokenAuthentication]
permission_classes = []
def get(self, request, *args, **kwargs):
queryset = ExamTest.objects.filter(consumer=request.user).order_by('-create_time')
pg = CommonPagination()
p = pg.paginate_queryset(queryset=queryset,request=request,view=self)
serializer = ExamTestListSerializer(instance=p,many=True)
return pg.get_paginated_response(serializer.data)
class MyExamTestFxView(APIView):
authentication_classes = [ConsumerTokenAuthentication]
permission_classes = []
def get(self, request, *args, **kwargs):
queryset = ExamTest.objects.filter(consumer=request.user)
ret = {}
ret['total'] = queryset.count()
ret['avg_score'] = round(queryset.aggregate(avg=Avg('score'))['avg'])
ret['pass_rate'] = round(((queryset.filter(is_pass=True).count())/ret['total'])*100) if ret['total'] else 0
return Response(ret)
class AnswerDetailView(APIView): class AnswerDetailView(APIView):
authentication_classes = [] authentication_classes = []
@ -107,17 +56,11 @@ class WorkScopeViewSet(ModelViewSet):
search_fields = ('^name',) search_fields = ('^name',)
def get_authenticators(self): def get_authenticators(self):
"""
GET请求不做登陆验证
"""
if self.request.method == 'GET': if self.request.method == 'GET':
self.authentication_classes = [] self.authentication_classes = []
return [auth() for auth in self.authentication_classes] return [auth() for auth in self.authentication_classes]
def get_permissions(self): def get_permissions(self):
"""
GET请求不做权限验证
"""
if self.request.method == 'GET': if self.request.method == 'GET':
self.permission_classes = [] self.permission_classes = []
return [permission() for permission in self.permission_classes] return [permission() for permission in self.permission_classes]
@ -179,17 +122,11 @@ class BannerViewSet(ModelViewSet):
ordering = ['sort'] ordering = ['sort']
def get_authenticators(self): def get_authenticators(self):
"""
GET请求不做登陆验证
"""
if self.request.method == 'GET': if self.request.method == 'GET':
self.authentication_classes = [] self.authentication_classes = []
return [auth() for auth in self.authentication_classes] return [auth() for auth in self.authentication_classes]
def get_permissions(self): def get_permissions(self):
"""
GET请求不做权限验证
"""
if self.request.method == 'GET': if self.request.method == 'GET':
self.permission_classes = [] self.permission_classes = []
return [permission() for permission in self.permission_classes] return [permission() for permission in self.permission_classes]
@ -209,17 +146,11 @@ class TestRuleViewSet(ModelViewSet):
search_fields = ('^name',) search_fields = ('^name',)
def get_authenticators(self): def get_authenticators(self):
"""
GET请求不做登陆验证
"""
if self.request.method == 'GET': if self.request.method == 'GET':
self.authentication_classes = [] self.authentication_classes = []
return [auth() for auth in self.authentication_classes] return [auth() for auth in self.authentication_classes]
def get_permissions(self): def get_permissions(self):
"""
GET请求不做权限验证
"""
if self.request.method == 'GET': if self.request.method == 'GET':
self.permission_classes = [] self.permission_classes = []
return [permission() for permission in self.permission_classes] return [permission() for permission in self.permission_classes]
@ -231,14 +162,76 @@ class ExamTestViewSet(ModelViewSet):
perms_map = ( perms_map = (
{'*': 'admin'}, {'*': 'ExamTest_all'}, {'get': 'ExamTest_list'}) {'*': 'admin'}, {'*': 'ExamTest_all'}, {'get': 'ExamTest_list'})
pagination_class = CommonPagination pagination_class = CommonPagination
queryset = ExamTest.objects.filter(is_delete=0).all().order_by("id") queryset = ExamTest.objects.filter(is_delete=0).all()
serializer_class = ExamTestListSerializer serializer_class = ExamTestListSerializer
ordering_fields = ('id',) ordering_fields = ('id','create_time')
ordering = ['id'] ordering = ['-create_time']
search_fields = ('^name',) search_fields = ('^name',)
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['type','is_pass'] filterset_fields = ['type','is_pass']
def get_authenticators(self):
if self.request.method == 'POST':
self.authentication_classes = [ConsumerTokenAuthentication]
return [auth() for auth in self.authentication_classes]
def get_permissions(self):
if self.request.method == 'POST':
self.permission_classes = []
return [permission() for permission in self.permission_classes]
@action(methods=['get'], detail=False, authentication_classes=[ConsumerTokenAuthentication], permission_classes=[],
url_path='self', url_name='selftest')
def selftest(self, request, pk=None):
'''
个人考试记录
'''
queryset = ExamTest.objects.filter(consumer=request.user).order_by('-create_time')
pg = CommonPagination()
p = pg.paginate_queryset(queryset=queryset,request=request,view=self)
serializer = ExamTestListSerializer(instance=p,many=True)
return pg.get_paginated_response(serializer.data)
@action(methods=['get'], detail=False, authentication_classes=[ConsumerTokenAuthentication], permission_classes=[],
url_path='fx', url_name='selffx')
def selffx(self, request, pk=None):
'''
个人考试分析
'''
queryset = ExamTest.objects.filter(consumer=request.user)
ret = {}
ret['total'] = queryset.count()
ret['avg_score'] = round(queryset.aggregate(avg=Avg('score'))['avg'])
ret['pass_rate'] = round(((queryset.filter(is_pass=True).count())/ret['total'])*100) if ret['total'] else 0
return Response(ret)
def create(self, request, *args, **kwargs):
serializer = MoniTestSerializer(data = request.data)
if serializer.is_valid():
instance = serializer.save(consumer = request.user)
if 'questions' in request.data:
questions = []
for i in request.data['questions']:
question = {}
question['question'] = i['id']
question['examtest'] = instance.id
question['score'] = i['score']
if 'user_answer' in i:
question['user_answer'] = i['user_answer']
question['is_right'] = i['is_right']
questions.append(question)
serializer_detail = AnswerDetailCreateSerializer(data=questions, many=True)
if serializer_detail.is_valid():
serializer_detail.save()
return Response(MoniTestSerializer(instance).data,status=status.HTTP_200_OK)
else:
return Response(serializer_detail.errors)
else:
return Response({'error':'答题记录不存在'})
else:
return Response(serializer.errors)
class PaperViewSet(ModelViewSet): class PaperViewSet(ModelViewSet):
""" """
@ -256,6 +249,22 @@ class PaperViewSet(ModelViewSet):
filterset_fields = ['workscope'] filterset_fields = ['workscope']
search_fields = ('^name',) search_fields = ('^name',)
def get_authenticators(self):
if self.request.method == 'GET':
self.authentication_classes = []
return [auth() for auth in self.authentication_classes]
def get_permissions(self):
if self.request.method == 'GET':
self.permission_classes = []
return [permission() for permission in self.permission_classes]
def get_serializer_class(self):
if self.action=='list':
return PaperSerializer
else:
return PaperDetailSerializer
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
data = request.data data = request.data
serializer = self.get_serializer(data=data) serializer = self.get_serializer(data=data)
@ -267,12 +276,7 @@ class PaperViewSet(ModelViewSet):
question = {} question = {}
question['question'] = i['id'] question['question'] = i['id']
question['paper'] = instance.id question['paper'] = instance.id
if i['type'] == '单选': question['total_score'] = i['total_score']
question['score'] = instance.danxuan_score
elif i['type'] == '多选':
question['score'] = instance.duoxuan_score
elif i['type'] == '判断':
question['score'] = instance.panduan_score
questions.append(question) questions.append(question)
serializer_detail = PaperQuestionsCreateSerializer(data=questions, many=True) serializer_detail = PaperQuestionsCreateSerializer(data=questions, many=True)
if serializer_detail.is_valid(): if serializer_detail.is_valid():
@ -282,4 +286,46 @@ class PaperViewSet(ModelViewSet):
return Response(serializer_detail.errors) return Response(serializer_detail.errors)
else: else:
return Response({'error':'不存在题库'}) return Response({'error':'不存在题库'})
def update(self, request, *args, **kwargs):
data = request.data
instance = self.get_object()
serializer = self.get_serializer(instance, data=data)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
if 'questions' in data:
questions = []
for i in data['questions']:
question = {}
question['question'] = i['id']
question['paper'] = instance.id
question['total_score'] = i['total_score']
questions.append(question)
serializer_detail = PaperQuestionsCreateSerializer(data=questions, many=True)
if serializer_detail.is_valid():
PaperQuestions.objects.filter(paper=instance).delete()
serializer_detail.save()
return Response(status=status.HTTP_200_OK)
else:
return Response(serializer_detail.errors)
else:
return Response({'error':'不存在题库'})
@action(methods=['get'], detail=True, authentication_classes=[ConsumerTokenAuthentication], permission_classes=[],
url_path='monitest', url_name='gen_monitest')
def monitest(self, request, pk=None):
'''
生成押卷模拟考试
'''
ret = {}
paper = self.get_object()
serializer = PaperDetailSerializer(instance=paper)
ret = serializer.data
ret['name'] = '押卷模考' + datetime.now().strftime('%Y%m%d%H%M')
ret['type'] = '押卷模考'
ret['paper'] = paper.id
return Response(ret)

View File

@ -107,7 +107,7 @@ class QuestioncatViewSet(ModelViewSet):
@action(methods=['get'], detail=False, authentication_classes=[], permission_classes=[], @action(methods=['get'], detail=False, authentication_classes=[], permission_classes=[],
url_path='workscope', url_name='questioncat_workscope', pagination_class = None) url_path='workscope', url_name='questioncat_workscope', pagination_class = None)
def subject(self, request): def workscope(self, request):
""" """
工作类别下的全部分类 工作类别下的全部分类
""" """