testpaper

This commit is contained in:
caoqianming 2020-03-31 18:00:18 +08:00
parent 721d4353ef
commit b67903481b
19 changed files with 809 additions and 129 deletions

View File

@ -1,2 +1,3 @@
[0309/185402.553:WARNING:minidump_to_upload_parameters.cc(36)] duplicate key guid, discarding value e9fabbb7-863e-4ba9-aa01-bd9e2a892f87
[0309/185709.823:WARNING:minidump_to_upload_parameters.cc(36)] duplicate key guid, discarding value e9fabbb7-863e-4ba9-aa01-bd9e2a892f87
[0330/140108.513:WARNING:minidump_to_upload_parameters.cc(36)] duplicate key guid, discarding value 8c211a77-fb10-434c-a128-67f93c6c5458

View File

@ -84,3 +84,24 @@ export function getExamTestDetail(id){
method: 'get',
})
}
export function getPaperList(query) {
return request({
url: '/examtest/paper/',
method: 'get',
params: query
})
}
export function getPaperDetail(id){
return request({
url: `/examtest/paper/${id}/`,
method: 'get',
})
}
export function createPaper(data) {
return request({
url: '/examtest/paper/',
method: 'post',
data
})
}

View File

@ -164,6 +164,13 @@ export const asyncRoutes = [
meta: { title: '编辑工作类别', noCache: true, icon: '', perms: ['workscope_update']},
hidden: true
},
{
path: 'paper/create',
name: 'CreatePaper',
component: () => import('@/views/examtest/papercreate.vue'),
meta: { title: '新建押题试卷', noCache: true, icon: '', perms: ['paper_add']},
hidden: true
},
]
},
{

View File

@ -1,44 +1,23 @@
<template>
<div class="app-container">
<div style="margin-top:10px">
<el-select
v-model="listQuery.is_pass"
placeholder="是否通过"
clearable
style="width: 200px"
<el-input
v-model="listQuery.search"
placeholder="名称"
style="width: 200px;"
class="filter-item"
@change="handleFilter"
>
<el-option
v-for="item in passOptions"
:key="item.key"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-select
v-model="listQuery.type"
placeholder="模考类型"
clearable
style="width: 200px"
class="filter-item"
@change="handleFilter"
>
<el-option
v-for="item in typeOptions"
:key="item.key"
:label="item.label"
:value="item.value"
/>
</el-select>
@keyup.enter.native="handleSearch"
/>
<el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
<el-button
class="filter-item"
type="primary"
icon="el-icon-refresh-left"
@click="resetFilter"
>刷新重置</el-button>
<div style="margin-top:10px">
</div>
</div>
<div style="margin-top:10px">
<el-button type="primary" @click="handleAdd" icon="el-icon-plus">新增</el-button>
</div>
<el-table
:data="tableData.results"
@ -51,34 +30,36 @@
max-height="600"
>
<el-table-column type="index" width="50"></el-table-column>
<el-table-column align="left" label="类型">
<template slot-scope="scope">{{ scope.row.type }}</template>
</el-table-column>
<el-table-column align="left" label="消费者">
<template slot-scope="scope">{{ scope.row.consumer_name }}</template>
<el-table-column align="left" label="名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column align="left" label="工作类别">
<template slot-scope="scope">{{ scope.row.workscope_name }}</template>
</el-table-column>
<el-table-column align="left" label="押题卷">
<template slot-scope="scope">{{ scope.row.paper_name }}</template>
<el-table-column align="left" label="总分">
<template slot-scope="scope">{{ scope.row.total_score }}</template>
</el-table-column>
<el-table-column align="left" label="分">
<template slot-scope="scope">{{ scope.row.score }}</template>
<el-table-column align="left" label="通过分">
<template slot-scope="scope">{{ scope.row.pass_score }}</template>
</el-table-column>
<el-table-column align="left" label="耗时(秒)">
<template slot-scope="scope">{{ scope.row.took }}</template>
</el-table-column>
<el-table-column align="left" label="答题时间">
<template slot-scope="scope">{{ scope.row.start_time }}</template>
<el-table-column align="left" label="限时(分钟)">
<template slot-scope="scope">{{ scope.row.limit }}</template>
</el-table-column>
<el-table-column align="center" label="操作">
<template slot-scope="scope">
<el-button
type="primary"
size="small"
@click="handleDetail(scope)"
icon="el-icon-more"
@click="handleEdit(scope)"
icon="el-icon-edit"
:disabled="!checkPermission(['paper_update'])"
></el-button>
<el-button
type="danger"
size="small"
@click="handleDelete(scope)"
icon="el-icon-delete"
:disabled="!checkPermission(['paper_delete'])"
></el-button>
</template>
</el-table-column>
@ -94,7 +75,7 @@
</template>
<script>
import { getExamTestlist } from "@/api/examtest";
import { getPaperList } from "@/api/examtest";
import checkPermission from "@/utils/permission";
import Pagination from "@/components/Pagination";
@ -113,14 +94,6 @@ export default {
results:[],
},
listLoading: true,
typeOptions: [
{ key: "自助模考", label: "自助模考", value: "自助模考" },
{ key: "押卷模考", label: "押卷模考", value: "押卷模考"},
],
passOptions: [
{ key: true, label: "通过", value: true },
{ key: false, label: "未通过", value: false},
],
};
},
computed: {},
@ -131,15 +104,13 @@ export default {
checkPermission,
getList(query = this.listQuery) {
this.listLoading = true;
getExamTestlist(query).then(response => {
this.tableData = response.data;
getPaperList(query).then(response => {
if(response.data.results){
this.tableData = response.data;
}
this.listLoading = false;
});
},
handleFilter() {
this.listQuery.page = 1;
this.getList();
},
resetFilter() {
this.listQuery = {
page: 1,
@ -148,9 +119,15 @@ export default {
};
this.getList();
},
handleDetail(scope) {
// this.dialogVisible = true
// this.question = scope.row
handleSearch() {
this.listQuery.page = 1;
this.getList();
},
handleAdd() {
this.$router.push({path:"/sjmanage/paper/create"})
},
handleEdit(scope) {
this.$router.push({path:"/sjmanage/paper/update",query:{id:scope.row.id}})
},
}
};

View File

@ -0,0 +1,198 @@
<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.danxuan_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 @click="resetForm('Form')">重置</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 { createPaper, getWorkScopeAll } 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();
},
methods: {
getWorkScopeAll() {
getWorkScopeAll().then(response => {
this.workscopeData = genTree(response.data);
});
},
submitForm(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
this.submitLoding = true;
createPaper(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++) {
questions.push({id:this.questions[i].id,type:this.questions[i].type})
switch (this.questions[i].type) {
case "单选":
danxuan_count = danxuan_count + 1;
break;
case "多选":
duoxuan_count = duoxuan_count + 1;
break;
case "判断":
panduan_count = panduan_count + 1;
break;
}
}
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

@ -2,7 +2,7 @@
<div class="app-container">
<div style="margin-top:10px">
<el-cascader
v-model="listQuery.questioncat"
v-model="questioncatC"
:options="questioncatData"
clearable
style="width: 400px"
@ -189,7 +189,8 @@ export default {
{ key: 2, label: "多选", value: "多选"},
{ key: 3, label: "判断", value: "判断" }
],
question:{}
question:{},
questioncatC:[],
};
},
computed: {},
@ -239,8 +240,10 @@ export default {
});
},
handleFilter() {
if(Array.isArray(this.listQuery.questioncat)) {
this.listQuery.questioncat = this.listQuery.questioncat.pop()
if(this.questioncatC.length) {
this.listQuery.questioncat = this.questioncatC[this.questioncatC.length-1]
}else{
this.listQuery.questioncat = ''
}
this.listQuery.page = 1;
this.getList();
@ -257,22 +260,6 @@ export default {
this.dialogVisible = true
this.question = scope.row
},
// handleAdd() {
// this.questioncat = Object.assign({}, defaultObj);
// this.dialogType = "new";
// this.dialogVisible = true;
// this.$nextTick(() => {
// this.$refs["commonForm"].clearValidate();
// });
// },
// handleEdit(scope) {
// this.questioncat = Object.assign({}, scope.row); // copy obj
// this.dialogType = "edit";
// this.dialogVisible = true;
// this.$nextTick(() => {
// this.$refs["commonForm"].clearValidate();
// });
// },
handleDelete(scope) {
this.$confirm("确认删除该题目吗?将丢失数据!", "警告", {
confirmButtonText: "确认",
@ -291,42 +278,6 @@ export default {
// console.error(err);
});
},
// async confirm(form) {
// this.$refs[form].validate(valid => {
// if (valid) {
// const isEdit = this.dialogType === "edit";
// if (isEdit) {
// updateQuestioncat(this.questioncat.id, this.questioncat).then(
// () => {
// this.getList();
// this.dialogVisible = false;
// this.$notify({
// title: "",
// message: "",
// type: "success",
// duration: 2000
// });
// }
// );
// } else {
// createQuestioncat(this.questioncat).then(res => {
// // this.questioncat = res.data
// // this.tableData.unshift(this.questioncat)
// this.getList();
// this.dialogVisible = false;
// this.$notify({
// title: "",
// message: "",
// type: "success",
// duration: 2000
// });
// });
// }
// } else {
// return false;
// }
// });
// }
}
};
</script>

View File

@ -0,0 +1,225 @@
<template>
<el-dialog title="选取试题" :visible.sync="chooseVisible_" width="80%" >
<div style="margin-top:10px">
<el-cascader
v-model="questioncatC"
:options="questioncatData"
clearable
style="width: 400px"
@change="handleFilter"
></el-cascader>
<el-select
v-model="listQuery.type"
placeholder="题型"
clearable
style="width: 120px"
class="filter-item"
@change="handleFilter"
>
<el-option
v-for="item in typeOptions"
:key="item.key"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-input
v-model="search"
placeholder="输入题干进行搜索"
style="width: 200px;"
class="filter-item"
@keyup.enter.native="handleSearch"
/>
<el-button
class="filter-item"
type="primary"
icon="el-icon-search"
@click="handleSearch"
>搜索</el-button>
<el-button
class="filter-item"
type="primary"
icon="el-icon-refresh-left"
@click="resetFilter"
>刷新重置</el-button>
</div>
<div style="margin-top:10px">
</div>
<el-table
:data="tableData.results"
style="width: 100%;margin-top:10px;"
border
stripe
fit
v-loading="listLoading"
highlight-current-row
max-height="400"
ref="table"
>
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column align="left" label="题干">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column align="left" label="所属题库">
<template slot-scope="scope">{{ scope.row.questioncat_name }}</template>
</el-table-column>
<el-table-column align="left" label="题型">
<template slot-scope="scope">{{ scope.row.type }}</template>
</el-table-column>
<el-table-column align="left" label="难易度">
<template slot-scope="scope">{{ scope.row.level }}</template>
</el-table-column>
<el-table-column label="创建日期">
<template slot-scope="scope">
<span>{{ scope.row.create_time }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="操作">
<template slot-scope="scope">
<el-button
type="primary"
size="small"
@click="handleDetail(scope)"
icon="el-icon-more"
></el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="tableData.count>0"
:total="tableData.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.limit"
@pagination="getList"
/>
<el-dialog
title="题目详情"
:visible.sync="dialogVisible"
width="30%"
append-to-body>
<div>{{question.type}}</div>
<div>{{question.name}}</div>
<ul id="repeat">
<li v-for="(value,key,index) in question.options">
{{ key }}:{{value}}
</li>
</ul>
<div>正确答案{{question.right}}</div>
<div>{{question.resolution}}</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="dialogVisible = false"> </el-button>
</span>
</el-dialog>
<div style="text-align:left;">
<el-button type="primary" @click="choseQuestions('table')">选中</el-button>
</div>
</el-dialog>
</template>
<script>
import {
getQuestioncatAll,
getQuestionList,
} from "@/api/question";
import { genTree, deepClone } from "@/utils";
import Pagination from "@/components/Pagination";
const listQuery = {
page: 1,
limit: 20,
search:''
};
export default {
name:'Questionchoose',
components: { Pagination },
props: {
chooseVisible: Boolean,
},
data() {
return {
questioncat: {
id: "",
name: ""
},
listQuery: listQuery,
search:"",
tableData: {
count:0,
results:[]
},
questioncatData:[],
listLoading: true,
dialogVisible: false,
typeOptions: [
{ key: 1, label: "单选", value: "单选" },
{ key: 2, label: "多选", value: "多选"},
{ key: 3, label: "判断", value: "判断" }
],
question:{},
questioncatC:[]
};
},
computed: {
chooseVisible_: {
get() {
return this.chooseVisible;
},
set(val) {
this.$emit('closeDg',val);
}
}
},
created() {
this.getList();
this.getQuestioncatAll();
},
methods: {
getList(query = this.listQuery) {
this.listLoading = true;
getQuestionList(query).then(response => {
if(response.data.results){
this.tableData = response.data
}
this.listLoading = false;
});
},
getQuestioncatAll() {
getQuestioncatAll().then(response => {
this.questioncatData = genTree(response.data);
});
},
handleFilter() {
if(this.questioncatC.length) {
this.listQuery.questioncat = this.questioncatC[this.questioncatC.length-1]
}else{
this.listQuery.questioncat = ''
}
this.listQuery.page = 1;
this.getList();
},
resetFilter() {
this.search = ""
this.listQuery = listQuery
this.getList();
},
handleSearch() {
this.getList({ search: this.search });
},
handleDetail(scope) {
this.dialogVisible = true
this.question = scope.row
},
choseQuestions(table) {
const _selectData = this.$refs.table.selection
this.$emit('choseQ',_selectData);
this.$emit('closeDg',false);
this.$refs.table.clearSelection();
}
}
};
</script>

View File

@ -147,7 +147,9 @@ export default {
getList() {
this.listLoading = true
getBannerAll().then(response => {
if(response.data.length){
this.tableData = response.data;
}
this.listLoading = false
});
},

View File

@ -18,7 +18,8 @@
"pages/test/list",
"pages/my/index",
"pages/collect/main",
"pages/workscope/index"
"pages/workscope/index",
"pages/yati/index"
],
"window": {
"backgroundTextStyle": "light",

View File

@ -126,10 +126,17 @@ Page({
}
},
goYati: function () {
wx.showToast({
title: '暂未开放',
icon:'none'
})
if (getApp().globalData.userinfo.workscope) {
wx.navigateTo({
url: '/pages/yati/index',
})
} else {
wx.showToast({
title: '未开通权限\r\n请联系课程顾问',
icon: 'none',
duration: 2000
})
}
},
testList: function (){
wx.navigateTo({

View File

@ -0,0 +1,116 @@
// pages/lianxi/index.js
const api = require("../../utils/request.js");
Page({
/**
* 页面的初始数据
*/
data: {
paperData: [],
query:{
page:1,
limit:10
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function () {
if (getApp().globalData.userinfo.workscope) {
this.setData({
workscopeId: getApp().globalData.userinfo.workscope
})
} else {
wx.switchTab({
url: '/pages/main/main',
})
}
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
this.getList()
},
getList: function () {
var that = this
if (that.data.workscopeId) {
that.data.query.workscope = that.data.workscopeId
api.request('/examtest/paper/', 'GET', that.data.query).then(res => {
if (that.data.query.page == 1) {
that.data.paperData = res.data.results
} else {
that.data.paperData = that.data.paperData.concat(res.data.results)
}
that.setData({
paperData: that.data.paperData,
count: res.data.count
})
})
}
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
var that = this
that.data.query.page = 1;
that.getList();
wx.stopPullDownRefresh();
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
var that = this
if (that.data.count <= that.data.query.page * that.data.query.limit) {
wx.showToast({
title: '没有更多了',
icon: 'none'
})
} else {
that.data.query.page = that.data.query.page + 1
that.getList()
}
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
startLianxi: function (e) {
wx.navigateTo({
url: 'main?questioncat=' + e.currentTarget.id,
})
},
})

View File

@ -0,0 +1,4 @@
{
"usingComponents": {},
"navigationBarTitleText": "押题试卷"
}

View File

@ -0,0 +1,26 @@
<!--pages/lianxi/index.wxml-->
<view class="page">
<view class="page__bd">
<view class="weui-panel__hd">当前工作类别押题卷</view>
<view class="weui-panel__bd">
<block wx:for="{{paperData}}" wx:key="unique">
<view class="weui-media-box weui-media-box_appmsg">
<view class="weui-media-box__bd">
<h4 class="weui-media-box__title">{{item.name}}</h4>
<view class="weui-media-box__desc">
<span style="color:orange;font-weight:bold">{{item.workscope_name}}</span>
<!-- --共
<span style="color:darkblue;font-weight:bold">{{item.tmtotal}}</span>
道/已答
<span style="color:darkblue;font-weight:bold">{{item.ydtmtotal}}</span>
道 -->
</view>
<view class="weui-media-box__desc">
<a class="weui-btn weui-btn_mini weui-btn_primary" bindtap="startYati" id="{{item.id}}" >开始考试</a>
</view>
</view>
</view>
</block>
</view>
</view>
</view>

View File

@ -0,0 +1 @@
/* pages/yati/index.wxss */

View File

@ -0,0 +1,56 @@
# Generated by Django 3.0.4 on 2020-03-31 01:01
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('question', '0008_auto_20200325_0959'),
('examtest', '0017_banner'),
]
operations = [
migrations.AddField(
model_name='paper',
name='limit',
field=models.IntegerField(default=0, verbose_name='限时(分钟)'),
),
migrations.AddField(
model_name='paper',
name='pass_score',
field=models.FloatField(default=0, verbose_name='及格分数'),
),
migrations.AddField(
model_name='paper',
name='total_score',
field=models.FloatField(default=0, verbose_name='满分'),
),
migrations.AddField(
model_name='paper',
name='workscope',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='examtest.WorkScope', verbose_name='名称'),
),
migrations.CreateModel(
name='PaperQuestions',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_delete', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('score', models.FloatField(default=0, verbose_name='满分')),
('paper', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='examtest.Paper', verbose_name='试卷')),
('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='question.Question', verbose_name='试题')),
],
options={
'abstract': False,
},
),
migrations.AddField(
model_name='paper',
name='questions',
field=models.ManyToManyField(through='examtest.PaperQuestions', to='question.Question'),
),
]

View File

@ -0,0 +1,43 @@
# Generated by Django 3.0.4 on 2020-03-31 08:16
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('examtest', '0018_auto_20200331_0901'),
]
operations = [
migrations.AddField(
model_name='paper',
name='danxuan_count',
field=models.IntegerField(default=0, verbose_name='单选数量'),
),
migrations.AddField(
model_name='paper',
name='danxuan_score',
field=models.FloatField(default=0, verbose_name='单选分数'),
),
migrations.AddField(
model_name='paper',
name='duoxuan_count',
field=models.IntegerField(default=0, verbose_name='多选数量'),
),
migrations.AddField(
model_name='paper',
name='duoxuan_score',
field=models.FloatField(default=0, verbose_name='多选分数'),
),
migrations.AddField(
model_name='paper',
name='panduan_count',
field=models.IntegerField(default=0, verbose_name='判断数量'),
),
migrations.AddField(
model_name='paper',
name='panduan_score',
field=models.FloatField(default=0, verbose_name='判断分数'),
),
]

View File

@ -41,10 +41,17 @@ class WorkScope(SoftCommonModel):
class Paper(SoftCommonModel):
name = models.CharField(max_length=200, verbose_name='名称')
workscope = models.ForeignKey(WorkScope, on_delete=models.CASCADE, null=True, blank=True, verbose_name='名称')
questions = models.ManyToManyField(Question, through='PaperQuestions')
limit = models.IntegerField(default=0, verbose_name='限时(分钟)')
total_score = models.FloatField(default=0, verbose_name='满分')
pass_score = models.FloatField(default=0, verbose_name='及格分数')
danxuan_count = models.IntegerField(default=0, verbose_name='单选数量')
danxuan_score = models.FloatField(default=2, verbose_name='单选分数')
duoxuan_count = models.IntegerField(default=0, verbose_name='多选数量')
duoxuan_score = models.FloatField(default=4, verbose_name='多选分数')
panduan_count = models.IntegerField(default=0, verbose_name='判断数量')
panduan_score = models.FloatField(default=2, verbose_name='判断分数')
class PaperQuestions(CommonModel):
paper = models.ForeignKey(Paper, on_delete=models.CASCADE, verbose_name='试卷')

View File

@ -77,6 +77,12 @@ class AnswerDetailCreateSerializer(serializers.ModelSerializer):
class PaperSerializer(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)
class Meta:
model = Paper
exclude = ('questions',)
class PaperQuestionsCreateSerializer(serializers.ModelSerializer):
class Meta:
model = PaperQuestions
fields = '__all__'

View File

@ -20,7 +20,7 @@ from .models import ExamTest, AnswerDetail, Banner
from .models_paper import TestRule, WorkScope, Paper
from .serializers import (TestRuleSerializer, MoniTestSerializer, AnswerDetailSerializer,
ExamTestListSerializer, AnswerDetailCreateSerializer, WorkScopeSerializer,
BannerSerializer, PaperSerializer)
BannerSerializer, PaperSerializer, PaperQuestionsCreateSerializer)
from server import settings
from crm.authentication import ConsumerTokenAuthentication
from utils.custom import CommonPagination
@ -248,7 +248,38 @@ class PaperViewSet(ModelViewSet):
{'*': 'admin'}, {'*': 'Paper_all'}, {'get': 'Paper_list'}, {'post': 'Paper_create'},
{'put': 'Paper_update'}, {'delete': 'Paper_delete'})
queryset = Paper.objects.filter(is_delete=0).all().order_by("id")
pagination_class = CommonPagination
serializer_class = PaperSerializer
ordering_fields = ('id',)
ordering = ['id']
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['workscope']
search_fields = ('^name',)
def create(self, request, *args, **kwargs):
data = request.data
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
instance = serializer.save()
if 'questions' in data:
questions = []
for i in data['questions']:
question = {}
question['question'] = i['id']
question['paper'] = instance.id
if i['type'] == '单选':
question['score'] = instance.danxuan_score
elif i['type'] == '多选':
question['score'] = instance.duoxuan_score
elif i['type'] == '判断':
question['score'] = instance.panduan_score
questions.append(question)
serializer_detail = PaperQuestionsCreateSerializer(data=questions, many=True)
if serializer_detail.is_valid():
serializer_detail.save()
return Response(status=status.HTTP_200_OK)
else:
return Response(serializer_detail.errors)
else:
return Response({'error':'不存在题库'})