123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- <template>
- <scoring-panel-container
- v-model="modalVisible"
- title="键盘给分"
- modal-class="no-mask"
- :width="'388px'"
- :modal="false"
- :can-resize="true"
- class="keybord-dialog"
- @close="onToggleClick"
- >
- <div class="scoring-panel-box" :class="getClass('modal-box')">
- <template v-for="(question, index) in questionList" :key="question.mainNumber + question.subNumber">
- <div v-if="dialogMode" class="flex dialog-name items-center">
- <p>{{ question.mainNumber }} - {{ question.subNumber }}</p>
- <p class="main-title">{{ question.mainTitle }}</p>
- </div>
- <scoring-panel-item
- v-model:score="scoreValues[index]"
- v-model:scoreValidFail="scoreValidFail[index]"
- :active="activeIndex === index"
- :modal="dialogMode"
- :toggle-modal="props.toggleModal && index === 0"
- :question="question"
- @blur="() => onBlur(index)"
- @enter="() => onEnter(index)"
- @focused="() => onFocused(index)"
- @toggle-click="onToggleClick"
- ></scoring-panel-item>
- </template>
- </div>
- <template #footer>
- <el-button type="primary" class="full-w" :disabled="!allowSubmit" @click="onEnter(0)">确定</el-button>
- </template>
- </scoring-panel-container>
- </template>
- <script setup lang="ts" name="ScoringPanel">
- import { watch, withDefaults, ref, defineComponent, useSlots, computed, nextTick, onMounted } from 'vue'
- import { ElButton } from 'element-plus'
- import BaseDialog from '@/components/element/BaseDialog.vue'
- import ScoringPanelItem from './ScoringPanelItem.vue'
- import useVModel from '@/hooks/useVModel'
- import useVW from '@/hooks/useVW'
- import useFetch from '@/hooks/useFetch'
- import { sessionStorage } from '@/plugins/storage'
- const props = withDefaults(
- defineProps<{
- /** 弹窗模式? */
- modal?: boolean
- /** 是否可以切换显示模式 */
- toggleModal?: boolean
- /** 显示隐藏 */
- visible?: boolean
- /** 分值 */
- score: (number | string)[]
- mainNumber?: number | null
- id?: number | null
- autoVisible?: boolean | undefined
- }>(),
- { modal: false, toggleModal: true, score: () => [], mainNumber: null, id: null, autoVisible: true }
- )
- const emits = defineEmits(['submit', 'update:score', 'update:visible', 'update:modal'])
- const dialogModeBeforeSubmit = ref<boolean>(false)
- const dialogMode = ref<boolean>(props.modal)
- const LessRenderComponent = defineComponent({
- name: 'LessRender',
- inheritAttrs: false,
- props: {
- modelValue: {
- type: Boolean,
- default: false,
- },
- },
- render() {
- return this.modelValue ? useSlots()?.default?.() : null
- },
- })
- const ScoringPanelContainer = computed(() => {
- return dialogMode.value ? BaseDialog : LessRenderComponent
- })
- const modalVisible = useVModel(props, 'visible')
- const scoreValues = useVModel(props, 'score')
- const activeIndex = ref<number | null>(0)
- const scoreValidFail = ref<boolean[]>([])
- watch(modalVisible, (val) => {
- activeIndex.value = 0
- let sessionKeyboardShowType = sessionStorage.get('dialogModeBeforeSubmit')
- dialogMode.value =
- typeof sessionKeyboardShowType === 'boolean' ? sessionKeyboardShowType : dialogModeBeforeSubmit.value
- })
- onMounted(() => {
- let sessionKeyboardShowType = sessionStorage.get('dialogModeBeforeSubmit')
- dialogMode.value =
- typeof sessionKeyboardShowType === 'boolean' ? sessionKeyboardShowType : dialogModeBeforeSubmit.value
- })
- const { fetch: getQuestionStruct, reset: resetQuestionStruct, result: questionStruct } = useFetch('getQuestionStruct')
- watch([() => props.id, () => props.autoVisible], () => {
- if (props.autoVisible) {
- modalVisible.value = !!props.id
- }
- scoreValues.value = []
- })
- watch(
- () => props.mainNumber,
- () => {
- /** reset scores */
- scoreValues.value = []
- if (props.mainNumber) {
- resetQuestionStruct()
- getQuestionStruct({ mainNumber: props.mainNumber })
- }
- },
- { immediate: true }
- )
- const questionList = computed(() => {
- if (!questionStruct.value) {
- return []
- }
- const { mainNumber, mainTitle, questionList = [] } = questionStruct.value
- return questionList.map((q) => ({ ...q, mainNumber, mainTitle }))
- })
- const allowSubmit = computed(() => {
- let filterArr = scoreValues.value.filter((score) => score != undefined)
- // return scoreValues.value?.length === questionList.value?.length
- return filterArr.length === questionList.value?.length
- })
- const getClass = (val: string, callback?: string) => {
- return dialogMode.value ? val : callback || ''
- }
- const onSubmit = () => {
- if (!scoreValidFail.value.some((valid) => valid)) {
- emits('submit', questionStruct.value)
- }
- }
- const onEnter = (index: number) => {
- dialogModeBeforeSubmit.value = dialogMode.value
- sessionStorage.set('dialogModeBeforeSubmit', dialogModeBeforeSubmit.value)
- nextTick(() => {
- // console.log('index:', index)
- // console.log('scoreValues.value.length:', scoreValues.value.length)
- // console.log('questionList.value?.length:', questionList.value?.length)
- let filterArr = scoreValues.value.filter((score) => score != undefined)
- // if (scoreValues.value.length >= questionList.value?.length) {
- if (filterArr.length >= questionList.value?.length) {
- const nullScoreIndex = scoreValues.value?.findIndex((v) => !`${v}`)
- const validFailIndexIndex = scoreValidFail.value?.findIndex((v) => !!v)
- if (nullScoreIndex >= 0) {
- activeIndex.value = nullScoreIndex
- } else if (validFailIndexIndex >= 0) {
- activeIndex.value = validFailIndexIndex
- } else {
- onSubmit()
- }
- } else {
- activeIndex.value = index + 1
- }
- })
- }
- const onFocused = (index: number) => {
- activeIndex.value = index
- }
- const onBlur = (index: number) => {
- if (activeIndex.value === index) {
- activeIndex.value = null
- }
- }
- const onToggleClick = () => {
- if (modalVisible.value) {
- dialogModeBeforeSubmit.value = dialogMode.value ? false : true
- sessionStorage.set('dialogModeBeforeSubmit', dialogModeBeforeSubmit.value)
- }
- dialogMode.value = props.toggleModal ? !dialogMode.value : dialogMode.value
- if (!props.toggleModal) {
- modalVisible.value = false
- }
- }
- </script>
- <style scoped lang="scss">
- .modal-box {
- max-height: 50vh;
- min-height: 8vw;
- .dialog-name {
- color: $color--primary;
- font-weight: bold;
- padding-left: 10px;
- }
- }
- </style>
|