| @ -1,187 +1,185 @@ | |||||
| <template> | <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.answer === option.id ? 'is-correct' : '', | ||||
| props.data.value === option.id && props.data.answer !== option.id ? 'is-error' : '', | 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> | </template> | ||||
| <script setup> | <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> | </script> | ||||
| <style lang="scss" scoped> | <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> | </style> | ||||