功能需求
这个是整个系统中的核心,也是最难,逻辑繁琐,代码量最多,技巧点最多的页面。
实现根据课程,创建考卷(自动随机选择20单选题),展现在页面上;选题时记录下得分;交卷时计算总分,在页面顶部展现。
界面原型
paper.wxml
<view>
<view class="common-text">
<text class="common-text-left">
学号:{{student.id}}
姓名:{{student.name}}
</text>
<text class="common-text-right">
题号:{{index+1}}/{{detailList.length}}
</text>
</view>
<view class="box" hidden="{{!isUpPaper}}">
<view class="score">您的成绩是:{{scores}} 分</view>
</view>
<view class="box">
<view class="title">问题:</view>
<view class="question">{{detail.problem}}</view>
</view>
<view class="box">
<view class="title">选项:</view>
<radio-group>
<view><radio checked="{{checkeda}}" size="mini" bindtap="selectedRadio" data-word="A" data-index="{{index}}">A:{{detail.a}}</radio></view>
<view><radio checked="{{checkedb}}" bindtap="selectedRadio" data-word="B" data-index="{{index}}">B:{{detail.b}}</radio></view>
<view><radio checked="{{checkedc}}" bindtap="selectedRadio" data-word="C" data-index="{{index}}">C:{{detail.c}}</radio></view>
<view><radio checked="{{checkedd}}" bindtap="selectedRadio" data-word="D" data-index="{{index}}">D:{{detail.d}}</radio></view>
</radio-group>
</view>
<view class="box" hidden="{{!isUpPaper}}">
<view class="title">分析:</view>
<view class="content">{{detail.analysis}}</view>
</view>
<view class="box">
<view class="title">答案:{{detail.answer}}</view>
<view class="title">得分:{{detail.score}}</view>
</view>
<view class="line">
<button class="btn" bindtap="upProblem" size="mini">上一题</button>
<button class="btn" bindtap="downProblem" size="mini">下一题</button>
<button class="btn" bindtap="upPaper" disabled="{{isUpPaper}}" size="mini">交卷</button>
</view>
</view>
page.wxss
字体渐变色样式
Page{
font-size: 24rpx;
}
radio{
margin: 2px;
}
.common-text {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 80rpx;
padding: 0 24rpx;
background: #fff;
}
.common-text-left {
font-size: 30rpx;
color: #333;
font-weight: 500;
margin-left: 30rpx;
}
.common-text-right {
font-size: 26rpx;
font-weight: 400;
color: #959595;
margin-right: 10rpx;
}
.box{
border: 1px solid black;
margin:10px;
padding:5px;
border-radius: 5px;
}
.score{
font-weight: bold;
padding-bottom: 5px;
text-align: center;
color: red;
font-size: 50rpx;
}
.title{
font-weight: bold;
padding-bottom: 5px;
}
.question{
background: linear-gradient(to right, black, green);
-webkit-background-clip: text;
color: transparent;
}
.content{
background: linear-gradient(to right, red, black);
-webkit-background-clip: text;
color: transparent;
}
.line{
display: flex;
text-align: right;
}
.btn{
color: white;
background-color:rgb(109, 165, 109);
width: 50rpx;
}
page.js
/*
功能:
1、学生登录后存储学员信息到本地缓存,从本地缓存读取学生信息,展现在页面顶部
2、ajax请求后台,创建试卷,将试题封装到detailList对象中,每个detail为一个考题
3、index记录当前考题号,从0开始
4、上一题按钮按下时,index--,detail=detailList[index]获取当前考题,在页面展示,注意判断极值已经到达第一题时处理
5、下一题按钮按下时,index++,detail=detailList[index]获取当前考题,在页面展示,注意判断极值已经到达最后一题时处理
6、上一题、下一题切换时,单选框已经被选中的问题,清除选择
6、单选,选择某项时记录下成绩,和detail中的正确答案比对,计算得分,存入数组中对应值
7、交卷,循环数组计算总分,并通知显示,ajax访问后台,最终提交数据库
*/
const app = getApp();
const myhost = app.globalData.myhost;
Page({
data: {
checkeda: false, //标识哪个选项
checkedb: false,
checkedc: false,
checkedd: false,
scores: 0, //最终成绩
resultList: [], //得分结果数组,索引是题号
isUpPaper: false, //是否交卷,交卷就显示分析、得分和答案
index: 0, //当前题号
student: "", //考试学生信息
detailList: "", //试题集合
detail: "" //当前题
},
onLoad(options) {
//准备学生信息
var student = wx.getStorageSync('student');
this.setData({
student: student
});
//因为答题结果存在本地缓存中,所以清除,否则就得垃圾数据会影响现有数据
wx.clearStorage({
success: (res) => {
console.log("缓存已清理")
},
})
wx.setStorageSync('student', student); //上面清除缓存会导致登录信息丢失,重新缓存
//准备试卷信息
var courseid = options.id;
var url = '/paper/createPaper?id=' + courseid +'&studentid='+student.id;
console.log(url);
wx.request({
url: myhost+'/paper/createPaper?id=' + courseid +'&studentid='+this.data.student.id,
method: 'POST',
success: (res)=>{
var list = res.data;
var resultList = Array(list.length).fill(0);
this.setData({
detailList: list,
detail: list[0],
resultList: resultList
})
},
fail(err){
console.log(err)
}
})
},
upProblem(evt){ //向上按钮
var index = this.data.index;
index--;
if(index<0){
index = 0;
}
//当前选项写缓存
var word = wx.getStorageSync('whoChecked-'+index);
//先取消后选择
this.setData({ checkeda: false, checkedb: false, checkedc: false, checkedd: false })
if(word=='A'){
this.setData({ checkeda: true, checkedb: false, checkedc: false, checkedd: false })
}
if(word=='B'){
this.setData({ checkeda: false, checkedb: true, checkedc: false, checkedd: false })
}
if(word=='C'){
this.setData({ checkeda: false, checkedb: false, checkedc: true, checkedd: false })
}
if(word=='D'){
this.setData({ checkeda: false, checkedb: false, checkedc: false, checkedd: true })
}
var detailList = this.data.detailList;
this.setData({
saveHidden: true,
index: index,
detail: detailList[index]
})
},
downProblem(evt){ //向下按钮
var saveHidden = this.data.saveHidden;
var index = this.data.index;
index++;
//当前选项写缓存
var word = wx.getStorageSync('whoChecked-'+index);
//先取消后选择
this.setData({ checkeda: false, checkedb: false, checkedc: false, checkedd: false })
if(word=='A'){
this.setData({ checkeda: true, checkedb: false, checkedc: false, checkedd: false })
}
if(word=='B'){
this.setData({ checkeda: false, checkedb: true, checkedc: false, checkedd: false })
}
if(word=='C'){
this.setData({ checkeda: false, checkedb: false, checkedc: true, checkedd: false })
}
if(word=='D'){
this.setData({ checkeda: false, checkedb: false, checkedc: false, checkedd: true })
}
var detailList = this.data.detailList;
if(index >= detailList.length-1){
index = detailList.length-1;
}
this.setData({
index: index,
detail: detailList[index]
})
},
upPaper(){ //交卷
var scores = this.data.scores;
var resultList = this.data.resultList;
for(var i=0;i<resultList.length;i++){
scores += resultList[i];
}
this.setData({
isUpPaper: true,
scores: scores
})
},
selectedRadio(e){ //选择单选框
var index = this.data.index;
var value = e.currentTarget.dataset.word;
//当前选项写缓存
wx.setStorageSync('whoChecked-'+index, value);
var detail = this.data.detail;
var resultList = this.data.resultList;
//选中的结果和答案比较,正确得5分,不正确得0分
if(detail.answer == value){
detail.score = 5;
resultList[index] = 5;
}else{
detail.score = 0;
resultList[index] = 0;
}
this.setData({
detail: detail,
resultList: resultList
})
}
})