风险测评小程序前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

428 lines
9.7 KiB

<template>
<view class="page__view">
<navbar title="答题测评" leftClick @leftClick="$utils.navigateBack" bgColor="transparent" />
<!-- 答题完成 -->
<template v-if="total && current === total">
<view class="flex main is-finish">
<view class="card">
<image class="card-bg" src="@/pages_order/static/test/bg-test-finsih.png" mode="widthFix"></image>
<view class="flex flex-column card-content">
<view class="text">恭喜你~</view>
<view class="text">您已完成所有测评题目!</view>
<button class="btn" @click="onCreateReport">生成报告</button>
</view>
</view>
</view>
</template>
<!-- 答题中 -->
<template v-else-if="currentQuestion">
<view class="bar">
<view class="flex info">
<view>答题进度</view>
<view>
<text class="highlight">{{ current + 1 }}</text>
<text>{{ `/${total}` }}</text>
</view>
</view>
<view class="progress">
<view class="progress-bar" :style="{ width: `${progress}%` }"></view>
</view>
</view>
<view class="main">
<view class="card">
<view class="card-header">
<view class="flex tips">
<image class="icon" src="@/pages_order/static/test/icon-warning.png" mode="widthFix"></image>
<view>请根据真实情况谨慎作答,点击下一题提交答案无法更改</view>
</view>
<view class="question">{{ currentQuestion.question }}</view>
</view>
<view class="card-content">
<view class="select">
<view
v-for="item in currentQuestion.options"
:key="item.id"
:class="['select-option', item.id === value ? 'is-active' : '']"
@click="onSelect(item.id)"
>
{{ item.content }}
</view>
</view>
</view>
</view>
</view>
<view class="bottom">
<button v-if="isLast" class="btn" @click="finish">提交</button>
<button v-else class="btn" @click="next">下一题</button>
</view>
</template>
</view>
</template>
<script>
export default {
data() {
return {
current: null,
tabs: [],
value: null,
answers: [],
batchNo: null,
questionsList: [],
total: 0,
}
},
computed: {
preIdx() {
let index = this.tabs.findIndex(index => index === this.current)
return index - 1
},
progress() {
return 100 * (this.current + 1) / this.total
},
isLast() {
return this.progress === 100
},
currentQuestion() {
return this.questionsList[this.current]
},
},
onLoad(arg) {
const { ids, examId, current } = arg
this.current = parseInt(current || 0)
this.fetchQuestionList(ids, examId)
this.value = this.answers[this.current]
console.log('currentQuestion', this.currentQuestion)
},
methods: {
async fetchQuestionList(categories, examId) {
let result
if (examId) {
result = await this.$fetch('queryExamById', { examId })
} else {
result = await this.$fetch('queryQuestionList', { categories })
}
const { batchNo, pageList } = result
this.batchNo = batchNo
this.questionsList = pageList.map((item, index) => {
const { id, question, answerList } = item
return {
id,
// question: `${index + 1}、${question}`,
question,
options: answerList.map((option, oIdx) => {
return {
id: option.id,
// content: `${String.fromCharCode(oIdx+65)}、${option.answer}`
content: `${option.answerNo}、${option.answer}`
}
}),
}
})
this.total = this.questionsList.length
this.answers = this.questionsList.map(() => null)
console.log('questionsList', this.questionsList)
console.log('answers', this.answers)
},
async fetchAnswer() {
try {
const { id: questionId } = this.currentQuestion
console.log('currentQuestion', this.currentQuestion)
console.log('value', this.value)
if (!this.value) {
console.log('未答题')
uni.showToast({
title: '请答题',
icon:'none'
})
return false
}
let params = {
batchNo: this.batchNo,
questionId,
answerId: this.value,
}
await this.$fetch('updateAnswer', params)
this.answers[this.current] = this.value
return true
} catch (err) {
console.log('fetchAnswer', err)
return false
}
},
async fetchFinish() {
// todo: delete
// todo
// await this.$fetch('submitPaper', { id: this.paperInfo.reportId })
this.current = this.total
console.log('fetchFinish', this.current, this.currentQuestion)
// todo
// uni.reLaunch({
// url: '/pages/index/report'
// })
},
async next() {
let succ = await this.fetchAnswer()
if (!succ) {
return
}
this.current += 1
this.value = this.answers[this.current]
},
async finish() {
let succ = await this.fetchAnswer()
if (!succ) {
return
}
this.fetchFinish()
},
async onSelect(id) {
this.value = id
},
async onSelectMulitple(id) {
this.value = this.value.includes(id) ? this.value.filter(item => item !== id) : this.value.concat(id)
},
onCreateReport() {
uni.redirectTo({
url: `/pages_order/report/pay?batchNo=${this.batchNo}`
})
},
},
}
</script>
<style scoped lang="scss">
.page__view {
width: 100vw;
min-height: 100vh;
background: linear-gradient(164deg, #014FA2, #014FA2, #2E8AED);
position: relative;
}
.bar {
margin-top: 42rpx;
width: 100%;
padding: 0 47rpx;
box-sizing: border-box;
.info {
justify-content: flex-start;
column-gap: 13rpx;
font-size: 28rpx;
color: #A1D6FF;
.highlight {
color: #FFFFFF;
margin-right: 8rpx;
}
}
.progress {
margin-top: 20rpx;
width: 100%;
height: 16rpx;
background: rgba($color: #FFFFFF, $alpha: 0.35);
border-radius: 8rpx;
&-bar {
height: 100%;
background: #FFFFFF;
border-radius: 8rpx;
}
}
}
.main {
width: 100%;
padding: 73rpx 33rpx;
box-sizing: border-box;
}
.card {
position: relative;
width: 100%;
min-height: 876rpx;
padding: 27rpx 0;
box-sizing: border-box;
background: #FFFFFF;
border-radius: 16rpx;
&:after {
content: ' ';
position: absolute;
bottom: 0;
left: 50%;
transform: translate(-50%, 100%);
width: calc(100% - 20rpx * 2);
height: 28rpx;
background: rgba($color: #E9EFF2, $alpha: 0.29);
border-bottom-left-radius: 16rpx;
border-bottom-right-radius: 16rpx;
}
&-header {
padding: 0 33rpx;
.tips {
column-gap: 3rpx;
padding: 12rpx 5rpx;
font-size: 22rpx;
color: #DB5742;
border: 3rpx solid #DB5742;
border-radius: 7rpx;
margin-bottom: 26rpx;
.icon {
width: 31rpx;
height: auto;
}
}
}
&-content {
padding: 0 24rpx;
}
}
.question {
font-family: PingFang SC;
font-weight: 400;
font-size: 28rpx;
line-height: 50rpx;
color: #000000;
margin-bottom: 64rpx;
}
.select {
&-option {
margin-top: 44rpx;
padding: 22rpx 28rpx;
line-height: 1.3;
font-size: 28rpx;
color: #707070;
background: #F3F3F3;
border-radius: 28rpx;
&.is-active {
color: #014FA2;
background: rgba($color: #014FA2, $alpha: 0.22);
}
}
}
.bottom {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
padding: 17rpx 72rpx;
padding-bottom: calc(env(safe-area-inset-bottom) + 17rpx);
background: #FFFFFF;
box-sizing: border-box;
.btn {
width: 100%;
padding: 26rpx 0;
font-size: 30rpx;
line-height: 1.4;
color: #FFFFFF;
background: #014FA2;
border-radius: 42rpx;
}
}
.desc {
margin-top: 220rpx;
font-family: PingFang SC;
font-weight: 400;
line-height: 1.4;
font-size: 26rpx;
color: #989898;
}
.main.is-finish {
height: calc(100vh - (var(--status-bar-height) + 120rpx));
padding: 0 33rpx;
padding-bottom: calc(var(--status-bar-height) + 120rpx);
.card {
min-height: 745rpx;
padding: 0;
background: transparent;
&-bg {
width: 100%;
height: auto;
}
&-content {
position: absolute;
top: 0;
left: 0;
justify-content: flex-end;
width: 100%;
height: 100%;
padding: 69rpx 94rpx;
box-sizing: border-box;
.text {
font-size: 32rpx;
font-weight: 600;
color: #000000;
}
.text + .text {
margin-top: 45rpx;
}
.btn {
margin-top: 139rpx;
padding: 29rpx 183rpx;
box-sizing: border-box;
line-height: 1.4;
white-space: nowrap;
color: #FFFFFF;
background: #014FA2;
border-radius: 50rpx;
}
}
}
}
</style>