-
+
-
+
-
+
+ v-model="Form.questioncat" multiple placeholder="请选择题库范围" style="width:400px"
+ @visible-change="getQuestionCount">
- 共有{{typecount.danxuan}}道,选取
- 道,每道
- 分
+ 共有 {{typecount.danxuan}} 道,选取
+ 道,每道
+ 分
- 共有{{typecount.duoxuan}}道,选取
- 道,每道
- 分
+ 共有 {{typecount.duoxuan}} 道,选取
+ 道,每道
+ 分
- 共有{{typecount.panduan}}道,选取
- 道,每道
- 分
+ 共有 {{typecount.panduan}} 道,选取
+ 道,每道
+ 分
-
- 分钟
+
+ 分钟
- {{ruleForm.detail.score}}分
+ {{Form.totalscore}} 分
- 分
+ 分
- 立即创建
- 重置
+ 立即创建
+ 重置
+ 返回
@@ -73,27 +74,20 @@ import { genTree } from "@/utils";
export default {
data() {
return {
- ruleForm: {
+ Form: {
name: "",
+ desc:"",
subject: null,
questioncat: [],
- detail: {
- danxuan: {
- count: 0,
- score: 0
- },
- duoxuan: {
- count: 0,
- score: 0
- },
- panduan: {
- count: 0,
- score: 0
- },
- duration: 0,
- score: 0,
- passscore: 0
- }
+ danxuan_count:0,
+ danxuan_score:0,
+ duoxuan_count:0,
+ duoxuan_score:0,
+ panduan_count:0,
+ panduan_score:0,
+ limit:0,
+ totalscore:0,
+ passscore:0
},
typecount:{
danxuan:0,
@@ -102,19 +96,22 @@ export default {
},
subjectData:[],
questioncatData:[],
+ submitLoding:false,
rules: {
name: [
- { required: true, message: "请输入名称", trigger: "blur" }
+ { required: true, message: "名称不能为空", trigger: "blur" }
// { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
],
questioncat: [
- { required: true, message: "请选择题库范围", trigger: "change" }
+ { required: true, message: "题库范围不能为空", trigger: "change" }
],
- duration: [
- { type: 'number', required: true, message: "请填写时间限制", trigger: "blur" }
+ limit: [
+ { required: true, message: "时间限制不能为空"},
+ { type: "number", message: "时间限制必须是数字"}
],
passscore: [
- { type: 'number', required: true, message: "请填写及格分数", trigger: "blur" }
+ { required: true, message: "及格分数不能为空"},
+ { type: "number", message: "及格分数必须是数字"}
]
}
@@ -124,12 +121,28 @@ export default {
this.getSubjectAll();
},
methods: {
+ maxDanxuan() {
+ return this.typecount.danxuan
+ },
+ maxDuoxuan() {
+ return this.typecount.duoxuan
+ },
+ maxPanduan() {
+ return this.typecount.panduan
+ },
submitForm(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
- alert("submit!");
+ this.submitLoding = true
+ createTestRule(this.Form).then(response => {
+ this.submitLoding = false
+ this.$message({
+ type: "success",
+ message: "新建成功!"
+ });
+ this.goBack()
+ });
} else {
- console.log("error submit!!");
return false;
}
});
@@ -139,24 +152,29 @@ export default {
this.subjectData = genTree(response.data) ;
});
},
- getQuestioncatAll() {
- getQuestioncatAll({pid:this.ruleForm.subject}).then(response => {
+ getQuestioncatAll(val) {
+ getQuestioncatAll({pid:val}).then(response => {
this.questioncatData = genTree(response.data) ;
});
},
- getQuestionCount() {
- console.log(this.ruleForm.questioncat)
- // getQuestionCount({ids:this.ruleForm.questioncat}).then(response => {
- // this.typecount = response.data
- // });
+ getQuestionCount(val) {
+ if (val==false){
+ getQuestionCount({ids:this.Form.questioncat}).then(response => {
+ this.typecount = response.data
+ });
+ }
+
},
- calScore() {
- let detail = this.ruleForm.detail
- let score = detail.danxuan.count * detail.danxuan.score + detail.duoxuan.count * detail.duoxuan.score + detail.panduan.count * detail.panduan.score
- this.ruleForm.detail.score = score
+ calScore(current,old) {
+ 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.totalscore = score
},
resetForm(formName) {
this.$refs[formName].resetFields();
+ },
+ goBack() {
+ this.$router.replace('/sjmanage/testrule/')
}
}
};
diff --git a/test_mini/app.json b/test_mini/app.json
index 68905bb..7e83dba 100644
--- a/test_mini/app.json
+++ b/test_mini/app.json
@@ -8,7 +8,10 @@
"pages/subject/index",
"pages/lianxi/main",
"pages/about/about",
- "pages/cuoti/index"
+ "pages/cuoti/index",
+ "pages/moni/index",
+ "pages/moni/note",
+ "pages/test/test"
],
"window": {
"backgroundTextStyle": "light",
diff --git a/test_mini/pages/cuoti/index.js b/test_mini/pages/cuoti/index.js
index 647644f..8ed06eb 100644
--- a/test_mini/pages/cuoti/index.js
+++ b/test_mini/pages/cuoti/index.js
@@ -28,6 +28,7 @@ Page({
*/
onLoad: function (options) {
var that = this
+ wx.showLoading({})
try {
var value = wx.getStorageSync('ctms')
if (value) {
@@ -36,7 +37,8 @@ Page({
tmtotal: value.length
})
}
- } catch (e) { }
+ wx.hideLoading()
+ } catch (e) { wx.hideLoading()}
try {
const res = wx.getSystemInfoSync()
that.setData({
diff --git a/test_mini/pages/lianxi/index.wxml b/test_mini/pages/lianxi/index.wxml
index e24e6a7..5234cf2 100644
--- a/test_mini/pages/lianxi/index.wxml
+++ b/test_mini/pages/lianxi/index.wxml
@@ -6,7 +6,7 @@
-
+
diff --git a/test_mini/pages/main/main.js b/test_mini/pages/main/main.js
index 887d9f7..b5b4f55 100644
--- a/test_mini/pages/main/main.js
+++ b/test_mini/pages/main/main.js
@@ -129,5 +129,19 @@ Page({
duration: 1500
})
}
+ },
+ goMoni: function () {
+ let nowSubject = wx.getStorageSync('nowSubject')
+ if (nowSubject) {
+ wx.navigateTo({
+ url: '/pages/moni/index',
+ })
+ } else {
+ wx.showToast({
+ title: '请先选择学科',
+ icon: 'none',
+ duration: 1500
+ })
+ }
}
})
\ No newline at end of file
diff --git a/test_mini/pages/main/main.wxml b/test_mini/pages/main/main.wxml
index b0c6b1d..bc4eacf 100644
--- a/test_mini/pages/main/main.wxml
+++ b/test_mini/pages/main/main.wxml
@@ -41,9 +41,9 @@
考试
-
+
-
+
模拟考试
diff --git a/test_mini/pages/moni/index.js b/test_mini/pages/moni/index.js
new file mode 100644
index 0000000..c42669e
--- /dev/null
+++ b/test_mini/pages/moni/index.js
@@ -0,0 +1,103 @@
+// pages/lianxi/index.js
+const api = require("../../utils/request.js");
+Page({
+
+ /**
+ * 页面的初始数据
+ */
+ data: {
+ ruleData: [],
+ isLoad: true
+ },
+
+ /**
+ * 生命周期函数--监听页面加载
+ */
+ onLoad: function () {
+ try {
+ var value = wx.getStorageSync('nowSubject')
+ if (value) {
+ this.setData({
+ subjectId: value.id
+ })
+ }
+ } catch (e) {
+ wx.navigateBack({
+ })
+ }
+ },
+
+ /**
+ * 生命周期函数--监听页面初次渲染完成
+ */
+ onReady: function () {
+
+ },
+
+ /**
+ * 生命周期函数--监听页面显示
+ */
+ onShow: function () {
+ this.getList()
+ },
+ getList: function () {
+ var that = this
+ api.request('examtest/testrule/', 'GET', { 'subject': that.data.subjectId }).then(res => {
+ if (res.code == 200) {
+ if (res.data.length > 0) {
+ that.setData({
+ ruleData: res.data
+ })
+ }
+ }
+ })
+ },
+ /**
+ * 生命周期函数--监听页面隐藏
+ */
+ onHide: function () {
+
+ },
+
+ /**
+ * 生命周期函数--监听页面卸载
+ */
+ onUnload: function () {
+
+ },
+
+ /**
+ * 页面相关事件处理函数--监听用户下拉动作
+ */
+ onPullDownRefresh: function () {
+
+ },
+
+ /**
+ * 页面上拉触底事件的处理函数
+ */
+ onReachBottom: function () {
+
+ },
+
+ /**
+ * 用户点击右上角分享
+ */
+ onShareAppMessage: function () {
+
+ },
+
+ genPaper: function (e) {
+ wx.showLoading({
+ title: '正在生成试卷',
+ })
+ api.request('examtest/monitest/', 'GET', { 'rule': e.currentTarget.id }).then(res => {
+ try {
+ wx.setStorageSync('monitest', res.data)
+ } catch (e) { }
+ wx.redirectTo({
+ url: 'note',
+ })
+ })
+ },
+})
\ No newline at end of file
diff --git a/test_mini/pages/moni/index.json b/test_mini/pages/moni/index.json
new file mode 100644
index 0000000..2317f37
--- /dev/null
+++ b/test_mini/pages/moni/index.json
@@ -0,0 +1,4 @@
+{
+ "usingComponents": {},
+ "navigationBarTitleText": "出题规则"
+}
\ No newline at end of file
diff --git a/test_mini/pages/moni/index.wxml b/test_mini/pages/moni/index.wxml
new file mode 100644
index 0000000..8280266
--- /dev/null
+++ b/test_mini/pages/moni/index.wxml
@@ -0,0 +1,19 @@
+
+
+
+当前学科出题规则
+
+
+
+
+
+ {{item.desc}}
+
+ 生成考试
+
+
+
+
+
+
+
diff --git a/test_mini/pages/moni/index.wxss b/test_mini/pages/moni/index.wxss
new file mode 100644
index 0000000..1214bd9
--- /dev/null
+++ b/test_mini/pages/moni/index.wxss
@@ -0,0 +1 @@
+/* pages/moni/index.wxss */
\ No newline at end of file
diff --git a/test_mini/pages/moni/note.js b/test_mini/pages/moni/note.js
new file mode 100644
index 0000000..cdcffbf
--- /dev/null
+++ b/test_mini/pages/moni/note.js
@@ -0,0 +1,77 @@
+// pages/examtest/note.js
+var util = require('../../utils/util.js')
+Page({
+
+ /**
+ * 页面的初始数据
+ */
+ data: {
+ },
+
+ /**
+ * 生命周期函数--监听页面加载
+ */
+ onLoad: function () {
+ try {
+ var value = wx.getStorageSync('monitest')
+ if (value) {
+ let monitest = value
+ delete monitest['questions']
+ this.setData(monitest)
+ }
+ } catch (e) { }
+
+ },
+ /**
+ * 生命周期函数--监听页面初次渲染完成
+ */
+ onReady: function () {
+
+ },
+
+ /**
+ * 生命周期函数--监听页面显示
+ */
+ onShow: function () {
+
+ },
+ /**
+ * 生命周期函数--监听页面隐藏
+ */
+ onHide: function () {
+
+ },
+
+ /**
+ * 生命周期函数--监听页面卸载
+ */
+ onUnload: function () {
+
+ },
+
+ /**
+ * 页面相关事件处理函数--监听用户下拉动作
+ */
+ onPullDownRefresh: function () {
+
+ },
+
+ /**
+ * 页面上拉触底事件的处理函数
+ */
+ onReachBottom: function () {
+
+ },
+
+ /**
+ * 用户点击右上角分享
+ */
+ onShareAppMessage: function () {
+
+ },
+ startTest: function () {
+ wx.redirectTo({
+ url: '/pages/test/test',
+ })
+ },
+})
\ No newline at end of file
diff --git a/test_mini/pages/moni/note.json b/test_mini/pages/moni/note.json
new file mode 100644
index 0000000..28a2a8e
--- /dev/null
+++ b/test_mini/pages/moni/note.json
@@ -0,0 +1,4 @@
+{
+ "usingComponents": {},
+ "navigationBarTitleText": "考试须知"
+}
\ No newline at end of file
diff --git a/test_mini/pages/moni/note.wxml b/test_mini/pages/moni/note.wxml
new file mode 100644
index 0000000..fd4c2eb
--- /dev/null
+++ b/test_mini/pages/moni/note.wxml
@@ -0,0 +1,22 @@
+
+
+
+ 考试须知
+ 1.考试详情
+ 名称:{{name}}
+ 答卷时长:{{limit}}分钟
+ {{danxuan_count}}道单选题,每题{{danxuan_score}}分
+ {{duoxuan_count}}道单选题,每题{{duoxuan_score}}分
+ {{panduan_count}}道单选题,每题{{panduan_score}}分
+ 满分{{totalscore}};{{passscore}}以上通过
+
+
+ 2.答题须知
+ 进入答题后请不要后退或返回桌面
+ 用户可点击上一题/下一题进行切换答题
+ 可点击答题卡复查
+ 请合理安排时间答题,可提前交卷,超时会自动提交
+
+
+ 开始考试
+
\ No newline at end of file
diff --git a/test_mini/pages/moni/note.wxss b/test_mini/pages/moni/note.wxss
new file mode 100644
index 0000000..cc6af1e
--- /dev/null
+++ b/test_mini/pages/moni/note.wxss
@@ -0,0 +1 @@
+/* pages/moni/note.wxss */
\ No newline at end of file
diff --git a/test_mini/pages/subject/index.wxml b/test_mini/pages/subject/index.wxml
index 3622de5..6f2a887 100644
--- a/test_mini/pages/subject/index.wxml
+++ b/test_mini/pages/subject/index.wxml
@@ -7,7 +7,7 @@
-
+
diff --git a/test_mini/pages/test/test.js b/test_mini/pages/test/test.js
new file mode 100644
index 0000000..f384bc9
--- /dev/null
+++ b/test_mini/pages/test/test.js
@@ -0,0 +1,157 @@
+// pages/lianxi/main.js
+const api = require("../../utils/request.js");
+var util = require('../../utils/util.js')
+Page({
+
+ /**
+ * 页面的初始数据
+ */
+ data: {
+ tms:[],
+ tmIndex: 0,
+ },
+ radioChange: function (e) {
+ var that = this
+ that.data.currentTm['userChecked'] = e.detail.value
+ that.data.tms[that.data.tmIndex] = that.data.currentTm
+ },
+ checkboxChange: function (e) {
+ var that = this
+ that.data.currentTm['userChecked'] = e.detail.value
+ that.data.tms[that.data.tmIndex] = that.data.currentTm
+ },
+ /**
+ * 生命周期函数--监听页面加载
+ */
+ onLoad: function () {
+ var that = this
+ try {
+ var value = wx.getStorageSync('monitest')
+ if (value) {
+ that.data.monitest = value
+ that.data.tms = value.questions
+ that.setData({
+ tmtotal:value.questions.length
+ })
+ that.showTm(that.data.tmIndex)
+ }
+ } catch (e) { }
+ try {
+ const res = wx.getSystemInfoSync()
+ that.setData({
+ scrollHeight: res.windowHeight - 70
+ })
+ } catch (e) {
+ }
+ },
+ /**
+ * 生命周期函数--监听页面初次渲染完成
+ */
+ onReady: function () {
+
+ },
+
+ /**
+ * 生命周期函数--监听页面显示
+ */
+ onShow: function () {
+ wx.hideHomeButton({})
+ },
+
+ /**
+ * 生命周期函数--监听页面隐藏
+ */
+ onHide: function () {
+
+ },
+
+ /**
+ * 生命周期函数--监听页面卸载
+ */
+ onUnload: function () {
+ },
+
+ /**
+ * 页面相关事件处理函数--监听用户下拉动作
+ */
+ onPullDownRefresh: function () {
+
+ },
+
+ /**
+ * 页面上拉触底事件的处理函数
+ */
+ onReachBottom: function () {
+
+ },
+
+ /**
+ * 用户点击右上角分享
+ */
+ onShareAppMessage: function () {
+
+ },
+
+ showTm: function (index) {
+ var that = this
+ var currentTm = that.data.tms[index]
+ that.setData({
+ 'tmIndex': index,
+ 'currentTm': currentTm
+ })
+ that.showOptions()
+ },
+ // panTi: function () {
+ // var that = this
+ // let currentTm = that.data.currentTm
+ // let isright = false
+ // if (currentTm.type == 2) {
+ // if (currentTm.userChecked) {
+ // if (currentTm.userChecked.sort().toString() == currentTm.right.sort().toString()) {
+ // isright = true
+ // }
+ // }
+
+ // } else {
+ // isright = currentTm.right == currentTm.userChecked
+ // }
+ // if (isright == false && currentTm.userChecked != undefined) {
+ // currentTm.dtime = util.formatTime(new Date())
+ // that.data.ctms.unshift(currentTm)
+ // if (that.data.ctms.length > 40) {
+ // that.data.ctms.length = 40
+ // }
+ // }
+ // return isright
+ // },
+ next: function () {
+ var that = this
+ var tmIndex = that.data.tmIndex + 1
+ that.showTm(tmIndex)
+ },
+ previous: function () {
+ var that = this
+ var tmIndex = that.data.tmIndex - 1
+ that.showTm(tmIndex)
+ },
+ showOptions: function () {
+ let currentTm = this.data.currentTm
+ let options = []
+ for (let key in currentTm.options) {
+ let option = {}
+ option.key = key
+ option.value = key + ':' + currentTm.options[key]
+ if (currentTm.userChecked) {
+ if (key == currentTm.userChecked || currentTm.userChecked.indexOf(key) != -1) {
+ option.checked = true
+ }
+ } else {
+ option.checked = false
+ }
+ options.push(option)
+ }
+ this.setData({
+ options: options
+ })
+ },
+})
\ No newline at end of file
diff --git a/test_mini/pages/test/test.json b/test_mini/pages/test/test.json
new file mode 100644
index 0000000..9c848e5
--- /dev/null
+++ b/test_mini/pages/test/test.json
@@ -0,0 +1,4 @@
+{
+ "usingComponents": {},
+ "navigationBarTitleText": "考试中"
+}
\ No newline at end of file
diff --git a/test_mini/pages/test/test.wxml b/test_mini/pages/test/test.wxml
new file mode 100644
index 0000000..c623c4c
--- /dev/null
+++ b/test_mini/pages/test/test.wxml
@@ -0,0 +1,55 @@
+
+ 题量: {{tmIndex+1}}/{{tmtotal}}
+
+
+
+ {{tmIndex+1}}.
+ 单选题
+ 多选题
+ 判断题
+ ({{currentTm.score}}分)
+
+ {{currentTm.name}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 交卷
+
+
\ No newline at end of file
diff --git a/test_mini/pages/test/test.wxss b/test_mini/pages/test/test.wxss
new file mode 100644
index 0000000..0ee5e6b
--- /dev/null
+++ b/test_mini/pages/test/test.wxss
@@ -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
+}
+
diff --git a/test_server/examtest/migrations/0004_auto_20200318_0938.py b/test_server/examtest/migrations/0004_auto_20200318_0938.py
new file mode 100644
index 0000000..ac2858c
--- /dev/null
+++ b/test_server/examtest/migrations/0004_auto_20200318_0938.py
@@ -0,0 +1,57 @@
+# Generated by Django 3.0.4 on 2020-03-18 01:38
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('examtest', '0003_auto_20200317_2157'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='testrule',
+ name='detail',
+ ),
+ migrations.AddField(
+ model_name='testrule',
+ name='danxuan_count',
+ field=models.IntegerField(default=0, verbose_name='单选数量'),
+ ),
+ migrations.AddField(
+ model_name='testrule',
+ name='danxuan_score',
+ field=models.IntegerField(default=0, verbose_name='单选分数'),
+ ),
+ migrations.AddField(
+ model_name='testrule',
+ name='duoxuan_count',
+ field=models.IntegerField(default=0, verbose_name='多选数量'),
+ ),
+ migrations.AddField(
+ model_name='testrule',
+ name='duoxuan_score',
+ field=models.IntegerField(default=0, verbose_name='多选分数'),
+ ),
+ migrations.AddField(
+ model_name='testrule',
+ name='panduan_count',
+ field=models.IntegerField(default=0, verbose_name='判断数量'),
+ ),
+ migrations.AddField(
+ model_name='testrule',
+ name='panduan_score',
+ field=models.IntegerField(default=0, verbose_name='判断分数'),
+ ),
+ migrations.AddField(
+ model_name='testrule',
+ name='passscore',
+ field=models.IntegerField(default=0, verbose_name='及格分数'),
+ ),
+ migrations.AddField(
+ model_name='testrule',
+ name='score',
+ field=models.IntegerField(default=0, verbose_name='总分'),
+ ),
+ ]
diff --git a/test_server/examtest/migrations/0005_testrule_limit.py b/test_server/examtest/migrations/0005_testrule_limit.py
new file mode 100644
index 0000000..897c70f
--- /dev/null
+++ b/test_server/examtest/migrations/0005_testrule_limit.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.0.4 on 2020-03-18 01:48
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('examtest', '0004_auto_20200318_0938'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='testrule',
+ name='limit',
+ field=models.IntegerField(default=0, verbose_name='限时(分钟)'),
+ ),
+ ]
diff --git a/test_server/examtest/migrations/0006_auto_20200318_1634.py b/test_server/examtest/migrations/0006_auto_20200318_1634.py
new file mode 100644
index 0000000..2fda9b8
--- /dev/null
+++ b/test_server/examtest/migrations/0006_auto_20200318_1634.py
@@ -0,0 +1,22 @@
+# Generated by Django 3.0.4 on 2020-03-18 08:34
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('examtest', '0005_testrule_limit'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='testrule',
+ name='score',
+ ),
+ migrations.AddField(
+ model_name='testrule',
+ name='totalscore',
+ field=models.IntegerField(default=0, verbose_name='满分'),
+ ),
+ ]
diff --git a/test_server/examtest/models.py b/test_server/examtest/models.py
index 41cc221..1f7ccea 100644
--- a/test_server/examtest/models.py
+++ b/test_server/examtest/models.py
@@ -9,4 +9,12 @@ class TestRule(CommonModel):
desc = models.TextField(verbose_name='描述', default='')
subject = models.ForeignKey(Questioncat, blank=True, null=True, on_delete=models.CASCADE, verbose_name='所属学科', related_name='subject')
questioncat = models.ManyToManyField(Questioncat, verbose_name='所选题库')
- detail = JSONField(verbose_name='试卷结构')
\ No newline at end of file
+ danxuan_count = models.IntegerField(default=0, verbose_name='单选数量')
+ danxuan_score = models.IntegerField(default=0, verbose_name='单选分数')
+ duoxuan_count = models.IntegerField(default=0, verbose_name='多选数量')
+ duoxuan_score = models.IntegerField(default=0, verbose_name='多选分数')
+ panduan_count = models.IntegerField(default=0, verbose_name='判断数量')
+ panduan_score = models.IntegerField(default=0, verbose_name='判断分数')
+ limit = models.IntegerField(default=0, verbose_name='限时(分钟)')
+ totalscore = models.IntegerField(default=0, verbose_name='满分')
+ passscore = models.IntegerField(default=0, verbose_name='及格分数')
\ No newline at end of file
diff --git a/test_server/examtest/serializers.py b/test_server/examtest/serializers.py
index 4223345..839103b 100644
--- a/test_server/examtest/serializers.py
+++ b/test_server/examtest/serializers.py
@@ -4,9 +4,31 @@ from .models import TestRule
+class TestRuleListSerializer(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 = TestRule
+ fields = ('id', 'name', 'create_time', 'update_time', 'subject', 'desc')
+ depth = 1
+
+
+class TestRuleCreateSerializer(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 = TestRule
+ fields = '__all__'
+
class TestRuleSerializer(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)
@@ -16,4 +38,5 @@ class TestRuleSerializer(serializers.ModelSerializer):
depth = 1
+
diff --git a/test_server/examtest/urls.py b/test_server/examtest/urls.py
index 6554ec3..2f8505e 100644
--- a/test_server/examtest/urls.py
+++ b/test_server/examtest/urls.py
@@ -1,5 +1,5 @@
from django.urls import path,include
-from .views import TestRuleViewSet
+from .views import TestRuleViewSet, MoniTestView
from rest_framework import routers
@@ -7,5 +7,6 @@ router = routers.DefaultRouter()
router.register('testrule', TestRuleViewSet, basename="testrule")
urlpatterns = [
+ path('monitest/',MoniTestView.as_view()),
path('', include(router.urls)),
]
diff --git a/test_server/examtest/views.py b/test_server/examtest/views.py
index 3f29333..b5c0a3f 100644
--- a/test_server/examtest/views.py
+++ b/test_server/examtest/views.py
@@ -9,15 +9,63 @@ from rest_framework import status
from django_filters.rest_framework import DjangoFilterBackend
from openpyxl import Workbook, load_workbook
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
+from datetime import datetime
from utils.custom import CommonPagination
from rbac.permission import RbacPermission
+from question.models import Question
+from question.serializers import QuestionSerializer
from .models import TestRule
-from .serializers import TestRuleSerializer
+from .serializers import TestRuleSerializer, TestRuleListSerializer, TestRuleCreateSerializer
from server import settings
from crm.authentication import ConsumerTokenAuthentication
# Create your views here.
+
+class MoniTestView(APIView):
+ authentication_classes = [ConsumerTokenAuthentication]
+ permission_classes = []
+
+ def get(self, request, *args, **kwargs):
+ if request.query_params.get('rule', None):
+ ret = {}
+ testrule = TestRule.objects.get(id = request.query_params.get('rule'))
+ ret['name'] = '自助模考' + datetime.now().strftime('%Y%m%d%H%M')
+ ret['type'] = 1 # 自助模拟考试
+ ret['rule'] = testrule.id
+ ret['limit'] = testrule.limit
+ ret['totalscore'] = testrule.totalscore
+ ret['passscore'] = testrule.passscore
+ 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=1).order_by('?')[:ret['danxuan_count']]
+ question_queryset = question_queryset | danxuan
+ if ret['duoxuan_count']:
+ duoxuan = queryset.filter(type=2).order_by('?')[:ret['duoxuan_count']]
+ question_queryset = question_queryset | duoxuan
+ if ret['panduan_count']:
+ panduan = queryset.filter(type=3).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['score'] = ret['danxuan_score']
+ elif i['type'] == 2:
+ i['score'] = ret['duoxuan_score']
+ else:
+ i['score'] = ret['panduan_score']
+ ret['questions'] = questions
+ return Response(ret)
+
+
+
class TestRuleViewSet(ModelViewSet):
"""
模考规则:增删改查
@@ -30,4 +78,34 @@ class TestRuleViewSet(ModelViewSet):
serializer_class = TestRuleSerializer
ordering_fields = ('id',)
ordering = ['id']
- search_fields = ('^name',)
\ No newline at end of file
+ search_fields = ('^name',)
+
+ def get_serializer(self, *args, **kwargs):
+ """
+ Return the serializer instance that should be used for validating and
+ deserializing input, and for serializing output.
+ """
+ if self.action == 'list':
+ serializer_class = TestRuleListSerializer
+ elif self.action == 'create':
+ serializer_class = TestRuleCreateSerializer
+ else:
+ serializer_class = TestRuleSerializer
+ kwargs['context'] = self.get_serializer_context()
+ return serializer_class(*args, **kwargs)
+
+ def get_authenticators(self):
+ """
+ GET请求不做登陆验证
+ """
+ if self.request.method == 'GET':
+ self.authentication_classes = []
+ return [auth() for auth in self.authentication_classes]
+
+ def get_permissions(self):
+ """
+ GET请求不做权限验证
+ """
+ if self.request.method == 'GET':
+ self.permission_classes = []
+ return [permission() for permission in self.permission_classes]
\ No newline at end of file
diff --git a/test_server/question/views.py b/test_server/question/views.py
index d56b8aa..17160b4 100644
--- a/test_server/question/views.py
+++ b/test_server/question/views.py
@@ -125,16 +125,17 @@ class QuestionViewSet(ModelViewSet):
instance.save()
return Response(status=status.HTTP_204_NO_CONTENT)
- @action(methods=['get'], detail=False, permission_classes=[IsAuthenticated],
+ @action(methods=['post'], detail=False, permission_classes=[IsAuthenticated],
url_path='count', url_name='question_count')
def count(self, request):
ret = {'danxuan':0,'duoxuan':0,'panduan':0}
queryset = self.queryset
- if request.query_params.get('ids',None):
- queryset = queryset.filter(questioncat__in = request.query_params.get('ids'))
+ if request.data.get('ids',None):
+ queryset = queryset.filter(questioncat__in = request.data.get('ids'))
ret['danxuan'] = queryset.filter(type=1).count()
- ret['duoxuan'] = queryset.filter(type=1).count()
- ret['panduan'] = queryset.filter(type=1).count()
+ ret['duoxuan'] = queryset.filter(type=2).count()
+ ret['panduan'] = queryset.filter(type=3).count()
+ print(ret)
return Response(ret)