volunteer-4/src/pages-sub/evaluation/assessmentPage.vue

348 lines
8.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<route lang="json5" type="page">
{
style: {
navigationStyle: 'custom',
transparentTitle: 'always',
navigationBarTitleText: '',
},
}
</route>
<template>
<view class="flex flex-col h-screen relative">
<Navbar
safeAreaInsetTop
:bordered="false"
leftArrow
@clickLeft="handleBack"
bg-color="transparent"
>
<template #title>
<text class="text-[#1F2329] text-[36rpx] font-medium text-[#fff]">{{ pageName }}</text>
</template>
</Navbar>
<view class="h-full w-full custom-bg absolute top-0 left-0 -z-1"></view>
<view class="question-container flex-1 overflow-hidden mt-[30rpx] flex">
<view class="flex-1 h-0 relative">
<view
v-for="(question, index) in questions"
:key="index"
:class="`h-full overflow-y-auto card-container ${currentIndex === index ? 'current-card' : ''}`"
>
<view class="px-[30rpx] py-[40rpx] flex flex-col card-content">
<text class="mb-[30rpx] text-[34rpx] font-semibold">
{{ index + 1 }}、{{ question.title }}
</text>
<CheckboxGroup
v-model="checkedList"
checked-color="#1580FF"
@change="handleCheckChange"
:max="questionType === 0 ? 1 : 0"
>
<Checkbox
v-for="item in question.answer"
:key="item.key"
:name="item.key"
cell
shape="button"
class="custom-checkbox"
default-style="width: 100%;height: 80rpx;background-color: #f6f7f8;border-radius: 8rpx;display: flex;align-items: center;justify-content: center;font-size: 28rpx;font-weight: 400;color: #303030;border: 2rpx solid #f6f7f8;"
>
{{ item.name }}
</Checkbox>
</CheckboxGroup>
</view>
</view>
</view>
<view class="mt-[86rpx] px-[30rpx]">
<button class="next-question" :disabled="disableBtn" @click="handleNextQuestion">
{{ currentIndex === questions.length - 1 ? '提交' : '下一题' }}
({{ currentIndex + 1 }}/{{ questions.length }})
</button>
</view>
</view>
</view>
<MessageBox v-model:show="show" title="" :defaultPadding="false" defaultWidth="85%">
<template>
<view class="custom-background">
<view class="px-[32rpx] pt-[48rpx]">
<text class="text-[#000] text-[48rpx] font-semibold">{{ questionName }}</text>
<view
class="bg-[rgba(21,128,255,0.1)] flex items-center gap-[10rpx] text-[24rpx] text-[#444] px-[24rpx] py-[6rpx] w-max rounded-[10rpx] mt-[10rpx]"
>
<view class="i-carbon-time-filled text-[#1580FF] w-[24rpx] h-[24rpx]"></view>
<view>{{ useTime }}</view>
</view>
<view class="text-[30rpx] my-[40rpx] text-[#333] text-[28rpx]">
{{ quesApplication }}
</view>
</view>
<view
class="text-center py-[26rpx] text-[#1580FF] text-[36rpx] font-medium start-border"
@click="show = false"
>
开始答题
</view>
</view>
</template>
</MessageBox>
</template>
<script setup lang="ts">
import Navbar from '@/pages-sub/components/navbar/Navbar.vue'
import MessageBox from '../components/messageBox/MessageBox.vue'
import {
getAssessmentQuestions,
getBusScaleDescription,
saveBusScaleAnswer,
} from '@/service/index/api'
import Checkbox from '@/pages-sub/components/check-group/Checkbox.vue'
import CheckboxGroup from '@/pages-sub/components/check-group/CheckboxGroup.vue'
import { useUserStore } from '@/store/user'
import { useRouterDetail } from './useRouterDetail'
const userStore = useUserStore()
const pageName = ref('')
const pageId = ref(-1)
const show = ref(true)
const handleBack = () => {
uni.navigateBack()
}
const checkedList = ref([])
const answerMap = new Map()
const disableBtn = ref(true)
const handleCheckChange = (value: any[]) => {
if (value.length === 0) {
disableBtn.value = true
return
} else {
disableBtn.value = false
}
if (questionType.value === 0 && value.length > 0) {
// 单选题就点完跳下一题
const timer = setTimeout(() => {
handleNextQuestion()
clearTimeout(timer)
}, 250)
}
}
const calcScore = () => {
let _type = questions.value[currentIndex.value].type
let _name = questions.value[currentIndex.value].answer[0].tag
let _options = questions.value[currentIndex.value].answer.filter((answer) => {
return checkedList.value.includes(answer.key)
})
if (answerMap.has(_type)) {
let val = answerMap.get(_type)
val.value += _options.reduce((count, cur) => (count = count + Number(cur.value)), 0)
answerMap.set(_type, val)
} else {
answerMap.set(_type, {
name: _name,
value: _options.reduce((count, cur) => (count = count + Number(cur.value)), 0),
})
}
}
// 当前显示的卡片索引
const currentIndex = ref(0)
const questions = ref([])
const questionType = ref(-1)
const questionName = ref('')
const useTime = ref('')
const quesApplication = ref('')
const isLoading = ref(false)
onLoad((options) => {
pageName.value = options.name
pageId.value = options.id
getAssessmentQuestions({ ScaleId: pageId.value }).then((res) => {
if (res.code === 200) {
let result = res.result as {
name: string
description: string
go: number
questionsType: number
scaleQuestions: any[]
}
questions.value = result.scaleQuestions
questionType.value = result.questionsType
}
})
getBusScaleDescription({ ScaleId: pageId.value }).then((res) => {
if (res.code === 200) {
let result = (
res.result as {
busScaleDescriptions: any[]
}
).busScaleDescriptions[0]
questionName.value = result.title
quesApplication.value = result.application
useTime.value = result.usesTime
}
})
})
const handleNextQuestion = () => {
if (disableBtn.value) return
disableBtn.value = true
calcScore()
checkedList.value = []
if (currentIndex.value === questions.value.length - 1) {
handleSubmit()
} else {
currentIndex.value++
}
}
const handleSubmit = () => {
if (isLoading.value) {
return
}
isLoading.value = true
let params = {
customId: userStore.userInfo.estimatedAchievement.wxId,
scaleId: pageId.value,
inputs: [],
}
let _inputs = []
answerMap.forEach((value, key) => {
_inputs.push({ type: key, name: value.name, value: value.value })
})
params.inputs = _inputs
saveBusScaleAnswer(params).then((res) => {
isLoading.value = false
let _result = res.result as {
reportId: string
type: number
}
if (res.code === 200) {
// uni.navigateBack()
useRouterDetail({ reportsId: _result.reportId, type: _result.type })
} else {
uni.showToast({
title: res.message,
icon: 'none',
})
}
})
}
</script>
<style scoped lang="scss">
.custom-bg {
background: linear-gradient(184deg, #0d79fc 0%, #2186fc 56%, #b3ebfc 100%);
}
.custom-background {
background: linear-gradient(180deg, #d8e7fc 0%, rgba(255, 255, 255, 0) 20%);
border-radius: 24rpx;
}
:deep(.icon-class) {
color: #fff !important;
}
.start-border {
border-top: 1rpx solid #dedede;
}
.next-question {
background: #1580ff;
border-radius: 16rpx;
height: 88rpx;
line-height: 1;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
:deep(.custom-checkbox) {
//
.checkbox {
width: 100%;
height: 80rpx;
background-color: #f6f7f8;
border-radius: 8rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
font-weight: 400;
color: #303030;
border: 2rpx solid #f6f7f8;
}
.checkbox__icon {
display: none;
}
}
:deep(.checkbox-group) {
display: grid !important;
gap: 16rpx;
// padding: 32rpx 16rpx 16rpx;
}
:deep(.checkbox-active) {
background: rgba(21, 128, 255, 0.05) !important;
border: 2rpx solid #1580ff !important;
border: 2rpx solid #1580ff;
.checkbox__label {
color: #2a82e4 !important;
}
}
.question-container {
position: relative;
display: flex;
flex-direction: column;
padding-bottom: calc(20rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(env(safe-area-inset-bottom) + 20rpx);
// safe-area-inset-bottom 0 padding-bottom 20rpx
@if env(safe-area-inset-bottom) == 0 {
padding-bottom: 20rpx;
}
}
.card-container {
background: rgb(140, 199, 245);
width: calc(100% - 60rpx);
border-radius: 20rpx;
position: absolute;
transform: translate3d(100vw, 0, 0);
margin: 0 30rpx;
overflow-y: auto;
}
.current-card {
background: #fff;
z-index: 1;
transform: translate3d(0, 0, 0);
transition: all 0.3s ease;
}
wx-button[disabled]:not([type]) {
background-color: rgba(255, 255, 255, 0.4);
color: #fff;
}
</style>