monitest complete
This commit is contained in:
parent
54ee7e06f1
commit
fc66951a17
|
@ -16,7 +16,7 @@
|
||||||
:value="item.value"
|
:value="item.value"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-select
|
<!-- <el-select
|
||||||
v-model="listQuery.is_paid"
|
v-model="listQuery.is_paid"
|
||||||
placeholder="是否缴费"
|
placeholder="是否缴费"
|
||||||
clearable
|
clearable
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
:label="item.display_name"
|
:label="item.display_name"
|
||||||
:value="item.key"
|
:value="item.key"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select> -->
|
||||||
<el-input
|
<el-input
|
||||||
v-model="search"
|
v-model="search"
|
||||||
placeholder="姓名"
|
placeholder="姓名"
|
||||||
|
@ -96,10 +96,14 @@
|
||||||
v-if="scope.row.company_name != null"
|
v-if="scope.row.company_name != null"
|
||||||
>{{ scope.row.company_name }}</template>
|
>{{ scope.row.company_name }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" label="是否付费">
|
<el-table-column align="center" label="缴费科目">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope" >
|
||||||
<el-tag type="success" v-if="scope.row.is_paid">已付费</el-tag>
|
<el-tag
|
||||||
<el-tag type="danger" v-else>未付费</el-tag>
|
v-for="item in scope.row.subjects"
|
||||||
|
:key="item.id"
|
||||||
|
effect="dark">
|
||||||
|
{{ item.name }}
|
||||||
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="创建日期">
|
<el-table-column label="创建日期">
|
||||||
|
@ -153,7 +157,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="单位" prop="company">
|
<el-form-item label="单位" prop="company">
|
||||||
<el-cascader
|
<el-cascader
|
||||||
v-model="consumer.company"
|
v-model="consumer.company.id"
|
||||||
:options="companyData"
|
:options="companyData"
|
||||||
:props="{ checkStrictly: true }"
|
:props="{ checkStrictly: true }"
|
||||||
clearable
|
clearable
|
||||||
|
@ -188,8 +192,10 @@ const defaultConsumer = {
|
||||||
id: "",
|
id: "",
|
||||||
name: "",
|
name: "",
|
||||||
username: "",
|
username: "",
|
||||||
company: null,
|
company: {
|
||||||
is_paid: false
|
id:0,
|
||||||
|
name:''
|
||||||
|
},
|
||||||
};
|
};
|
||||||
const listQuery = {
|
const listQuery = {
|
||||||
page: 1,
|
page: 1,
|
||||||
|
@ -206,13 +212,7 @@ export default {
|
||||||
return {
|
return {
|
||||||
uploadUrl: uploadUrl(),
|
uploadUrl: uploadUrl(),
|
||||||
popovervisible: false,
|
popovervisible: false,
|
||||||
consumer: {
|
consumer: defaultConsumer,
|
||||||
id: "",
|
|
||||||
name: "",
|
|
||||||
username: "",
|
|
||||||
company: null,
|
|
||||||
ispaid: false
|
|
||||||
},
|
|
||||||
myHeaders: { Authorization: "JWT " + getToken() },
|
myHeaders: { Authorization: "JWT " + getToken() },
|
||||||
consumerList: [],
|
consumerList: [],
|
||||||
total: 0,
|
total: 0,
|
||||||
|
@ -345,7 +345,9 @@ export default {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
const isEdit = this.dialogType === "edit";
|
const isEdit = this.dialogType === "edit";
|
||||||
if (isEdit) {
|
if (isEdit) {
|
||||||
updateConsumer(this.consumer.id, this.consumer).then(() => {
|
let consumer = this.consumer
|
||||||
|
consumer.company = consumer.company.id
|
||||||
|
updateConsumer(this.consumer.id, consumer).then(() => {
|
||||||
for (let index = 0; index < this.consumerList.length; index++) {
|
for (let index = 0; index < this.consumerList.length; index++) {
|
||||||
if (this.consumerList[index].id === this.consumer.id) {
|
if (this.consumerList[index].id === this.consumer.id) {
|
||||||
this.consumerList.splice(
|
this.consumerList.splice(
|
||||||
|
@ -365,8 +367,10 @@ export default {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.consumer.company = this.consumer.company.pop();
|
this.consumer.company.id = this.consumer.company.id.pop();
|
||||||
createConsumer(this.consumer).then(res => {
|
let consumer = this.consumer
|
||||||
|
consumer.company = consumer.company.id
|
||||||
|
createConsumer(consumer).then(res => {
|
||||||
// this.consumer = res.data
|
// this.consumer = res.data
|
||||||
// this.consumerList.unshift(this.consumer)
|
// this.consumerList.unshift(this.consumer)
|
||||||
this.getList();
|
this.getList();
|
||||||
|
|
|
@ -11,7 +11,11 @@
|
||||||
"pages/cuoti/index",
|
"pages/cuoti/index",
|
||||||
"pages/moni/index",
|
"pages/moni/index",
|
||||||
"pages/moni/note",
|
"pages/moni/note",
|
||||||
"pages/test/test"
|
"pages/test/test",
|
||||||
|
"pages/test/result",
|
||||||
|
"pages/test/detail",
|
||||||
|
"pages/test/sheet",
|
||||||
|
"pages/test/list"
|
||||||
],
|
],
|
||||||
"window": {
|
"window": {
|
||||||
"backgroundTextStyle": "light",
|
"backgroundTextStyle": "light",
|
||||||
|
|
|
@ -8,20 +8,20 @@ Page({
|
||||||
*/
|
*/
|
||||||
data: {
|
data: {
|
||||||
ctms: [],
|
ctms: [],
|
||||||
tmIndex: 0,
|
tm_index: 0,
|
||||||
isright:false,
|
isright:false,
|
||||||
answerP:false
|
answerP:false
|
||||||
},
|
},
|
||||||
radioChange: function (e) {
|
radioChange: function (e) {
|
||||||
var that = this
|
var that = this
|
||||||
that.data.currentTm['user_answer'] = e.detail.value
|
that.data.currentTm['user_answer'] = e.detail.value
|
||||||
that.data.ctms[that.data.tmIndex] = that.data.currentTm
|
that.data.ctms[that.data.tm_index] = that.data.currentTm
|
||||||
that.showAnswer()
|
that.showAnswer()
|
||||||
},
|
},
|
||||||
checkboxChange: function (e) {
|
checkboxChange: function (e) {
|
||||||
var that = this
|
var that = this
|
||||||
that.data.currentTm['user_answer'] = e.detail.value
|
that.data.currentTm['user_answer'] = e.detail.value
|
||||||
that.data.ctms[that.data.tmIndex] = that.data.currentTm
|
that.data.ctms[that.data.tm_index] = that.data.currentTm
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 生命周期函数--监听页面加载
|
* 生命周期函数--监听页面加载
|
||||||
|
@ -64,7 +64,7 @@ Page({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}else{
|
}else{
|
||||||
that.showTm(that.data.tmIndex)
|
that.showTm(that.data.tm_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -123,7 +123,7 @@ Page({
|
||||||
var that = this
|
var that = this
|
||||||
var currentTm = that.data.ctms[index]
|
var currentTm = that.data.ctms[index]
|
||||||
that.setData({
|
that.setData({
|
||||||
'tmIndex': index,
|
'tm_index': index,
|
||||||
'tmtotal':that.data.ctms.length,
|
'tmtotal':that.data.ctms.length,
|
||||||
'currentTm': currentTm
|
'currentTm': currentTm
|
||||||
})
|
})
|
||||||
|
@ -165,13 +165,13 @@ Page({
|
||||||
},
|
},
|
||||||
next: function () {
|
next: function () {
|
||||||
var that = this
|
var that = this
|
||||||
var tmIndex = that.data.tmIndex + 1
|
var tm_index = that.data.tm_index + 1
|
||||||
that.showTm(tmIndex)
|
that.showTm(tm_index)
|
||||||
},
|
},
|
||||||
previous: function () {
|
previous: function () {
|
||||||
var that = this
|
var that = this
|
||||||
var tmIndex = that.data.tmIndex - 1
|
var tm_index = that.data.tm_index - 1
|
||||||
that.showTm(tmIndex)
|
that.showTm(tm_index)
|
||||||
},
|
},
|
||||||
showOptions: function () {
|
showOptions: function () {
|
||||||
let currentTm = this.data.currentTm
|
let currentTm = this.data.currentTm
|
||||||
|
@ -195,7 +195,7 @@ Page({
|
||||||
},
|
},
|
||||||
remove: function () {
|
remove: function () {
|
||||||
var that = this
|
var that = this
|
||||||
var index = that.data.tmIndex
|
var index = that.data.tm_index
|
||||||
that.data.ctms.splice(index,1)
|
that.data.ctms.splice(index,1)
|
||||||
if(that.data.ctms.length>index){
|
if(that.data.ctms.length>index){
|
||||||
that.showTm(index)
|
that.showTm(index)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<view class="head">
|
<view class="head">
|
||||||
题量: {{tmIndex+1}}/{{tmtotal}}
|
题量: {{tm_index+1}}/{{tmtotal}}
|
||||||
</view>
|
</view>
|
||||||
<scroll-view scroll-y="true" style="height: {{scrollHeight}}px;">
|
<scroll-view scroll-y="true" style="height: {{scrollHeight}}px;">
|
||||||
<view class="weui-article">
|
<view class="weui-article">
|
||||||
<view class="weui-article__h2">{{tmIndex+1}}.
|
<view class="weui-article__h2">{{tm_index+1}}.
|
||||||
<span class="txlabel">{{currentTm.type}}</span>
|
<span class="txlabel">{{currentTm.type}}</span>
|
||||||
</view>
|
</view>
|
||||||
<view style="text-align:center">
|
<view style="text-align:center">
|
||||||
|
@ -52,10 +52,10 @@
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
<view class="btns">
|
<view class="btns">
|
||||||
<view style="width:25%">
|
<view style="width:25%">
|
||||||
<button type="primary" size="mini" bindtap="previous" disabled="{{tmIndex==0}}">上题</button>
|
<button type="primary" size="mini" bindtap="previous" disabled="{{tm_index==0}}">上题</button>
|
||||||
</view>
|
</view>
|
||||||
<view style="width:25%">
|
<view style="width:25%">
|
||||||
<button type="primary" size="mini" bindtap="next" disabled="{{tmIndex==tmtotal-1}}">下题</button>
|
<button type="primary" size="mini" bindtap="next" disabled="{{tm_index==tmtotal-1}}">下题</button>
|
||||||
</view>
|
</view>
|
||||||
<view style="width:25%">
|
<view style="width:25%">
|
||||||
<button type="primary" size="mini" bindtap="showAnswer">答案</button>
|
<button type="primary" size="mini" bindtap="showAnswer">答案</button>
|
||||||
|
|
|
@ -11,14 +11,14 @@ Page({
|
||||||
tms:[],
|
tms:[],
|
||||||
ydtms:[],
|
ydtms:[],
|
||||||
ctms:[],
|
ctms:[],
|
||||||
tmIndex: 0,
|
tm_index: 0,
|
||||||
answerP: false,
|
answerP: false,
|
||||||
isLoad:true,
|
isLoad:true,
|
||||||
},
|
},
|
||||||
radioChange: function (e) {
|
radioChange: function (e) {
|
||||||
var that = this
|
var that = this
|
||||||
that.data.tm_current['user_answer'] = e.detail.value
|
that.data.tm_current['user_answer'] = e.detail.value
|
||||||
that.data.tms[that.data.tmIndex] = that.data.tm_current
|
that.data.tms[that.data.tm_index] = that.data.tm_current
|
||||||
that.showAnswer()
|
that.showAnswer()
|
||||||
if (that.data.ydtms.indexOf(that.data.tm_current.id)==-1){
|
if (that.data.ydtms.indexOf(that.data.tm_current.id)==-1){
|
||||||
that.data.ydtms.push(that.data.tm_current.id)
|
that.data.ydtms.push(that.data.tm_current.id)
|
||||||
|
@ -27,7 +27,7 @@ Page({
|
||||||
checkboxChange: function (e) {
|
checkboxChange: function (e) {
|
||||||
var that = this
|
var that = this
|
||||||
that.data.tm_current['user_answer'] = e.detail.value
|
that.data.tm_current['user_answer'] = e.detail.value
|
||||||
that.data.tms[that.data.tmIndex] = that.data.tm_current
|
that.data.tms[that.data.tm_index] = that.data.tm_current
|
||||||
if (that.data.ydtms.indexOf(that.data.tm_current.id) == -1) {
|
if (that.data.ydtms.indexOf(that.data.tm_current.id) == -1) {
|
||||||
that.data.ydtms.push(that.data.tm_current.id)
|
that.data.ydtms.push(that.data.tm_current.id)
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ Page({
|
||||||
})
|
})
|
||||||
}else{
|
}else{
|
||||||
that.data.tms = that.data.tms.concat(res.data.results)
|
that.data.tms = that.data.tms.concat(res.data.results)
|
||||||
that.showTm(that.data.tmIndex) //展示题目和答案
|
that.showTm(that.data.tm_index) //展示题目和答案
|
||||||
if(that.data.isLoad){
|
if(that.data.isLoad){
|
||||||
that.setData({
|
that.setData({
|
||||||
tmtotal: res.data.total,
|
tmtotal: res.data.total,
|
||||||
|
@ -152,7 +152,7 @@ Page({
|
||||||
var that = this
|
var that = this
|
||||||
var tm_current = that.data.tms[index]
|
var tm_current = that.data.tms[index]
|
||||||
that.setData({
|
that.setData({
|
||||||
'tmIndex': index,
|
'tm_index': index,
|
||||||
'tm_current': tm_current
|
'tm_current': tm_current
|
||||||
})
|
})
|
||||||
that.showOptions()
|
that.showOptions()
|
||||||
|
@ -193,25 +193,25 @@ Page({
|
||||||
},
|
},
|
||||||
next: function () {
|
next: function () {
|
||||||
var that = this
|
var that = this
|
||||||
var tmIndex = that.data.tmIndex + 1
|
var tm_index = that.data.tm_index + 1
|
||||||
that.setData({
|
that.setData({
|
||||||
tmIndex: tmIndex,
|
tm_index: tm_index,
|
||||||
answerP: false
|
answerP: false
|
||||||
})
|
})
|
||||||
if (tmIndex + 1 > that.data.tms.length) {
|
if (tm_index + 1 > that.data.tms.length) {
|
||||||
that.getTms()
|
that.getTms()
|
||||||
} else {
|
} else {
|
||||||
that.showTm(tmIndex)
|
that.showTm(tm_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
previous: function () {
|
previous: function () {
|
||||||
var that = this
|
var that = this
|
||||||
var tmIndex = that.data.tmIndex - 1
|
var tm_index = that.data.tm_index - 1
|
||||||
that.setData({
|
that.setData({
|
||||||
answerP: false
|
answerP: false
|
||||||
})
|
})
|
||||||
that.showTm(tmIndex)
|
that.showTm(tm_index)
|
||||||
},
|
},
|
||||||
showOptions: function () {
|
showOptions: function () {
|
||||||
let tm_current = this.data.tm_current
|
let tm_current = this.data.tm_current
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<view class="head">
|
<view class="head">
|
||||||
题量: {{tmIndex+1}}/{{tmtotal}}
|
题量: {{tm_index+1}}/{{tmtotal}}
|
||||||
</view>
|
</view>
|
||||||
<scroll-view scroll-y="true" style="height: {{scrollHeight}}px;">
|
<scroll-view scroll-y="true" style="height: {{scrollHeight}}px;">
|
||||||
<view class="weui-article">
|
<view class="weui-article">
|
||||||
<view class="weui-article__h2">{{tmIndex+1}}.
|
<view class="weui-article__h2">{{tm_index+1}}.
|
||||||
<span class="txlabel">{{tm_current.type}}</span>
|
<span class="txlabel">{{tm_current.type}}</span>
|
||||||
</view>
|
</view>
|
||||||
<view class="weui-article__title">{{tm_current.name}}</view>
|
<view class="weui-article__title">{{tm_current.name}}</view>
|
||||||
|
@ -48,10 +48,10 @@
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
<view class="btns">
|
<view class="btns">
|
||||||
<view style="width:25%">
|
<view style="width:25%">
|
||||||
<button type="primary" size="mini" bindtap="previous" disabled="{{tmIndex==0}}">上题</button>
|
<button type="primary" size="mini" bindtap="previous" disabled="{{tm_index==0}}">上题</button>
|
||||||
</view>
|
</view>
|
||||||
<view style="width:25%">
|
<view style="width:25%">
|
||||||
<button type="primary" size="mini" bindtap="next" disabled="{{tmIndex==tmtotal-1}}">下题</button>
|
<button type="primary" size="mini" bindtap="next" disabled="{{tm_index==tmtotal-1}}">下题</button>
|
||||||
</view>
|
</view>
|
||||||
<view style="width:25%">
|
<view style="width:25%">
|
||||||
<button type="primary" size="mini" bindtap="showAnswer">答案</button>
|
<button type="primary" size="mini" bindtap="showAnswer">答案</button>
|
||||||
|
|
|
@ -143,5 +143,16 @@ Page({
|
||||||
duration: 1500
|
duration: 1500
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
goYati: function () {
|
||||||
|
wx.showToast({
|
||||||
|
title: '暂未开放',
|
||||||
|
icon:'none'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
testList: function (){
|
||||||
|
wx.navigateTo({
|
||||||
|
url: '/pages/test/list',
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
|
@ -47,14 +47,14 @@
|
||||||
</view>
|
</view>
|
||||||
<view class="weui-grid__label">自助模考</view>
|
<view class="weui-grid__label">自助模考</view>
|
||||||
</a>
|
</a>
|
||||||
<a class="weui-grid">
|
<a class="weui-grid" bindtap="goYati">
|
||||||
<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">
|
<a class="weui-grid" bindtap="testList">
|
||||||
<view class="weui-grid__icon">
|
<view class="weui-grid__icon" >
|
||||||
<image src="/images/ksjl.svg" alt></image>
|
<image src="/images/ksjl.svg" alt></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="weui-grid__label">考试记录</view>
|
<view class="weui-grid__label">考试记录</view>
|
||||||
|
|
|
@ -91,7 +91,7 @@ Page({
|
||||||
wx.showLoading({
|
wx.showLoading({
|
||||||
title: '正在生成试卷',
|
title: '正在生成试卷',
|
||||||
})
|
})
|
||||||
api.request('examtest/monitest/', 'GET', { 'rule': e.currentTarget.id }).then(res => {
|
api.request('examtest/testrule/' + e.currentTarget.id + '/monitest', 'GET').then(res => {
|
||||||
try {
|
try {
|
||||||
wx.setStorageSync('monitest', res.data)
|
wx.setStorageSync('monitest', res.data)
|
||||||
} catch (e) { }
|
} catch (e) { }
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
// pages/test/detail.js
|
||||||
|
const api = require("../../utils/request.js");
|
||||||
|
Page({
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面的初始数据
|
||||||
|
*/
|
||||||
|
data: {
|
||||||
|
tm_index:0,
|
||||||
|
results:[]
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面加载
|
||||||
|
*/
|
||||||
|
onLoad: function (options) {
|
||||||
|
var that = this
|
||||||
|
var query = {'examtest':options.id}
|
||||||
|
api.request('examtest/answerdetail/', 'GET', query).then(res => {
|
||||||
|
that.data.results= res.data
|
||||||
|
that.showTm(0)
|
||||||
|
that.setData({
|
||||||
|
tmtotal:res.data.length
|
||||||
|
})
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
const res = wx.getSystemInfoSync()
|
||||||
|
that.setData({
|
||||||
|
scrollHeight: res.windowHeight - 70
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面初次渲染完成
|
||||||
|
*/
|
||||||
|
onReady: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面显示
|
||||||
|
*/
|
||||||
|
onShow: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面隐藏
|
||||||
|
*/
|
||||||
|
onHide: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面卸载
|
||||||
|
*/
|
||||||
|
onUnload: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面相关事件处理函数--监听用户下拉动作
|
||||||
|
*/
|
||||||
|
onPullDownRefresh: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面上拉触底事件的处理函数
|
||||||
|
*/
|
||||||
|
onReachBottom: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户点击右上角分享
|
||||||
|
*/
|
||||||
|
onShareAppMessage: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
showTm: function (index) {
|
||||||
|
var that = this
|
||||||
|
var tm_current = that.data.results[index]
|
||||||
|
that.setData({
|
||||||
|
'tm_index': index,
|
||||||
|
'tm_current': tm_current
|
||||||
|
})
|
||||||
|
that.showOptions()
|
||||||
|
},
|
||||||
|
next: function () {
|
||||||
|
var that = this
|
||||||
|
var tm_index = that.data.tm_index + 1
|
||||||
|
that.showTm(tm_index)
|
||||||
|
|
||||||
|
},
|
||||||
|
previous: function () {
|
||||||
|
var that = this
|
||||||
|
var tm_index = that.data.tm_index - 1
|
||||||
|
that.showTm(tm_index)
|
||||||
|
},
|
||||||
|
showOptions: function () {
|
||||||
|
var that = this
|
||||||
|
let question_options = that.data.tm_current.question.options
|
||||||
|
let options = []
|
||||||
|
let user_answer = that.data.tm_current.user_answer
|
||||||
|
for (let key in question_options) {
|
||||||
|
let option = {}
|
||||||
|
option.key = key
|
||||||
|
option.value = key + ':' + question_options[key]
|
||||||
|
if (user_answer) {
|
||||||
|
if (key == user_answer || user_answer.indexOf(key) != -1) {
|
||||||
|
option.checked = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
option.checked = false
|
||||||
|
}
|
||||||
|
options.push(option)
|
||||||
|
}
|
||||||
|
that.setData({
|
||||||
|
options: options
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"usingComponents": {}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
<view class="head">
|
||||||
|
题量: {{tm_index+1}}/{{tmtotal}}
|
||||||
|
</view>
|
||||||
|
<scroll-view scroll-y="true" style="height: {{scrollHeight}}px;">
|
||||||
|
<view class="weui-article">
|
||||||
|
<view class="weui-article__h2">{{tm_index+1}}.
|
||||||
|
<span class="txlabel">{{tm_current.question.type}}</span>
|
||||||
|
</view>
|
||||||
|
<view class="weui-article__title">{{tm_current.question.name}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="weui-cells weui-cells_radio">
|
||||||
|
<radio-group class="radio-group" wx:if="{{(tm_current.question.type=='单选' ||tm_current.question.type=='判断')}}">
|
||||||
|
<label class="weui-cell weui-cell_active weui-check__label" wx:for="{{options}}" wx:key="key">
|
||||||
|
<view class="weui-cell__bd">
|
||||||
|
<view>{{item.value}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="weui-cell__ft">
|
||||||
|
<radio class="weui-check" value="{{item.key}}" checked="{{item.checked}}" />
|
||||||
|
<i class="weui-icon-checked"></i>
|
||||||
|
</view>
|
||||||
|
</label>
|
||||||
|
</radio-group>
|
||||||
|
</view>
|
||||||
|
<view class="weui-cells weui-cells_checkbox">
|
||||||
|
<checkbox-group bindchange="checkboxChange" wx:if="{{tm_current.question.type=='多选'}}">
|
||||||
|
<label class="weui-cell weui-cell_active weui-check__label" wx:for="{{options}}" wx:key="key">
|
||||||
|
|
||||||
|
<view class="weui-cell__bd">
|
||||||
|
<view>{{item.value}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="weui-cell__hd">
|
||||||
|
<checkbox class="weui-check" value="{{item.key}}" checked="{{item.checked}}"/>
|
||||||
|
<i class="weui-icon-checked"></i>
|
||||||
|
</view>
|
||||||
|
</label>
|
||||||
|
</checkbox-group>
|
||||||
|
</view>
|
||||||
|
<view class="weui-article">
|
||||||
|
<view class="weui-article__h2" wx:if="{{tm_current.is_right}}" style="color:green;font-weight:bold">回答正确!</view>
|
||||||
|
<view class="weui-article__h2" wx:else style="color:red;font-weight:bold">回答有误!</view>
|
||||||
|
<view class="weui-article__h2">正确答案是{{tm_current.question.right}},你的答案是{{tm_current.user_answer}}</view>
|
||||||
|
<view class="weui-article__title">
|
||||||
|
<span style="color:blue">解析: </span>
|
||||||
|
<span wx:if="{{tm_current.question.resoluation != null}}">{{tm_current.question.resoluation}}</span>
|
||||||
|
<span wx:else>无</span>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
<view class="btns">
|
||||||
|
<view style="width:33%">
|
||||||
|
<button type="primary" size="mini" bindtap="previous" disabled="{{tm_index==0}}">上题</button>
|
||||||
|
</view>
|
||||||
|
<view style="width:33%">
|
||||||
|
<button type="primary" size="mini" bindtap="next" disabled="{{tm_index==tmtotal-1}}">下题</button>
|
||||||
|
</view>
|
||||||
|
<view style="width:33%">
|
||||||
|
<image style="height: 80%;" src="/images/weishoucang.svg" bindtap="shoucang" wx:if="weishoucang"></image>
|
||||||
|
<image style="height: 80%;" src="/images/yishoucang.svg" bindtap="shoucang" wx:else></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
|
@ -0,0 +1,20 @@
|
||||||
|
.head{
|
||||||
|
width:100%;
|
||||||
|
height:30px;
|
||||||
|
color:#fff;
|
||||||
|
background-color: cornflowerblue;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.btns{
|
||||||
|
height:40px;
|
||||||
|
display:flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
.txlabel{
|
||||||
|
color:#fff;
|
||||||
|
background-color: rgb(216, 140, 0);
|
||||||
|
padding: 2px
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
// pages/lianxi/index.js
|
||||||
|
const api = require("../../utils/request.js");
|
||||||
|
Page({
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面的初始数据
|
||||||
|
*/
|
||||||
|
data: {
|
||||||
|
results: [],
|
||||||
|
query:{
|
||||||
|
page:1,
|
||||||
|
limit:10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面加载
|
||||||
|
*/
|
||||||
|
onLoad: function () {
|
||||||
|
var that = this
|
||||||
|
that.getList(that.data.query)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面初次渲染完成
|
||||||
|
*/
|
||||||
|
onReady: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面显示
|
||||||
|
*/
|
||||||
|
onShow: function () {
|
||||||
|
},
|
||||||
|
getList: function () {
|
||||||
|
var that = this
|
||||||
|
api.request('examtest/myexamtest/', 'GET', that.data.query).then(res => {
|
||||||
|
if(res.data.length==0){
|
||||||
|
wx.showToast({
|
||||||
|
title: '没有更多了',
|
||||||
|
icon:''
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
if (that.data.query.page == 1){
|
||||||
|
that.data.results = res.data.results
|
||||||
|
}else{
|
||||||
|
that.data.results = that.data.results.concat(res.data.results)
|
||||||
|
}
|
||||||
|
|
||||||
|
that.setData({
|
||||||
|
results:that.data.results,
|
||||||
|
count:res.data.count
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面隐藏
|
||||||
|
*/
|
||||||
|
onHide: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面卸载
|
||||||
|
*/
|
||||||
|
onUnload: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面相关事件处理函数--监听用户下拉动作
|
||||||
|
*/
|
||||||
|
onPullDownRefresh: function () {
|
||||||
|
var that = this
|
||||||
|
that.data.query.page = 1;
|
||||||
|
that.getList();
|
||||||
|
wx.stopPullDownRefresh();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面上拉触底事件的处理函数
|
||||||
|
*/
|
||||||
|
onReachBottom: function () {
|
||||||
|
that.data.query.page = that.data.query.page + 1
|
||||||
|
that.getList()
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户点击右上角分享
|
||||||
|
*/
|
||||||
|
onShareAppMessage: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
detail: function (e) {
|
||||||
|
wx.navigateTo({
|
||||||
|
url: '',
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"usingComponents": {},
|
||||||
|
"navigationBarTitleText": "考试记录",
|
||||||
|
"enablePullDownRefresh": true,
|
||||||
|
"onReachBottomDistance": 50
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
<view class="head">
|
||||||
|
|
||||||
|
共{{count}}条考试记录</view>
|
||||||
|
<view class="weui-cells weui-cells_after-title">
|
||||||
|
<block wx:for="{{results}}" wx:key="unique">
|
||||||
|
<navigator url="detail?id={{item.id}}" class="weui-media-box weui-media-box_appmsg" hover-class="weui-cell_active">
|
||||||
|
<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" style="color:orange">
|
||||||
|
<span style="font-weight:bold;color:white;background-color:orange;">{{item.type}}</span>
|
||||||
|
<span>-</span>
|
||||||
|
<span style="font-weight:bold;color:white;background-color:green;" wx:if="{{item.is_pass}}">通过</span>
|
||||||
|
<span style="font-weight:bold;color:white;background-color:red;" wx:else>未通过</span>
|
||||||
|
(得分
|
||||||
|
<span style="color:green;font-weight:bold" wx:if="{{item.is_pass}}">{{item.score}}</span>
|
||||||
|
<span style="color:red;font-weight:bold" wx:else>{{item.score}}</span>
|
||||||
|
-满分
|
||||||
|
<span style="font-weight:bold">{{item.total_score}})</span>
|
||||||
|
</view>
|
||||||
|
<view class="weui-media-box__desc" style="color:orange">
|
||||||
|
耗时:{{item.took}}s
|
||||||
|
开始答题:{{item.start_time}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="weui-panel__ft weui-cell__ft_in-access">
|
||||||
|
<view class="weui-media-box__desc">答卷详情</view>
|
||||||
|
</view>
|
||||||
|
</navigator>
|
||||||
|
</block>
|
||||||
|
</view>
|
|
@ -0,0 +1,5 @@
|
||||||
|
.head{
|
||||||
|
color:#fff;
|
||||||
|
background-color: cornflowerblue;
|
||||||
|
text-align: center;
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
// pages/examtest/result.js
|
||||||
|
Page({
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面的初始数据
|
||||||
|
*/
|
||||||
|
data: {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面加载
|
||||||
|
*/
|
||||||
|
onLoad: function () {
|
||||||
|
this.setData(getApp().globalData.testData)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面初次渲染完成
|
||||||
|
*/
|
||||||
|
onReady: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面显示
|
||||||
|
*/
|
||||||
|
onShow: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面隐藏
|
||||||
|
*/
|
||||||
|
onHide: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面卸载
|
||||||
|
*/
|
||||||
|
onUnload: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面相关事件处理函数--监听用户下拉动作
|
||||||
|
*/
|
||||||
|
onPullDownRefresh: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面上拉触底事件的处理函数
|
||||||
|
*/
|
||||||
|
onReachBottom: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户点击右上角分享
|
||||||
|
*/
|
||||||
|
onShareAppMessage: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
detail: function () {
|
||||||
|
wx.redirectTo({
|
||||||
|
url: 'detail?id=' + this.data.id,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
back: function () {
|
||||||
|
wx.switchTab({
|
||||||
|
url: '/pages/main/main'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"usingComponents": {}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
<view class="page">
|
||||||
|
<view class="weui-msg">
|
||||||
|
<view class="weui-msg__icon-area" wx:if="{{is_pass}}"><i class="weui-icon-success weui-icon_msg"></i></view>
|
||||||
|
<view class="weui-msg__icon-area" wx:else><i class="weui-icon-warn weui-icon_msg"></i></view>
|
||||||
|
<view class="weui-msg__text-area">
|
||||||
|
<h2 class="weui-msg__title" wx:if="{{is_pass}}">恭喜您,通过考试</h2>
|
||||||
|
<h2 class="weui-msg__title" wx:else>很遗憾,下次加油</h2>
|
||||||
|
<view class="weui-msg__desc">
|
||||||
|
得分
|
||||||
|
<span style="color:green;font-weight:bold" wx:if="{{is_pass}}">{{score}}</span>
|
||||||
|
<span style="color:red;font-weight:bold" wx:else>{{score}}</span>
|
||||||
|
——满分
|
||||||
|
<span style="font-weight:bold">{{total_score}}</span>
|
||||||
|
</view>
|
||||||
|
<view class="weui-msg__desc">
|
||||||
|
用时:
|
||||||
|
<span style="color:green;font-weight:bold" wx:if="{{is_pass}}">{{took}}</span>
|
||||||
|
<span style="color:red;font-weight:bold" wx:else>{{took}}</span>
|
||||||
|
秒
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="weui-msg__opr-area">
|
||||||
|
<view class="weui-btn-area">
|
||||||
|
<a class="weui-btn weui-btn_primary" bindtap="detail">查看答卷详情</a>
|
||||||
|
<a class="weui-btn weui-btn_default" bindtap="back">返回首页</a>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
|
@ -0,0 +1 @@
|
||||||
|
/* pages/test/note.wxss */
|
|
@ -0,0 +1,86 @@
|
||||||
|
// pages/examtest/sheet.js
|
||||||
|
|
||||||
|
Page({
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面的初始数据
|
||||||
|
*/
|
||||||
|
data: {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
back: function (e) {
|
||||||
|
console.log(e.currentTarget.dataset.index);
|
||||||
|
var tm_index = e.currentTarget.dataset.index
|
||||||
|
var pages = getCurrentPages();
|
||||||
|
var prevPage = pages[pages.length - 2]; //上一个页面
|
||||||
|
prevPage.setData({
|
||||||
|
tm_index: tm_index
|
||||||
|
})
|
||||||
|
prevPage.showTm(tm_index)
|
||||||
|
prevPage.showOptions()
|
||||||
|
wx.navigateBack({
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面加载
|
||||||
|
*/
|
||||||
|
onLoad: function (options) {
|
||||||
|
var pages = getCurrentPages();
|
||||||
|
var prevPage = pages[pages.length - 2]; //上一个页面
|
||||||
|
var tms = prevPage.data.tms //取上页data里的数据也可以修改
|
||||||
|
this.setData({
|
||||||
|
tms: tms
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面初次渲染完成
|
||||||
|
*/
|
||||||
|
onReady: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面显示
|
||||||
|
*/
|
||||||
|
onShow: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面隐藏
|
||||||
|
*/
|
||||||
|
onHide: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面卸载
|
||||||
|
*/
|
||||||
|
onUnload: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面相关事件处理函数--监听用户下拉动作
|
||||||
|
*/
|
||||||
|
onPullDownRefresh: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面上拉触底事件的处理函数
|
||||||
|
*/
|
||||||
|
onReachBottom: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户点击右上角分享
|
||||||
|
*/
|
||||||
|
onShareAppMessage: function () {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"usingComponents": {},
|
||||||
|
"navigationBarTitleText": "答题卡"
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
<!--pages/examtest/sheet.wxml-->
|
||||||
|
<view style="width:100%;display:flex;padding:20rpx;flex-wrap: wrap ">
|
||||||
|
<view wx:for="{{tms}}" wx:key="id" >
|
||||||
|
|
||||||
|
<view wx:if="{{item.user_answer && item.user_answer.length !=0 }}" class="ok" data-index="{{index}}" bindtap='back'>
|
||||||
|
{{index+1}}
|
||||||
|
</view>
|
||||||
|
<view wx:else class="no" data-index="{{index}}" bindtap='back'>
|
||||||
|
{{index+1}}
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* pages/examtest/sheet.wxss */
|
||||||
|
.ok{
|
||||||
|
display: flex;
|
||||||
|
color:#fff;
|
||||||
|
background-color: green;
|
||||||
|
border:4rpx solid green;
|
||||||
|
height:100rpx;
|
||||||
|
width:100rpx;
|
||||||
|
margin:20rpx;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.no{
|
||||||
|
display: flex;
|
||||||
|
border:4rpx solid red;
|
||||||
|
height:100rpx;
|
||||||
|
width:100rpx;
|
||||||
|
margin:20rpx;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
|
@ -43,6 +43,12 @@ Page({
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
var value = wx.getStorageSync('ctms')
|
||||||
|
if (value) {
|
||||||
|
that.data.ctms = value
|
||||||
|
}
|
||||||
|
} catch (e) { }
|
||||||
let mil = that.data.monitest.limit * 60 * 1000
|
let mil = that.data.monitest.limit * 60 * 1000
|
||||||
let starttimes = (new Date()).getTime() //时间戳
|
let starttimes = (new Date()).getTime() //时间戳
|
||||||
let endtimes = starttimes + mil
|
let endtimes = starttimes + mil
|
||||||
|
@ -78,6 +84,9 @@ Page({
|
||||||
*/
|
*/
|
||||||
onUnload: function () {
|
onUnload: function () {
|
||||||
clearInterval(getApp().globalData.timer)
|
clearInterval(getApp().globalData.timer)
|
||||||
|
try {
|
||||||
|
wx.setStorageSync('ctms', this.data.ctms)
|
||||||
|
} catch (e) { }
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -178,6 +187,11 @@ Page({
|
||||||
options: options
|
options: options
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
sheet: function () {
|
||||||
|
wx.navigateTo({
|
||||||
|
url: 'sheet',
|
||||||
|
})
|
||||||
|
},
|
||||||
hand: function () {
|
hand: function () {
|
||||||
var that = this
|
var that = this
|
||||||
for (var i = 0, len = that.data.tms.length; i < len; i++) {
|
for (var i = 0, len = that.data.tms.length; i < len; i++) {
|
||||||
|
@ -219,19 +233,35 @@ Page({
|
||||||
for (var i = 0, len = that.data.tms.length; i < len; i++) {
|
for (var i = 0, len = that.data.tms.length; i < len; i++) {
|
||||||
let tm_result = that.panTi(that.data.tms[i])
|
let tm_result = that.panTi(that.data.tms[i])
|
||||||
that.data.tms[i].is_right = tm_result.is_right
|
that.data.tms[i].is_right = tm_result.is_right
|
||||||
|
if (tm_result.is_right == false){
|
||||||
|
that.data.ctms.unshift(that.data.tms[i])
|
||||||
|
if (that.data.ctms.length > 40) {
|
||||||
|
that.data.ctms.length = 40
|
||||||
|
}
|
||||||
|
}
|
||||||
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.monitest.score = score
|
||||||
|
if (score >= that.data.monitest.pass_score){
|
||||||
|
that.data.monitest.is_pass = true
|
||||||
|
}else{
|
||||||
|
that.data.monitest.is_pass = false
|
||||||
|
}
|
||||||
|
console.log(that.data.tms)
|
||||||
that.data.monitest.questions = that.data.tms
|
that.data.monitest.questions = that.data.tms
|
||||||
that.data.monitest.start_time = util.formatTime(new Date(that.data.starttimes))
|
that.data.monitest.start_time = util.formatTime(new Date(that.data.starttimes))
|
||||||
that.data.monitest.end_time = util.formatTime(new Date())
|
that.data.monitest.end_time = util.formatTime(new Date())
|
||||||
that.data.monitest.took = Math.floor(((new Date()).getTime() - this.data.starttimes) / 1000)
|
that.data.monitest.took = Math.floor(((new Date()).getTime() - this.data.starttimes) / 1000)
|
||||||
console.log(that.data.monitest)
|
api.request('examtest/monitest/', 'POST', that.data.monitest).then(res => {
|
||||||
// api.request('examtest/monitest/', 'POST', that.data.monitest).then(res => {
|
getApp().globalData.testData = res.data
|
||||||
// wx.redirectTo({
|
try {
|
||||||
// url: 'note',
|
wx.removeStorageSync('monitest')
|
||||||
// })
|
} catch (e) {
|
||||||
// })
|
}
|
||||||
|
wx.redirectTo({
|
||||||
|
url: 'result',
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"usingComponents": {},
|
"usingComponents": {},
|
||||||
"navigationBarTitleText": "考试中"
|
"navigationBarTitleText": "答题中"
|
||||||
}
|
}
|
|
@ -53,7 +53,7 @@
|
||||||
<button type="primary" size="mini" bindtap="next" disabled="{{tm_index==tm_total-1}}">下题</button>
|
<button type="primary" size="mini" bindtap="next" disabled="{{tm_index==tm_total-1}}">下题</button>
|
||||||
</view>
|
</view>
|
||||||
<view style="width:25%">
|
<view style="width:25%">
|
||||||
<button type="primary" size="mini" bindtap="sheet">答题卡</button>
|
<a class="weui-btn weui-btn_mini weui-btn_primary" bindtap="sheet">答题卡</a>
|
||||||
</view>
|
</view>
|
||||||
<view style="width:25%">
|
<view style="width:25%">
|
||||||
<a class="weui-btn weui-btn_mini weui-btn_warn" bindtap="hand">交卷</a>
|
<a class="weui-btn weui-btn_mini weui-btn_warn" bindtap="hand">交卷</a>
|
||||||
|
|
|
@ -6,7 +6,7 @@ const formatTime = date => {
|
||||||
const minute = date.getMinutes()
|
const minute = date.getMinutes()
|
||||||
const second = date.getSeconds()
|
const second = date.getSeconds()
|
||||||
|
|
||||||
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
|
return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':')
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatNumber = n => {
|
const formatNumber = n => {
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Generated by Django 3.0.4 on 2020-03-20 09:26
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('question', '0007_auto_20200319_0846'),
|
||||||
|
('crm', '0006_auto_20200310_1531'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='consumer',
|
||||||
|
name='is_paid',
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='PaySubject',
|
||||||
|
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='删除标记')),
|
||||||
|
('consumer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='crm.Consumer')),
|
||||||
|
('subject', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='question.Questioncat')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='consumer',
|
||||||
|
name='subjects',
|
||||||
|
field=models.ManyToManyField(through='crm.PaySubject', to='question.Questioncat', verbose_name='付费学科'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,9 +1,10 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
import django.utils.timezone as timezone
|
import django.utils.timezone as timezone
|
||||||
from rbac.models import CommonModel
|
from rbac.models import SoftCommonModel, CommonModel
|
||||||
|
from question.models import Questioncat
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
|
|
||||||
class Company(CommonModel):
|
class Company(SoftCommonModel):
|
||||||
"""
|
"""
|
||||||
客户企业
|
客户企业
|
||||||
"""
|
"""
|
||||||
|
@ -17,7 +18,7 @@ class Company(CommonModel):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Consumer(CommonModel):
|
class Consumer(SoftCommonModel):
|
||||||
"""
|
"""
|
||||||
学员
|
学员
|
||||||
"""
|
"""
|
||||||
|
@ -27,7 +28,7 @@ class Consumer(CommonModel):
|
||||||
openid = models.CharField(max_length=200, verbose_name="openid", null=True, blank=True, unique=True)
|
openid = models.CharField(max_length=200, verbose_name="openid", null=True, blank=True, unique=True)
|
||||||
avatar = models.CharField(default="/media/default/avatar.png",max_length=1000, null=True, blank=True, verbose_name="头像")
|
avatar = models.CharField(default="/media/default/avatar.png",max_length=1000, null=True, blank=True, verbose_name="头像")
|
||||||
nickname = models.CharField(max_length=200, verbose_name="昵称", null=True, blank=True)
|
nickname = models.CharField(max_length=200, verbose_name="昵称", null=True, blank=True)
|
||||||
is_paid = models.BooleanField(default=False,verbose_name="是否付费")
|
subjects = models.ManyToManyField(Questioncat, verbose_name="付费学科", through="PaySubject")
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -35,4 +36,11 @@ class Consumer(CommonModel):
|
||||||
verbose_name_plural = verbose_name
|
verbose_name_plural = verbose_name
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
class PaySubject(CommonModel):
|
||||||
|
'''
|
||||||
|
付费学科关联表
|
||||||
|
'''
|
||||||
|
consumer = models.ForeignKey(Consumer, on_delete=models.CASCADE)
|
||||||
|
subject = models.ForeignKey(Questioncat, on_delete=models.CASCADE)
|
|
@ -24,3 +24,15 @@ class ConsumerSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Consumer
|
model = Consumer
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
depth = 1
|
||||||
|
|
||||||
|
class ConsumerCUSerializer(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)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Consumer
|
||||||
|
fields = '__all__'
|
|
@ -14,9 +14,10 @@ import json
|
||||||
|
|
||||||
from utils.custom import CommonPagination
|
from utils.custom import CommonPagination
|
||||||
from rbac.permission import RbacPermission
|
from rbac.permission import RbacPermission
|
||||||
from .models import Company, Consumer
|
from .models import Company, Consumer, PaySubject
|
||||||
from .serializers import CompanySerializer, ConsumerSerializer
|
from .serializers import CompanySerializer, ConsumerSerializer, ConsumerCUSerializer
|
||||||
from server import settings
|
from server import settings
|
||||||
|
from question.models import Questioncat
|
||||||
|
|
||||||
appid = 'wx5c39b569f01c27db'
|
appid = 'wx5c39b569f01c27db'
|
||||||
secret = '68762892f8df2b4a0b1940c5250a8dc0'
|
secret = '68762892f8df2b4a0b1940c5250a8dc0'
|
||||||
|
@ -70,9 +71,14 @@ class ConsumerViewSet(ModelViewSet):
|
||||||
ordering_fields = ('id',)
|
ordering_fields = ('id',)
|
||||||
ordering = ['id']
|
ordering = ['id']
|
||||||
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
|
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
|
||||||
filterset_fields = ('is_paid','company')
|
filterset_fields = ('company',)
|
||||||
search_fields = ('^name',)
|
search_fields = ('^name',)
|
||||||
|
|
||||||
|
def get_serializer_class(self):
|
||||||
|
if self.action == 'list':
|
||||||
|
return ConsumerSerializer
|
||||||
|
else:
|
||||||
|
return ConsumerCUSerializer
|
||||||
|
|
||||||
def destroy(self, request, *args, **kwargs): #逻辑删除
|
def destroy(self, request, *args, **kwargs): #逻辑删除
|
||||||
instance = self.get_object()
|
instance = self.get_object()
|
||||||
|
@ -125,8 +131,10 @@ class ConsumerViewSet(ModelViewSet):
|
||||||
obj.name = name
|
obj.name = name
|
||||||
obj.username = username
|
obj.username = username
|
||||||
obj.company = companyobj
|
obj.company = companyobj
|
||||||
obj.is_paid = True
|
|
||||||
obj.save()
|
obj.save()
|
||||||
|
subjects = Questioncat.objects.filter(is_subject=True,is_delete=False)
|
||||||
|
if subjects.exists():
|
||||||
|
PaySubject.objects.create(subject=subjects.first(), consumer=obj)
|
||||||
i = i + 1
|
i = i + 1
|
||||||
if consumerdict:
|
if consumerdict:
|
||||||
return {"code":206,"data":consumerdict,"msg":"导入部分成功"}
|
return {"code":206,"data":consumerdict,"msg":"导入部分成功"}
|
||||||
|
|
|
@ -50,7 +50,7 @@ class Migration(migrations.Migration):
|
||||||
field=models.FloatField(default=0, verbose_name='判断分数'),
|
field=models.FloatField(default=0, verbose_name='判断分数'),
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='MoniTest',
|
name='ExamTest',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('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='创建时间')),
|
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||||
|
@ -73,8 +73,8 @@ class Migration(migrations.Migration):
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='answerdetail',
|
model_name='answerdetail',
|
||||||
name='monitest',
|
name='examtest',
|
||||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='examtest.MoniTest'),
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='examtest.ExamTest'),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='answerdetail',
|
model_name='answerdetail',
|
||||||
|
|
|
@ -29,7 +29,7 @@ class Migration(migrations.Migration):
|
||||||
options={'verbose_name': '答题记录', 'verbose_name_plural': '答题记录'},
|
options={'verbose_name': '答题记录', 'verbose_name_plural': '答题记录'},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='monitest',
|
name='examtest',
|
||||||
options={'verbose_name': '自助模考', 'verbose_name_plural': '自助模考'},
|
options={'verbose_name': '自助模考', 'verbose_name_plural': '自助模考'},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.0.4 on 2020-03-20 03:12
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('examtest', '0009_auto_20200319_1850'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='testrule',
|
||||||
|
name='is_pass',
|
||||||
|
field=models.BooleanField(default=True, verbose_name='是否通过'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,42 @@
|
||||||
|
# Generated by Django 3.0.4 on 2020-03-20 03:15
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('examtest', '0010_testrule_is_pass'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='testrule',
|
||||||
|
name='is_pass',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='examtest',
|
||||||
|
name='is_pass',
|
||||||
|
field=models.BooleanField(default=True, verbose_name='是否通过'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='examtest',
|
||||||
|
name='total_score',
|
||||||
|
field=models.FloatField(default=0, verbose_name='总分'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='examtest',
|
||||||
|
name='score',
|
||||||
|
field=models.FloatField(default=0, verbose_name='得分'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='testrule',
|
||||||
|
name='pass_score',
|
||||||
|
field=models.FloatField(default=0, verbose_name='及格分数'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='testrule',
|
||||||
|
name='total_score',
|
||||||
|
field=models.FloatField(default=0, verbose_name='满分'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,50 @@
|
||||||
|
# Generated by Django 3.0.4 on 2020-03-20 06:39
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('examtest', '0011_auto_20200320_1115'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Paper',
|
||||||
|
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='删除标记')),
|
||||||
|
('name', models.CharField(max_length=200, verbose_name='名称')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='PaperTest',
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='examtest',
|
||||||
|
options={'verbose_name': '考试表', 'verbose_name_plural': '考试表'},
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='examtest',
|
||||||
|
name='rule',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='examtest.TestRule', verbose_name='所用规则'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='examtest',
|
||||||
|
name='type',
|
||||||
|
field=models.CharField(choices=[('自助模考', '自助模考'), ('押卷模考', '押卷模考')], default='自助模考', max_length=50, verbose_name='考试类型'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='examtest',
|
||||||
|
name='paper',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='examtest.Paper', verbose_name='所用试卷'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,11 +1,11 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from rbac.models import CommonModel
|
from rbac.models import SoftCommonModel, CommonModel
|
||||||
from django.contrib.postgres.fields import JSONField, ArrayField
|
from django.contrib.postgres.fields import JSONField, ArrayField
|
||||||
from question.models import Questioncat, Question
|
from question.models import Questioncat, Question
|
||||||
from crm.models import Consumer
|
from crm.models import Consumer
|
||||||
|
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
class TestRule(CommonModel):
|
class TestRule(SoftCommonModel):
|
||||||
name = models.CharField(max_length=200, unique=True, verbose_name='名称')
|
name = models.CharField(max_length=200, unique=True, verbose_name='名称')
|
||||||
desc = models.TextField(verbose_name='描述', default='')
|
desc = models.TextField(verbose_name='描述', default='')
|
||||||
subject = models.ForeignKey(Questioncat, blank=True, null=True, on_delete=models.CASCADE, verbose_name='所属学科', related_name='subject')
|
subject = models.ForeignKey(Questioncat, blank=True, null=True, on_delete=models.CASCADE, verbose_name='所属学科', related_name='subject')
|
||||||
|
@ -17,8 +17,9 @@ class TestRule(CommonModel):
|
||||||
panduan_count = models.IntegerField(default=0, verbose_name='判断数量')
|
panduan_count = models.IntegerField(default=0, verbose_name='判断数量')
|
||||||
panduan_score = models.FloatField(default=0, verbose_name='判断分数')
|
panduan_score = models.FloatField(default=0, verbose_name='判断分数')
|
||||||
limit = models.IntegerField(default=0, verbose_name='限时(分钟)')
|
limit = models.IntegerField(default=0, verbose_name='限时(分钟)')
|
||||||
total_score = models.IntegerField(default=0, verbose_name='满分')
|
total_score = models.FloatField(default=0, verbose_name='满分')
|
||||||
pass_score = models.IntegerField(default=0, verbose_name='及格分数')
|
pass_score = models.FloatField(default=0, verbose_name='及格分数')
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = '出题规则'
|
verbose_name = '出题规则'
|
||||||
|
@ -27,31 +28,38 @@ class TestRule(CommonModel):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class PaperTest(CommonModel):
|
|
||||||
pass
|
|
||||||
class Meta:
|
|
||||||
verbose_name = '押题模考'
|
|
||||||
verbose_name_plural = verbose_name
|
|
||||||
|
|
||||||
|
class Paper(SoftCommonModel):
|
||||||
class MoniTest(CommonModel):
|
|
||||||
name = models.CharField(max_length=200, verbose_name='名称')
|
name = models.CharField(max_length=200, verbose_name='名称')
|
||||||
type = models.CharField(max_length=50, default='自助模考',verbose_name='考试类型')
|
|
||||||
|
class ExamTest(CommonModel):
|
||||||
|
'''
|
||||||
|
硬删除
|
||||||
|
'''
|
||||||
|
type_choices = (
|
||||||
|
('自助模考', '自助模考'),
|
||||||
|
('押卷模考', '押卷模考'),
|
||||||
|
)
|
||||||
|
name = models.CharField(max_length=200, verbose_name='名称')
|
||||||
|
type = models.CharField(max_length=50, default='自助模考',choices = type_choices, verbose_name='考试类型')
|
||||||
limit = models.IntegerField(default=0, verbose_name='限时(分钟)')
|
limit = models.IntegerField(default=0, verbose_name='限时(分钟)')
|
||||||
rule = models.ForeignKey(TestRule, on_delete=models.CASCADE, verbose_name='出题规则')
|
rule = models.ForeignKey(TestRule, on_delete=models.CASCADE, verbose_name='所用规则', null=True, blank=True)
|
||||||
|
paper = models.ForeignKey(Paper, on_delete=models.CASCADE, verbose_name='所用试卷', null=True, blank=True)
|
||||||
consumer = models.ForeignKey(Consumer, on_delete=models.CASCADE, verbose_name='模考人')
|
consumer = models.ForeignKey(Consumer, on_delete=models.CASCADE, verbose_name='模考人')
|
||||||
score = models.IntegerField(default=0, verbose_name='得分')
|
total_score = models.FloatField(default=0, verbose_name='总分')
|
||||||
|
score = models.FloatField(default=0, verbose_name='得分')
|
||||||
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, related_name='答题记录', through='AnswerDetail')
|
||||||
|
is_pass = models.BooleanField(default=True, verbose_name='是否通过')
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = '自助模考'
|
verbose_name = '考试表'
|
||||||
verbose_name_plural = verbose_name
|
verbose_name_plural = verbose_name
|
||||||
|
|
||||||
|
|
||||||
class AnswerDetail(CommonModel):
|
class AnswerDetail(SoftCommonModel):
|
||||||
monitest = models.ForeignKey(MoniTest, on_delete=models.CASCADE)
|
examtest = models.ForeignKey(ExamTest, on_delete=models.CASCADE)
|
||||||
question = models.ForeignKey(Question, on_delete=models.CASCADE)
|
question = models.ForeignKey(Question, on_delete=models.CASCADE)
|
||||||
user_answer = JSONField()
|
user_answer = JSONField()
|
||||||
score = models.FloatField(default=0, verbose_name='本题得分')
|
score = models.FloatField(default=0, verbose_name='本题得分')
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from question.models import Questioncat
|
from question.models import Questioncat
|
||||||
from .models import TestRule, MoniTest
|
from crm.models import Consumer
|
||||||
|
from .models import TestRule, ExamTest, AnswerDetail
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,12 +42,36 @@ class MoniTestSerializer(serializers.ModelSerializer):
|
||||||
"""
|
"""
|
||||||
自助模考序列化
|
自助模考序列化
|
||||||
"""
|
"""
|
||||||
start_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True)
|
start_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
|
||||||
end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True)
|
end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
|
||||||
|
consumer = serializers.PrimaryKeyRelatedField(queryset=Consumer.objects.all(), required=False)
|
||||||
|
rule = serializers.PrimaryKeyRelatedField(queryset=TestRule.objects.all(), required=True)
|
||||||
create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
|
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)
|
update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
|
||||||
class Meta:
|
class Meta:
|
||||||
model = MoniTest
|
model = ExamTest
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class ExamTestListSerializer(serializers.ModelSerializer):
|
||||||
|
"""
|
||||||
|
考试列表序列化
|
||||||
|
"""
|
||||||
|
start_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
|
||||||
|
end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
|
||||||
|
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)
|
||||||
|
class Meta:
|
||||||
|
model = ExamTest
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
class AnswerDetailSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = AnswerDetail
|
||||||
|
fields = '__all__'
|
||||||
|
depth = 1
|
||||||
|
|
||||||
|
class AnswerDetailCreateSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = AnswerDetail
|
||||||
|
fields = '__all__'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from django.urls import path,include
|
from django.urls import path,include
|
||||||
from .views import TestRuleViewSet, MoniTestView
|
from .views import TestRuleViewSet, MoniTestView, MyExamTestView, AnswerDetailView
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,5 +8,7 @@ router.register('testrule', TestRuleViewSet, basename="testrule")
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('monitest/',MoniTestView.as_view()),
|
path('monitest/',MoniTestView.as_view()),
|
||||||
|
path('myexamtest/',MyExamTestView.as_view()),
|
||||||
|
path('answerdetail/', AnswerDetailView.as_view()),
|
||||||
path('', include(router.urls)),
|
path('', include(router.urls)),
|
||||||
]
|
]
|
||||||
|
|
|
@ -15,60 +15,65 @@ from utils.custom import CommonPagination
|
||||||
from rbac.permission import RbacPermission
|
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 TestRule
|
from .models import TestRule, ExamTest, AnswerDetail
|
||||||
from .serializers import TestRuleSerializer, TestRuleListSerializer, TestRuleCreateSerializer, MoniTestSerializer
|
from .serializers import TestRuleSerializer, TestRuleListSerializer, TestRuleCreateSerializer, MoniTestSerializer, AnswerDetailSerializer, ExamTestListSerializer, AnswerDetailCreateSerializer
|
||||||
from server import settings
|
from server import settings
|
||||||
from crm.authentication import ConsumerTokenAuthentication
|
from crm.authentication import ConsumerTokenAuthentication
|
||||||
|
from utils.custom import CommonPagination
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
class MoniTestView(APIView):
|
class MoniTestView(APIView):
|
||||||
authentication_classes = [ConsumerTokenAuthentication]
|
authentication_classes = [ConsumerTokenAuthentication]
|
||||||
permission_classes = []
|
permission_classes = []
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
data = request.data
|
serializer = MoniTestSerializer(data = request.data)
|
||||||
pass
|
if serializer.is_valid():
|
||||||
def get(self, request, *args, **kwargs):
|
instance = serializer.save(consumer = request.user)
|
||||||
'''
|
if 'questions' in request.data:
|
||||||
生成模拟考试
|
questions = []
|
||||||
'''
|
for i in request.data['questions']:
|
||||||
if request.query_params.get('rule', None):
|
question = {}
|
||||||
ret = {}
|
question['question'] = i['id']
|
||||||
testrule = TestRule.objects.get(id = request.query_params.get('rule'))
|
question['examtest'] = instance.id
|
||||||
ret['name'] = '自助模考' + datetime.now().strftime('%Y%m%d%H%M')
|
question['score'] = i['score']
|
||||||
ret['type'] = '自助模考' # 自助模拟考试
|
if 'user_answer' in i:
|
||||||
ret['rule'] = testrule.id
|
question['user_answer'] = i['user_answer']
|
||||||
ret['limit'] = testrule.limit
|
question['is_right'] = i['is_right']
|
||||||
ret['total_score'] = testrule.total_score
|
questions.append(question)
|
||||||
ret['pass_score'] = testrule.pass_score
|
serializer_detail = AnswerDetailCreateSerializer(data=questions, many=True)
|
||||||
ret['danxuan_count'] = testrule.danxuan_count
|
if serializer_detail.is_valid():
|
||||||
ret['danxuan_score'] = testrule.danxuan_score
|
serializer_detail.save()
|
||||||
ret['duoxuan_count'] = testrule.duoxuan_count
|
return Response(MoniTestSerializer(instance).data,status=status.HTTP_200_OK)
|
||||||
ret['duoxuan_score'] = testrule.duoxuan_score
|
|
||||||
ret['panduan_count'] = testrule.panduan_count
|
|
||||||
ret['panduan_score'] = testrule.panduan_score
|
|
||||||
question_queryset = Question.objects.none()
|
|
||||||
queryset = Question.objects.filter(is_delete=0,questioncat__in = testrule.questioncat.all())
|
|
||||||
if ret['danxuan_count']:
|
|
||||||
danxuan = queryset.filter(type='单选').order_by('?')[:ret['danxuan_count']]
|
|
||||||
question_queryset = question_queryset | danxuan
|
|
||||||
if ret['duoxuan_count']:
|
|
||||||
duoxuan = queryset.filter(type='多选').order_by('?')[:ret['duoxuan_count']]
|
|
||||||
question_queryset = question_queryset | duoxuan
|
|
||||||
if ret['panduan_count']:
|
|
||||||
panduan = queryset.filter(type='判断').order_by('?')[:ret['panduan_count']]
|
|
||||||
question_queryset = question_queryset | panduan
|
|
||||||
questions = QuestionSerializer(instance=question_queryset.order_by('type'),many=True).data
|
|
||||||
for i in questions:
|
|
||||||
if i['type'] == 1:
|
|
||||||
i['total_score'] = ret['danxuan_score']
|
|
||||||
elif i['type'] == 2:
|
|
||||||
i['total_score'] = ret['duoxuan_score']
|
|
||||||
else:
|
else:
|
||||||
i['total_score'] = ret['panduan_score']
|
return Response(serializer_detail.errors)
|
||||||
ret['questions'] = questions
|
|
||||||
return Response(ret)
|
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)
|
||||||
|
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 AnswerDetailView(APIView):
|
||||||
|
authentication_classes = []
|
||||||
|
permission_classes = []
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
queryset = AnswerDetail.objects.all()
|
||||||
|
if request.query_params.get('examtest', None):
|
||||||
|
queryset = queryset.filter(examtest=request.query_params.get('examtest'))
|
||||||
|
serializer = AnswerDetailSerializer(instance=queryset,many=True)
|
||||||
|
return Response(serializer.data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -114,4 +119,46 @@ class TestRuleViewSet(ModelViewSet):
|
||||||
"""
|
"""
|
||||||
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]
|
||||||
|
|
||||||
|
@action(methods=['get'], detail=True, permission_classes=[IsAuthenticated],
|
||||||
|
url_path='monitest', url_name='gen_monitest')
|
||||||
|
def monitest(self, request, pk=None):
|
||||||
|
'''
|
||||||
|
生成自助模拟考试
|
||||||
|
'''
|
||||||
|
ret = {}
|
||||||
|
testrule = self.get_object()
|
||||||
|
ret['name'] = '自助模考' + datetime.now().strftime('%Y%m%d%H%M')
|
||||||
|
ret['type'] = '自助模考' # 自助模拟考试
|
||||||
|
ret['rule'] = testrule.id
|
||||||
|
ret['limit'] = testrule.limit
|
||||||
|
ret['total_score'] = testrule.total_score
|
||||||
|
ret['pass_score'] = testrule.pass_score
|
||||||
|
ret['danxuan_count'] = testrule.danxuan_count
|
||||||
|
ret['danxuan_score'] = testrule.danxuan_score
|
||||||
|
ret['duoxuan_count'] = testrule.duoxuan_count
|
||||||
|
ret['duoxuan_score'] = testrule.duoxuan_score
|
||||||
|
ret['panduan_count'] = testrule.panduan_count
|
||||||
|
ret['panduan_score'] = testrule.panduan_score
|
||||||
|
question_queryset = Question.objects.none()
|
||||||
|
queryset = Question.objects.filter(is_delete=0,questioncat__in = testrule.questioncat.all())
|
||||||
|
if ret['danxuan_count']:
|
||||||
|
danxuan = queryset.filter(type='单选').order_by('?')[:ret['danxuan_count']]
|
||||||
|
question_queryset = question_queryset | danxuan
|
||||||
|
if ret['duoxuan_count']:
|
||||||
|
duoxuan = queryset.filter(type='多选').order_by('?')[:ret['duoxuan_count']]
|
||||||
|
question_queryset = question_queryset | duoxuan
|
||||||
|
if ret['panduan_count']:
|
||||||
|
panduan = queryset.filter(type='判断').order_by('?')[:ret['panduan_count']]
|
||||||
|
question_queryset = question_queryset | panduan
|
||||||
|
questions = QuestionSerializer(instance=question_queryset.order_by('type'),many=True).data
|
||||||
|
for i in questions:
|
||||||
|
if i['type'] == 1:
|
||||||
|
i['total_score'] = ret['danxuan_score']
|
||||||
|
elif i['type'] == 2:
|
||||||
|
i['total_score'] = ret['duoxuan_score']
|
||||||
|
else:
|
||||||
|
i['total_score'] = ret['panduan_score']
|
||||||
|
ret['questions'] = questions
|
||||||
|
return Response(ret)
|
Binary file not shown.
Binary file not shown.
|
@ -1,10 +1,10 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from rbac.models import CommonModel
|
from rbac.models import SoftCommonModel
|
||||||
from django.contrib.postgres.fields import JSONField, ArrayField
|
from django.contrib.postgres.fields import JSONField, ArrayField
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
|
|
||||||
|
|
||||||
class Questioncat(CommonModel):
|
class Questioncat(SoftCommonModel):
|
||||||
name = models.CharField(max_length=200, unique=True, verbose_name='名称')
|
name = models.CharField(max_length=200, unique=True, verbose_name='名称')
|
||||||
pid = models.ForeignKey('self', verbose_name='父', null=True, blank=True, on_delete=models.CASCADE, related_name='questioncatpid')
|
pid = models.ForeignKey('self', verbose_name='父', null=True, blank=True, on_delete=models.CASCADE, related_name='questioncatpid')
|
||||||
is_subject = models.BooleanField(default=False, verbose_name='是否是学科')
|
is_subject = models.BooleanField(default=False, verbose_name='是否是学科')
|
||||||
|
@ -20,7 +20,7 @@ class Questioncat(CommonModel):
|
||||||
return self.questioncat.count()
|
return self.questioncat.count()
|
||||||
|
|
||||||
|
|
||||||
class Question(CommonModel):
|
class Question(SoftCommonModel):
|
||||||
type_choices = (
|
type_choices = (
|
||||||
('单选', '单选'),
|
('单选', '单选'),
|
||||||
('多选', '多选'),
|
('多选', '多选'),
|
||||||
|
|
|
@ -13,7 +13,7 @@ class SoftDeletManager(models.Manager):
|
||||||
'''
|
'''
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""
|
"""
|
||||||
在这里处理一下QuerySet, 然后返回没被标记位is_deleted的QuerySet
|
在这里处理一下QuerySet, 然后返回没被标记位is_delete的QuerySet
|
||||||
"""
|
"""
|
||||||
kwargs = {'model': self.model, 'using': self._db}
|
kwargs = {'model': self.model, 'using': self._db}
|
||||||
if hasattr(self, '_hints'):
|
if hasattr(self, '_hints'):
|
||||||
|
@ -21,7 +21,7 @@ class SoftDeletManager(models.Manager):
|
||||||
|
|
||||||
return self._queryset_class(**kwargs).filter(is_delete=False)
|
return self._queryset_class(**kwargs).filter(is_delete=False)
|
||||||
|
|
||||||
class CommonModel(models.Model):
|
class SoftCommonModel(models.Model):
|
||||||
create_time = models.DateTimeField(default=timezone.now, verbose_name='创建时间', help_text='创建时间')
|
create_time = models.DateTimeField(default=timezone.now, verbose_name='创建时间', help_text='创建时间')
|
||||||
update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间', help_text='修改时间')
|
update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间', help_text='修改时间')
|
||||||
is_delete = models.BooleanField(default=False, verbose_name='删除标记', help_text='删除标记')
|
is_delete = models.BooleanField(default=False, verbose_name='删除标记', help_text='删除标记')
|
||||||
|
@ -39,10 +39,18 @@ class CommonModel(models.Model):
|
||||||
self.is_delete = True
|
self.is_delete = True
|
||||||
self.save(using=using)
|
self.save(using=using)
|
||||||
else:
|
else:
|
||||||
return super(CommonModel, self).delete(using=using, *args, **kwargs)
|
return super(SoftCommonModel, self).delete(using=using, *args, **kwargs)
|
||||||
|
|
||||||
|
class CommonModel(models.Model):
|
||||||
|
create_time = models.DateTimeField(default=timezone.now, verbose_name='创建时间', help_text='创建时间')
|
||||||
|
update_time = models.DateTimeField(auto_now=True, verbose_name='修改时间', help_text='修改时间')
|
||||||
|
is_delete = models.BooleanField(default=False, verbose_name='删除标记', help_text='删除标记')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
abstract = True
|
||||||
|
|
||||||
|
|
||||||
class Menu(CommonModel):
|
class Menu(SoftCommonModel):
|
||||||
"""
|
"""
|
||||||
功能权限:目录,菜单,权限
|
功能权限:目录,菜单,权限
|
||||||
"""
|
"""
|
||||||
|
@ -68,7 +76,7 @@ class Menu(CommonModel):
|
||||||
ordering = ['id']
|
ordering = ['id']
|
||||||
|
|
||||||
|
|
||||||
class Role(CommonModel):
|
class Role(SoftCommonModel):
|
||||||
"""
|
"""
|
||||||
角色
|
角色
|
||||||
"""
|
"""
|
||||||
|
@ -83,7 +91,7 @@ class Role(CommonModel):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Organization(CommonModel):
|
class Organization(SoftCommonModel):
|
||||||
"""
|
"""
|
||||||
组织架构
|
组织架构
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue