小程序 考试功能初次提交

This commit is contained in:
caoqianming 2022-11-11 17:02:30 +08:00
parent 086c701cfa
commit 4295fe09de
12 changed files with 599 additions and 5 deletions

View File

@ -60,4 +60,5 @@
<style lang="scss"> <style lang="scss">
@import "uview-ui/index.scss"; @import "uview-ui/index.scss";
@import "common/demo.scss"; @import "common/demo.scss";
@import "common/uni-ui.scss";
</style> </style>

View File

@ -44,6 +44,10 @@ const install = (Vue, vm) => {
let getVideos = (params={})=>vm.$u.get('/vod/video/', params);//点播视频 let getVideos = (params={})=>vm.$u.get('/vod/video/', params);//点播视频
let getDickey = (params={})=>vm.$u.get('/system/dict/', params);//查询字典 let getDickey = (params={})=>vm.$u.get('/system/dict/', params);//查询字典
let putMyVideoView =(id)=>vm.$u.put(`/vod/video/${id}/myview/`);//更新本人观看信息 let putMyVideoView =(id)=>vm.$u.put(`/vod/video/${id}/myview/`);//更新本人观看信息
//考试有关
let getExamList = (params={})=>vm.$u.get('/exam/exam/', params);//考试列表
vm.$u.api = {getUserInfo, vm.$u.api = {getUserInfo,
getCode, getCode,
codeLogin, codeLogin,
@ -64,7 +68,9 @@ const install = (Vue, vm) => {
getDocument, getDocument,
getVideos, getVideos,
getDickey, getDickey,
putMyVideoView putMyVideoView,
getExamList
}; };
} }

View File

@ -0,0 +1,119 @@
.uni-flex {
display: flex;
}
.uni-flex-row {
@extend .uni-flex;
flex-direction: row;
box-sizing: border-box;
}
.uni-flex-column {
@extend .uni-flex;
flex-direction: column;
}
.uni-color-gary {
color: #3b4144;
}
/* 标题 */
.uni-title {
display: flex;
margin-bottom: $uni-spacing-col-base;
font-size: $uni-font-size-lg;
font-weight: bold;
color: #3b4144;
}
.uni-title-sub {
display: flex;
// margin-bottom: $uni-spacing-col-base;
font-size: $uni-font-size-base;
font-weight: 500;
color: #3b4144;
}
/* 描述 额外文本 */
.uni-note {
margin-top: 10px;
color: #999;
font-size: $uni-font-size-sm;
}
/* 列表内容 */
.uni-list-box {
@extend .uni-flex-row;
flex: 1;
margin-top: 10px;
}
/* 略缩图 */
.uni-thumb {
flex-shrink: 0;
margin-right: $uni-spacing-row-base;
width: 125px;
height: 75px;
border-radius: $uni-border-radius-lg;
overflow: hidden;
border: 1px #f5f5f5 solid;
image {
width: 100%;
height: 100%;
}
}
.uni-media-box {
@extend .uni-flex-row;
// margin-bottom: $uni-spacing-col-base;
border-radius: $uni-border-radius-lg;
overflow: hidden;
.uni-thumb {
margin: 0;
margin-left: 4px;
flex-shrink: 1;
width: 33%;
border-radius:0;
&:first-child {
margin: 0;
}
}
}
/* 内容 */
.uni-content {
@extend .uni-flex-column;
justify-content: space-between;
}
/* 列表footer */
.uni-footer {
@extend .uni-flex-row;
justify-content: space-around;
margin-top: $uni-spacing-col-lg;
}
.uni-footer-text {
font-size: $uni-font-size-sm;
color: $uni-text-color-grey;
margin-left: 5px;
}
/* 标签 */
.uni-tag {
flex-shrink: 0;
padding: 0 5px;
border: 1px $uni-border-color solid;
margin-right: $uni-spacing-row-sm;
border-radius: $uni-border-radius-base;
background: $uni-bg-color-grey;
color: $uni-text-color;
font-size: $uni-font-size-sm;
}
/* 链接 */
.uni-link {
margin-left: 10px;
color: $uni-text-color;
text-decoration: underline;
}

