| @ -1,187 +1,185 @@ | |||
| <template> | |||
| <view class="mt32 question__view" :class="[props.mode]"> | |||
| <view class="size-28 mb20 question"> | |||
| {{ props.data.title }} | |||
| <!-- {{ `${props.index + 1}、${props.data.title}` }} --> | |||
| </view> | |||
| <template v-if="props.mode === 'edit'"> | |||
| <template v-if="props.data.options?.length"> | |||
| <view class="size-28 option" | |||
| v-for="(option, oIdx) in props.data.options" | |||
| :key="`${props.index}-option-${oIdx}`" | |||
| :class="[value === option.id ? 'is-selected' : '']" | |||
| @click="onChange(option.id)" | |||
| > | |||
| {{ option.title }} | |||
| </view> | |||
| </template> | |||
| <template v-else> | |||
| <view class="textarea"> | |||
| <textarea | |||
| v-model="value" | |||
| placeholder="请输入您的答案,不得低于700个字" | |||
| :rows="10" | |||
| @blur="onChange($event.detail.value)" | |||
| ></textarea> | |||
| </view> | |||
| </template> | |||
| </template> | |||
| <template v-else> | |||
| <template v-if="props.data.options?.length"> | |||
| <view class="size-28 option" | |||
| v-for="(option, oIdx) in props.data.options" | |||
| :key="`${props.index}-option-${oIdx}`" | |||
| :class="[ | |||
| <view class="mt32 question__view" :class="[props.mode]"> | |||
| <view class="size-28 mb20 question"> | |||
| {{ props.data.title }} | |||
| <!-- {{ `${props.index + 1}、${props.data.title}` }} --> | |||
| </view> | |||
| <template v-if="props.mode === 'edit'"> | |||
| <template v-if="props.data.options?.length"> | |||
| <view class="size-28 option" v-for="(option, oIdx) in props.data.options" | |||
| :key="`${props.index}-option-${oIdx}`" :class="[value === option.id ? 'is-selected' : '']" | |||
| @click="onChange(option.id)"> | |||
| {{ option.title }} | |||
| </view> | |||
| </template> | |||
| <template v-else> | |||
| <view class="textarea"> | |||
| <textarea v-model="value" placeholder="请输入您的答案,不得低于700个字" :rows="10" | |||
| @blur="onChange($event.detail.value)"></textarea> | |||
| </view> | |||
| </template> | |||
| </template> | |||
| <template v-else> | |||
| <template v-if="props.data.options?.length"> | |||
| <view class="size-28 option" v-for="(option, oIdx) in props.data.options" | |||
| :key="`${props.index}-option-${oIdx}`" :class="[ | |||
| props.data.answer === option.id ? 'is-correct' : '', | |||
| props.data.value === option.id && props.data.answer !== option.id ? 'is-error' : '', | |||
| ]" | |||
| > | |||
| {{ option.title }} | |||
| <view class="icon icon-correct"> | |||
| <up-icon name="checkmark" color="#05C160" size="35rpx"></up-icon> | |||
| </view> | |||
| <view class="icon icon-error"> | |||
| <up-icon name="close" color="#FF2A2A" size="35rpx"></up-icon> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <template v-else> | |||
| <view class="textarea"> | |||
| <view>{{ props.data.value }}</view> | |||
| <view class="highlight">{{ props.data.answer }}</view> | |||
| </view> | |||
| </template> | |||
| </template> | |||
| </view> | |||
| ]"> | |||
| {{ option.title }} | |||
| <view class="icon icon-correct"> | |||
| <up-icon name="checkmark" color="#05C160" size="35rpx"></up-icon> | |||
| </view> | |||
| <view class="icon icon-error"> | |||
| <up-icon name="close" color="#FF2A2A" size="35rpx"></up-icon> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <template v-else> | |||
| <view class="textarea"> | |||
| <view>{{ props.data.value }}</view> | |||
| <view class="highlight">{{ props.data.answer }}</view> | |||
| </view> | |||
| </template> | |||
| </template> | |||
| </view> | |||
| </template> | |||
| <script setup> | |||
| import { computed, watch } from 'vue' | |||
| import { addBaseAnswer, addTrainAnswer } from '@/api/examination' | |||
| import { store } from '@/store' | |||
| const userId = computed(() => { | |||
| return store.state.user.userInfo.userId | |||
| }) | |||
| const props = defineProps({ | |||
| index: { | |||
| type: Number, | |||
| default: null, | |||
| }, | |||
| data: { | |||
| type: Object, | |||
| default() { | |||
| return {} | |||
| } | |||
| }, | |||
| modelValue: { | |||
| type: String | Number, | |||
| default: null, | |||
| }, | |||
| mode: { | |||
| type: String, | |||
| default: 'edit', // edit | display | |||
| }, | |||
| type: { | |||
| type: String, | |||
| default: null, // '基本' | '培训' | |||
| } | |||
| }) | |||
| const emit = defineEmits(['update:modelValue']) | |||
| const value = computed({ | |||
| set(val) { | |||
| emit('update:modelValue', val) | |||
| }, | |||
| get() { | |||
| return props.modelValue | |||
| } | |||
| }) | |||
| const onChange = (val) => { | |||
| value.value = val | |||
| const data = { | |||
| userId: userId.value, | |||
| questionId: props.data.id, | |||
| } | |||
| if (props.type === '基本') { | |||
| data.answerId = val | |||
| addBaseAnswer(data) | |||
| } else if (props.type === '培训') { | |||
| data.answer = val | |||
| addTrainAnswer(data) | |||
| } | |||
| } | |||
| import { | |||
| computed, | |||
| watch | |||
| } from 'vue' | |||
| import { | |||
| addBaseAnswer, | |||
| addTrainAnswer | |||
| } from '@/api/examination' | |||
| import { | |||
| store | |||
| } from '@/store' | |||
| const userId = computed(() => { | |||
| return store.state.user.userInfo.userId | |||
| }) | |||
| const props = defineProps({ | |||
| index: { | |||
| type: Number, | |||
| default: null, | |||
| }, | |||
| data: { | |||
| type: Object, | |||
| default () { | |||
| return {} | |||
| } | |||
| }, | |||
| modelValue: { | |||
| type: String | Number, | |||
| default: null, | |||
| }, | |||
| mode: { | |||
| type: String, | |||
| default: 'edit', // edit | display | |||
| }, | |||
| type: { | |||
| type: String, | |||
| default: null, // '基本' | '培训' | |||
| } | |||
| }) | |||
| const emit = defineEmits(['update:modelValue']) | |||
| const value = computed({ | |||
| set(val) { | |||
| emit('update:modelValue', val) | |||
| }, | |||
| get() { | |||
| return props.modelValue | |||
| } | |||
| }) | |||
| const onChange = (val) => { | |||
| value.value = val | |||
| const data = { | |||
| userId: userId.value, | |||
| questionId: props.data.id, | |||
| } | |||
| if (props.type === '基本') { | |||
| data.answerId = val | |||
| addBaseAnswer(data) | |||
| } else if (props.type === '培训') { | |||
| data.answer = val | |||
| addTrainAnswer(data) | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .question { | |||
| color: #000000; | |||
| } | |||
| .option { | |||
| background-color: #F3F3F3; | |||
| color: #707070; | |||
| line-height: 37rpx; | |||
| padding: 23rpx; | |||
| border-radius: 28rpx; | |||
| position: relative; | |||
| & + & { | |||
| margin-top: 20rpx; | |||
| } | |||
| .icon { | |||
| position: absolute; | |||
| right: 45rpx; | |||
| bottom: 23rpx; | |||
| display: none; | |||
| } | |||
| } | |||
| .textarea { | |||
| background-color: #F3F3F3; | |||
| padding: 23rpx; | |||
| border-radius: 16rpx; | |||
| .highlight { | |||
| color: #FF2A2A; | |||
| font-size: 28rpx; | |||
| } | |||
| } | |||
| .question__view.edit { | |||
| .option.is-selected { | |||
| background-color: rgba($color: #FFBF60, $alpha: 0.22); | |||
| color: #FFBF60; | |||
| } | |||
| } | |||
| .question__view.display { | |||
| .option { | |||
| &.is-correct { | |||
| background-color: rgba($color: #05C160, $alpha: 0.08); | |||
| color: #05C160; | |||
| .icon-correct { | |||
| display: block; | |||
| } | |||
| } | |||
| &.is-error { | |||
| background-color: rgba($color: #FFEBCE, $alpha: 0.36); | |||
| color: #FF2A2A; | |||
| .icon-error { | |||
| display: block; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .question { | |||
| color: #000000; | |||
| } | |||
| .option { | |||
| background-color: #F3F3F3; | |||
| color: #707070; | |||
| line-height: 37rpx; | |||
| padding: 23rpx; | |||
| border-radius: 28rpx; | |||
| position: relative; | |||
| &+& { | |||
| margin-top: 20rpx; | |||
| } | |||
| .icon { | |||
| position: absolute; | |||
| right: 45rpx; | |||
| bottom: 23rpx; | |||
| display: none; | |||
| } | |||
| } | |||
| .textarea { | |||
| background-color: #F3F3F3; | |||
| padding: 23rpx; | |||
| border-radius: 16rpx; | |||
| .highlight { | |||
| color: #FF2A2A; | |||
| font-size: 28rpx; | |||
| } | |||
| } | |||
| .question__view.edit { | |||
| .option.is-selected { | |||
| background-color: rgba($color: #FFBF60, $alpha: 0.22); | |||
| color: #FFBF60; | |||
| } | |||
| } | |||
| .question__view.display { | |||
| .option { | |||
| &.is-correct { | |||
| background-color: rgba($color: #05C160, $alpha: 0.08); | |||
| color: #05C160; | |||
| .icon-correct { | |||
| display: block; | |||
| } | |||
| } | |||
| &.is-error { | |||
| background-color: rgba($color: #FFEBCE, $alpha: 0.36); | |||
| color: #FF2A2A; | |||
| .icon-error { | |||
| display: block; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| </style> | |||