这一节我们把测试模块实现出来,并提供模块的wxml、wxss、js源代码。
实现后的效果图:


代码结构图:

一、wxml
<!--pages/ceshizh/ceshizh.wxml-->
<view class='top'>
<view class='topLeft'><text style='margin-left:20rpx;'>{{tikuleixing2}} {{tikuxuhao2}}</text></view>
<view class='topRight'>
<view class='topRightContent'>
<text style='color:#1bd0bd;font-size:50rpx; font-style:italic;margin-right:10rpx;'>{{tihaox}}</text><text> /20 </text>
</view>
</view>
</view>
<view class='timu'>
<view wx:for="{{jieguo}}" wx:key="item" >{{item.tigan}}</view>
</view>
<view class='daan'>
<view class='daan_fir'>
<view hover-class='dongtai' hover-stay-time='400' style="color:{{color1}}" data-text="{{item.ans}}" class='daan1' wx:for="{{daanluanxu}}" wx:key="item" bindtap='panduicuo1'>{{item.ans}}</view>
<view class='daan1_1' hidden="{{hidden1}}"> {{zhengwutext}}</view>
</view>
<view class='daan_sec'>
<view hover-class='dongtai' hover-stay-time='400' style="color:{{color2}}" data-text="{{item.ansx}}" class='daan2' wx:for="{{daanluanxu}}" wx:key="item" bindtap='panduicuo2'>{{item.ansx}}</view>
<view class='daan2_1' hidden="{{hidden2}}"> {{zhengwutext}}</view>
</view>
<view class='daan_thi'>
<view hover-class='dongtai' hover-stay-time='400' style="color:{{color3}}" data-text="{{item.ansy}}" class='daan3' wx:for="{{daanluanxu}}" wx:key="item" bindtap='panduicuo3'>{{item.ansy}}</view>
<view class='daan3_1' hidden="{{hidden3}}"> {{zhengwutext}}</view>
</view>
</view>
<button class='finish' bindtap='finish'>结束测试</button>
二、wxss
.top{
height: 100rpx;
width: 100%;
border-bottom: 1px solid #c9c9c9;
}
.topLeft{
display:flex;
font-size:35rpx;
align-items:center;
float: left;
width: 50%;
height: 100%;
}
.topRight{
display:flex;
align-items:center;
float: right;
width: 50%;
height: 100%;
}
.topRightContent{
position: fixed;
margin-right: 20rpx;
right: 0;
text-align: right;
}
.timu{
color: #060000;
margin: 30rpx 30rpx 30rpx 30rpx;
font-size: 40rpx;
height: 300rpx;
border-bottom: 1rpx solid #c9c9c9;
}
.daan{
display:flex;
flex-direction:column;
justify-content:space-around;
color: #5A5A5A;
margin: 30rpx 30rpx 30rpx 30rpx;
font-size: 40rpx;
height: 350rpx;
border: 1rpx solid #ffffff;
}
.dongtai{
opacity: 0.8;
transform: scale(1.2,1.2);
padding-left:20px;
}
.daan_fir{
display:flex;
flex-direction:row;
width: 100%;
}
.daan_sec{
display:flex;
flex-direction:row;
width: 100%;
}
.daan_thi{
display:flex;
flex-direction:row;
width: 100%;
}
.daan1_1{
margin-left: 130rpx;
font-size: 40rpx;
}
.daan2_1{
margin-left: 130rpx;
font-size: 40rpx;
}
.daan3_1{
margin-left: 130rpx;
font-size: 40rpx;
}
.finish{
width: 30%;
height:80rpx;
margin-right: 60rpx;
}
三、js
// pages/ceshizh/ceshizh.js
const app = getApp()
Page({
data: {
//右上角显示的第几题调试程序时,显示随机抽到的题号
tihaox: 1,
//做到第几题
tempt: 1,
//缓存查询到的结果
jieguo: null,
//答案数组
daan:null,
//随机乱序的答案
daanluanxu: null,
//页面左上角显示选择的题库
tikuxianshi: null,
//答对或者答错时显示的颜色和正误结果
color1: null,
color2: null,
color3: null,
hidden1:true,
hidden2:true,
hidden3:true,
//正误文字
zhengwutext: null,
//从题库的前20个题中抽取题目,用于第一个测试题
timushu:20,
//答对和答错的题数
corans:0,
wroans:0,
tikuleixing2: null,
tikuxuhao2: null
},
chaxun: function (e) {
this.setData({
color1: null,
color2: null,
color3: null,
hidden1: true,
hidden2: true,
hidden3: true,
})
var tiku = wx.getStorageSync('cstikuzhi').toString();
var tk = 'gx' + tiku;
const db = wx.cloud.database()
var that = this
db.collection(tk).where({
tihao: e,
})
.get({
success(res) {
//在一个事件的接口调用成功的回调函数里执行另一个事件,用that.
that.setData({
jieguo: res.data,
})
//显示乱序后的备选项
that.daanluanxu()
}
})
},
//打乱选项顺序
daanluanxu:function(){
//以原答案建立数组
var daan = [this.data.jieguo[0].ans, this.data.jieguo[0].ansx, this.data.jieguo[0].ansy]
//刷新data中daan的值,函数panduicuo中会用
this.setData({
daan:daan
})
//打乱数组元素顺序
var daantemp = daan.sort(() => Math.random() - 0.5)
//以新顺序建立数组对象
var daanluanxu2 = [{ ans: daantemp[0], ansx: daantemp[1] , ansy: daantemp[2]}]
this.setData({
daanluanxu:daanluanxu2
})
},
openAlert: function (e) {
wx.showModal({
title: '本次测试结果',
content: e,
showCancel: false,
success: function (res) {
if (res.confirm) {
wx.switchTab({
url: '/pages/ceshixz/ceshixz',
success: function (res) {
},
fail: function (res) { },
complete: function (res) { },
})
}
}
});
},
onAdd: function () {
const db = wx.cloud.database()
db.collection('cuotiku').add({
data: {
tigan: this.data.jieguo[0].tigan,
ans: this.data.jieguo[0].ans
},
success: res => {
},
fail: err => {
}
})
},
panduicuo1:function(e){
var tempt=this.data.tempt
var tihaox=this.data.tihaox
var corans=this.data.corans
var wroans=this.data.wroans
//回答与正确答案是否一致
if (e.currentTarget.dataset.text === this.data.daan[0]) {
this.setData({
color1: 'green',
zhengwutext: '回答正确',
hidden1: false,
corans: corans + 1
})
}
else {
this.setData({
color1: 'red',
zhengwutext: '回答错误',
hidden1: false,
wroans: wroans + 1,
})
//回答错误,把此题加入错题库
this.onAdd()
}
//是否已答20个题
if (tempt<20){
var cxs=this.random()
var that = this
//延时0.5秒后,查询下一个题,答题计数器加1,右上角题数加1
setTimeout(function () {
//调试需要把cxs强制改成了1
that.chaxun(cxs)
that.setData({
tempt: tempt + 1,
tihaox: tihaox + 1
})
}, 500)
}
else{
var e='答对题数:'+this.data.corans.toString()+' , '+'答错题数:'+this.data.wroans.toString()
console.log(e)
this.openAlert(e)
}
},
panduicuo2: function (e) {
var tempt = this.data.tempt
var tihaox = this.data.tihaox
var corans = this.data.corans
var wroans = this.data.wroans
//回答与正确答案是否一致
if (e.currentTarget.dataset.text === this.data.daan[0]) {
this.setData({
color2: 'green',
zhengwutext: '回答正确',
hidden2: false,
corans: corans + 1
})
}
else {
this.setData({
color2: 'red',
zhengwutext: '回答错误',
hidden2: false,
wroans: wroans + 1
})
//回答错误,把此题加入错题库
this.onAdd()
}
//是否已答20个题
if (tempt < 20) {
var cxs = this.random()
var that = this
//延时0.5秒后,查询下一个题,答题计数器加1,右上角题数加1
setTimeout(function () {
//调试需要把cxs强制改成了1
that.chaxun(cxs)
that.setData({
tempt: tempt + 1,
tihaox: tihaox + 1
})
}, 500)
}
else {
var e = '答对题数:' + this.data.corans.toString() + ' , ' + '答错题数:' + this.data.wroans.toString()
console.log(e)
this.openAlert(e)
}
},
panduicuo3: function (e) {
var tempt = this.data.tempt
var tihaox = this.data.tihaox
var corans = this.data.corans
var wroans = this.data.wroans
//回答与正确答案是否一致
if (e.currentTarget.dataset.text === this.data.daan[0]) {
this.setData({
color3: 'green',
zhengwutext: '回答正确',
hidden3: false,
corans: corans + 1
})
}
else {
this.setData({
color3: 'red',
zhengwutext: '回答错误',
hidden3: false,
wroans: wroans + 1
})
//回答错误,把此题加入错题库
this.onAdd()
}
//是否已答20个题
if (tempt < 20) {
var cxs = this.random()
var that = this
//延时0.5秒后,查询下一个题,答题计数器加1,右上角题数加1
setTimeout(function () {
//调试需要把cxs强制改成了1
that.chaxun(cxs)
that.setData({
tempt: tempt + 1,
tihaox: tihaox + 1
})
}, 500)
}
else {
var e = '答对题数:' + this.data.corans.toString() + ' , ' + '答错题数:' + this.data.wroans.toString()
console.log(e)
this.openAlert(e)
}
},
openConfirm: function (e) {
wx.showModal({
title: '结束测试',
content: e,
confirmText: "确定结束",
cancelText: "继续测试",
success: function (res) {
console.log(res);
if (res.confirm) {
console.log('用户点击主操作')
wx.switchTab({
url: '/pages/ceshixz/ceshixz',
success: function (res) {
},
fail: function (res) { },
complete: function (res) { },
})
} else {
console.log('用户点击辅助操作')
}
}
});
},
finish:function(){
var e = '当前答对:'+this.data.corans.toString()+'题' + ' , ' + '答错:'+this.data.wroans.toString()+'题。'+'您确定要结束本次测试吗?'
this.openConfirm(e)
},
//获取题库的题目数,用于随机数函数生成抽到的题
timushu: function () {
var tiku = wx.getStorageSync('cstikuzhi').toString();
var tk = 'gx' + tiku;
const db = wx.cloud.database()
var that = this
db.collection(tk).count({
success(res) {
that.setData({
timushu: res.total
})
}
})
},
//生成随机数函数
random: function () {
var suijitemp = Math.random() * this.data.timushu
var suiji = Math.round(suijitemp) + 1
return suiji
},
onGetOpenid: function () {
// 调用云函数
wx.cloud.callFunction({
name: 'login',
data: {},
success: res => {
console.log('[云函数] [login] user openid: ', res.result.openid)
app.globalData.openid = res.result.openid
},
fail: err => {
console.error('[云函数] [login] 调用失败', err)
wx.navigateTo({
url: '../deployFunctions/deployFunctions',
})
}
})
},
onLoad: function (options) {
var tiku2 = wx.getStorageSync('cstikuzhi');
this.timushu()
//调用随机数函数,生成随机数firstsuiji
var firstsuiji=this.random()
//下面的跟新题库号和题号应该写到chaxun里,每次调用才都能动态更新。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
this.setData({
tikuxianshi: tiku2
})
//开发测试时,把查询题号由随机数firstsuiji改为了1
this.chaxun(firstsuiji)
this.onGetOpenid()
var global2 = getApp()
this.setData({
tikuleixing2: global2.tikuleixing,
tikuxuhao2: global2.tikuxuhao
})
},
onReady: function () {
},
onShow: function () {
},
onHide: function () {
},
onUnload: function () {
},
onPullDownRefresh: function () {
},
onReachBottom: function () {
},
onShareAppMessage: function () {
return {
title: '大家一起学',
}
}
})
四、关于源代码的说明
- 选定题库后进入答题界面,左上角显示所处的题库
- 每次测试,会从选定的题库中随机抽取20个题,右上角斜体的绿色显示当前答到第几题
- 答题时,会即时展示回答的对错结果,然后记进本次答题的统计中
- 若回答错误,会把答错的题目收录进答题人的错题库用来有针对性地复习(本程序的重要功能)
- 在答完20道题之前,点击结束测试按钮会有一个showModal做确认
- 测试结束后,会展示本次测试的整体情况
- 程序的功能实现已在代码中做了详细的注释