View File

@ -124,7 +124,52 @@
"path" : "pages/vod/video", "path" : "pages/vod/video",
"style" : "style" :
{ {
"navigationBarTitleText": "云点播", "navigationBarTitleText": "视频观看",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/exam/index",
"style" :
{
"navigationBarTitleText": "考试列表",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/exam/preview",
"style" :
{
"navigationBarTitleText": "考试须知",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/exam/main",
"style" :
{
"navigationBarTitleText": "答题中",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/exam/record",
"style" :
{
"navigationBarTitleText": "答题记录",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/exam/result",
"style" :
{
"navigationBarTitleText": "答题结束",
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
@ -147,12 +192,18 @@
"selectedIconPath": "static/common/homec.png", "selectedIconPath": "static/common/homec.png",
"text": "主页" "text": "主页"
}, },
/* { {
"pagePath": "pages/exam/index",
"iconPath": "static/common/play.png",
"selectedIconPath": "static/common/playc.png",
"text": "答题"
},
{
"pagePath": "pages/vod/video", "pagePath": "pages/vod/video",
"iconPath": "static/common/play.png", "iconPath": "static/common/play.png",
"selectedIconPath": "static/common/playc.png", "selectedIconPath": "static/common/playc.png",
"text": "点播" "text": "点播"
}, */ },
{ {
"pagePath": "pages/my/my", "pagePath": "pages/my/my",
"iconPath": "static/common/me.png", "iconPath": "static/common/me.png",

View File

@ -0,0 +1,22 @@
<template>
<view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,60 @@
<template>
<view>
<uni-list>
<!-- 垂直排列无略缩图主标题+副标题显示 -->
<uni-list-item direction="column" :key="item.id" v-for="(item, index) in examList">
<template v-slot:header>
<view class="uni-title">{{item.name}}</view>
</template>
<template v-slot:body>
<view class="uni-list-box">
<view class="uni-content">
<view class="uni-title-sub uni-ellipsis-2">开启时间: {{item.open_time}}{{item.close_time}}</view>
<view class="uni-note">考试机会: {{item.chance}}</view>
</view>
</view>
</template>
<template v-slot:footer>
<view class="uni-footer">
<u-button size="mini" type="primary" @click="attendExam(item)">我要参加</u-button>
<u-button size="mini" type="info">成绩排名</u-button>
</view>
</template>
</uni-list-item>
</uni-list>
</view>
</template>
<script>
export default {
data() {
return {
query:{
page: 1
},
examList: []
}
},
onLoad() {
this.getExamList();
},
methods: {
getExamList(){
this.$u.api.getExamList(this.query).then(res=>{
this.examList = res.data.results
})
},
attendExam(val){
console.log(val)
uni.setStorageSync('currentExam', val)
uni.navigateTo({
url:"/pages/exam/preview"
})
}
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,22 @@
<template>
<view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,76 @@
<template>
<view class='wrap'>
<view class="subTitle">
考试信息
</view>
<view class="examContent">
<view>考试名称<text>{{currentExam.name}}</text> </view>
<view>考试总分<text>{{currentExam.paper_.total_score}}</text></view>
<view v-if="currentExam.limit>0">考试时长<text>{{currentExam.limit}}</text>分钟</view>
<view v-else>考试时长<text>不限时长</text></view>
<view>题目分布单选<text>{{currentExam.paper_.danxuan_count}}</text>;多选<text>{{currentExam.paper_.duoxuan_count}}</text>;判断<text>{{currentExam.paper_.panduan_count}}</text></view>
<view>判分规则单选{{currentExam.paper_.danxuan_score}},多选{{currentExam.paper_.duoxuan_score}},多选{{currentExam.paper_.panduan_score}},错选少选均不得分</view>
</view>
<view class="subTitle">答题须知</view>
<view class="tipsArea">
<ul>
<li>1.进入答题后请不要后退或返回</li>
<li>2.可点击上一题/下一题切换</li>
<li>3.可点击答题卡复查</li>
<li>4.请合理安排时间答题,可提前交卷</li>
</ul>
</view>
<u-button type="primary" @click="start()">开始答题</u-button>
</view>
</template>
<script>
export default {
data() {
return {
currentExam:{}
}
},
onLoad() {
this.currentExam = uni.getStorageSync('currentExam')
},
methods: {
start(){
uni.reLaunch({
url:'/pages/exam/main'
})
}
}
}
</script>
<style lang="scss" scoped>
.wrap{
padding: 24rpx;
font-size: 32rpx;
}
.subTitle {
font-size: $u-font-size-title;
font-weight: bold;
color: $theme-color;
text-align: center;
margin: 40rpx auto 20rpx auto;
}
.examContent {
line-height: 50rpx;
margin-left: 80rpx;
text {
font-weight: bold;
color:$u-type-warning-dark;
}
}
.tipsArea {
padding: 0 40rpx;
margin-left: 0rpx;
margin-bottom: 30rpx;
}
ul {
margin: 0 30rpx;
line-height: 50rpx;
}
</style>

View File

@ -0,0 +1,133 @@
<template>
<view>
<uni-list>
<uni-list-item v-for="item in list" :key="item.id" @click="goDetail(item.id)" :clickable="true" link>
<!-- 自定义 header -->
<!-- <view slot="header" class="slot-box">
<view>{{item.name}}</view>
</view> -->
<!-- 自定义 body -->
<template slot="body" style="display: block;">
<view>
<text v-if="item.type=='自助模考'">模拟练习</text>
<text v-else style="font-weight: bold;color:orange">正式竞赛</text>
<text v-if="item.name.indexOf('(补)') != -1">()</text>
</view>
<view style="color:gray;font-size: 26rpx;">
<span>耗时:
<span style="color:darkblue;font-weight: bold;">{{item.took}}</span>
s</span>
-
<text>提交时间:{{item.create_time}}</text>
</view>
<view style="color:gray;font-size: 26rpx;">
<span>总分:{{item.total_score}}</span>
-
<span>得分:
<span style="color:green;font-weight: bold;">{{item.score}}</span>
</span>
</view>
</template>
<!-- 自定义 footer-->
<!-- <template slot="footer">
<image class="slot-image" src="/static/logo.png" mode="widthFix"></image>
</template> -->
</uni-list-item>
</uni-list>
<!-- <uni-card :title="item.name" :isFull="true" isShadow='true' extra="查看详情" @click="clickCard" v-for="item in list" :key="item.id">
<view>
<text>{{item.type}}</text>
</view>
<view>
<text>耗时:{{item.took}}</text>
<text>开始答题:{{item.start_time}}</text>
</view>
</uni-card> -->
<view style="color:gray;text-align: center;margin-top:20upx">{{loadingText}}</view>
</view>
</template>
<script>
export default {
data() {
return {
listQuery: {
page: 1,
page_size: 20
},
list: [],
loadingText: '加载中...'
}
},
methods: {
getList() {
var that = this
that.$u.api.getMyExamRecord(that.listQuery).then(res => {
uni.stopPullDownRefresh()
uni.setNavigationBarTitle({
title: res.data.count + '条答题记录'
})
if (that.listQuery.page == 1) {
if (res.data.results.length == 0) {
that.loadingText = '暂无答题记录'
} else {
that.loadingText = ''
that.list = res.data.results
}
} else {
that.loadingText = ''
that.list = that.list.concat(res.data.results)
}
}).catch(res => {
uni.stopPullDownRefresh()
if (res.code == 404) {
that.loadingText = '到底了'
}
})
},
goDetail(id) {
uni.showLoading({
title:"正在获取答题详情",
})
this.$u.api.getExamRecordDetail(id).then(res=>{
uni.hideLoading()
uni.setStorageSync('currentExam', res.data)
if (res.data.questions.length>0){
uni.redirectTo({
url:'/pages/exam/detail?examrecord='+id
})
}
else{
uni.showToast({
title:'获取失败',
icon:'none'
})
return
}
}).catch(e=>{
})
}
},
onLoad() {
this.listQuery.page = 1
this.getList()
},
onPullDownRefresh() {
this.listQuery.page = 1
this.getList()
},
onReachBottom() {
this.listQuery.page = this.listQuery.page + 1
this.getList()
}
}
</script>
<style lang='scss'>
page {
background-color: $u-bg-color;
}
</style>

View File

@ -0,0 +1,97 @@
<template>
<view>
<image class="examImage" :src="imageSrc" mode="aspectFit"></image>
<view class="finishText">
恭喜您完成考试
</view>
<view class="finishText">
<view><text>{{currentExam.name}}</text></view>
<!-- 练习类型{{paperRecord.paperName}} -->
<view>总分<text>{{currentExam.total_score}}</text></view>
<!-- <view>答对<text>{{paperRecord.rightQueNum}}</text></view> -->
<view>得分<text>{{currentExam.score}}</text> </view>
</view>
<view class="btnArea">
<u-button class="btnClass" type="primary" :ripple="true" shape="circle" @click="goDetail">查看答卷</u-button>
<u-button class="btnClass" :ripple="true" shape="circle" @click="backToHome">返回首页</u-button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
imageSrc: '/static/exam/result.png',
currentExam:{}
}
},
methods: {
goDetail(){
uni.showLoading({
title:"正在获取答题详情",
})
this.$u.api.getExamRecordDetail(this.currentExam.id).then(res=>{
uni.hideLoading()
uni.setStorageSync('currentExam', res.data)
uni.redirectTo({
url:'/pages/exam/detail?examrecord='+this.currentExam.id
})
}).catch(e=>{
})
},
backToHome(){
uni.reLaunch({
url:'/pages/index/index'
})
}
},
onLoad(options){
this.currentExam = uni.getStorageSync('currentExam')
},
}
</script>
<style lang="scss" scoped>
.examImage {
width: 100%;
display: flex;
justify-content: center;
// background-color: #000000;
margin-top: 100rpx;
height: 300rpx;
}
.finishText {
// margin: 100rpx 200rpx;
padding: 50rpx;
letter-spacing: 0.2em;
font-size: 32rpx;
display: flex;
flex-direction: column;
align-items: center;
text {
color: $theme-color;
font-weight: bold;
}
}
.btnArea {
display: flex;
margin-top: 50rpx;
justify-content: center;
align-items: center;
.btnClass {
width: 300rpx;
}
}
.infoArea {
display: flex;
flex-direction: column;
justify-content: center;
}
</style>

View File

@ -31,7 +31,7 @@
</video> </video>
<view style="color:darkblue;margin-left:4upx"> <view style="color:darkblue;margin-left:4upx">
<text>{{video.name}}</text> <text>{{video.name}}</text>
<text style="float:right;color:gray;margin-right: 8upx;">{{video.viewsp}}人观看</text> <text style="float:right;color:gray;margin-right: 8upx;">{{video.views}}次播放</text>
</view> </view>
</view> </view>
</view> </view>

View File

@ -2,6 +2,7 @@
// uni.scss中引入的样式会同时混入到全局样式文件和单独每一个页面的样式中造成微信程序包太大 // uni.scss中引入的样式会同时混入到全局样式文件和单独每一个页面的样式中造成微信程序包太大
// 故uni.scss只建议放scss变量名相关样式其他的样式可以通过main.js或者App.vue引入 // 故uni.scss只建议放scss变量名相关样式其他的样式可以通过main.js或者App.vue引入
$theme-color:#0080d1;
$u-main-color: #303133; $u-main-color: #303133;
$u-content-color: #606266; $u-content-color: #606266;
$u-tips-color: #909399; $u-tips-color: #909399;
@ -36,3 +37,9 @@ $u-type-info-light: #f4f4f5;
$u-form-item-height: 70rpx; $u-form-item-height: 70rpx;
$u-form-item-border-color: #dcdfe6; $u-form-item-border-color: #dcdfe6;
/* 文字尺寸 */
$u-font-size-sm:24rpx;
$u-font-size-lg:32rpx;
$u-font-size-base:28rpx;
$u-font-size-title:36rpx;