Browse Source

feat: 调试

zhangjie 4 days ago
parent
commit
7b210b1957

+ 2 - 2
src/api/api-types/question.d.ts

@@ -66,7 +66,7 @@ export namespace Question {
     { mainNumber: number | string; mainTitle: string; questionList: SubQuestionStruct[] }
   >
 
-  export interface MarkLevelSpeedLimitItem {
+  export interface MarkDelayItem {
     startScore: number | undefined
     endScore: number | undefined
     minMarkTime: number | undefined
@@ -109,7 +109,7 @@ export namespace Question {
     relationMainNumber?: any
     markSpeedLimit?: any
     // 分数段评卷时间
-    markLevelSpeedLimitList?: MarkLevelSpeedLimitItem[]
+    markDelay?: MarkDelayItem[]
   }
 
   /** 新增大题 */

+ 41 - 7
src/components/shared/ScoringPanel.vue

@@ -38,13 +38,15 @@
       </template>
     </div>
     <template #footer>
-      <el-button type="primary" class="full-w" :disabled="!allowSubmit" @click="onEnter(0)">确定</el-button>
+      <el-button type="primary" class="full-w" :disabled="buttonDisabled" @click="onEnter(0)">{{
+        buttonText
+      }}</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 { watch, withDefaults, ref, defineComponent, useSlots, computed, nextTick, onMounted, onUnmounted } from 'vue'
 
 import { ElButton } from 'element-plus'
 import BaseDialog from '@/components/element/BaseDialog.vue'
@@ -54,6 +56,9 @@ import useVW from '@/hooks/useVW'
 import useFetch from '@/hooks/useFetch'
 import { sessionStorage } from '@/plugins/storage'
 import bus from '@/utils/bus'
+import useMarkStore from '@/store/mark'
+
+const markStore = useMarkStore()
 const props = withDefaults(
   defineProps<{
     /** 弹窗模式? */
@@ -160,12 +165,10 @@ const questionList = computed(() => {
   const { mainNumber, mainTitle, questionList = [] } = questionStruct.value
 
   // 更新分数端评卷时间
-  const markLevelSpeedLimitList = questionStruct.value.markLevelSpeedLimitList
-    ? JSON.parse(questionStruct.value.markLevelSpeedLimitList)
-    : []
+  const markDelay = questionStruct.value.markDelay ? JSON.parse(questionStruct.value.markDelay) : []
   const getMarkLevelSpeedLimit = (score: number): number => {
-    if (markLevelSpeedLimitList.length) {
-      const speedLimit = item.markLevelSpeedLimitList.find((limit) => {
+    if (markDelay.length) {
+      const speedLimit = markDelay.find((limit) => {
         return limit.endScore >= score && limit.startScore <= score
       })
       return speedLimit?.minMarkTime || 0
@@ -188,6 +191,32 @@ const allowSubmit = computed(() => {
   return filterArr.length === questionList.value?.length
 })
 
+// 倒计时相关计算属性
+const isCountingDown = computed(() => markStore.isCountingDown)
+const buttonText = computed(() => markStore.buttonText)
+const buttonDisabled = computed(() => {
+  return isCountingDown.value || !allowSubmit.value
+})
+
+// 启动倒计时
+const startCountdown = () => {
+  const markSpeedLimit = questionList.value[activeIndex.value]?.markSpeedLimit
+  markStore.startCountdown(markSpeedLimit)
+}
+
+const currentQuestion = computed(() => {
+  return questionList.value[activeIndex.value]
+})
+
+// 监听questionList变化,启动倒计时
+watch(
+  () => currentQuestion.value,
+  () => {
+    startCountdown()
+  },
+  { immediate: true, deep: true }
+)
+
 const getClass = (val: string, callback?: string) => {
   return dialogMode.value ? val : callback || ''
 }
@@ -256,6 +285,11 @@ bus.on('openScoreDialogByMouseRight', () => {
     onToggleClick()
   }
 })
+
+// 组件卸载时清除倒计时
+onUnmounted(() => {
+  markStore.clearCountdown()
+})
 </script>
 
 <style scoped lang="scss">

+ 4 - 50
src/components/shared/ScoringPanelItem.vue

@@ -93,7 +93,7 @@
 </template>
 
 <script setup lang="ts" name="ScoringPanelItem">
-import { watch, computed, ref, nextTick, withDefaults, defineComponent, useSlots, onUnmounted } from 'vue'
+import { watch, computed, ref, nextTick, withDefaults, defineComponent, useSlots } from 'vue'
 import SvgIcon from '@/components/common/SvgIcon.vue'
 import useVModel from '@/hooks/useVModel'
 import { getNumbers } from '@/utils/common'
@@ -190,60 +190,14 @@ const focused = ref<boolean>(false)
 const refInput1 = ref<HTMLInputElement>()
 const refInput2 = ref<HTMLInputElement>()
 
-// 倒计时相关状态
-const countdownTime = ref<number>(0)
-const countdownTimer = ref<NodeJS.Timeout | null>(null)
-const isCountingDown = computed(() => countdownTime.value > 0)
-
-// 按钮文本和可点击状态
-const buttonText = computed(() => {
-  return isCountingDown.value ? `${countdownTime.value}s` : '确定'
-})
+// 使用store中的倒计时功能
+const isCountingDown = computed(() => markStore.isCountingDown)
+const buttonText = computed(() => markStore.buttonText)
 
 const buttonDisabled = computed(() => {
   return isCountingDown.value || !props.allowSubmit
 })
 
-// 启动倒计时
-const startCountdown = () => {
-  // 清除之前的计时器
-  if (countdownTimer.value) {
-    clearInterval(countdownTimer.value)
-    countdownTimer.value = null
-  }
-
-  const markSpeedLimit = question.value.markSpeedLimit
-  if (!markSpeedLimit || markSpeedLimit <= 0) {
-    countdownTime.value = 0
-    return
-  }
-
-  countdownTime.value = markSpeedLimit
-  countdownTimer.value = setInterval(() => {
-    countdownTime.value--
-    if (countdownTime.value <= 0) {
-      clearInterval(countdownTimer.value!)
-      countdownTimer.value = null
-    }
-  }, 1000)
-}
-
-// 监听question变化,重新启动倒计时
-watch(
-  () => props.question,
-  () => {
-    startCountdown()
-  },
-  { immediate: true, deep: true }
-)
-
-// 组件卸载时清除计时器
-onUnmounted(() => {
-  if (countdownTimer.value) {
-    clearInterval(countdownTimer.value)
-  }
-})
-
 watch(
   () => props.active,
   () => {

+ 4 - 3
src/modules/admin-subject/edit-main-question/index.vue

@@ -35,7 +35,7 @@
           </el-select>
         </template>
         <template #form-item-levelMarkTime>
-          <score-range-time-editor ref="scoreRangeTimeEditorRef" v-model="model.markLevelSpeedLimitList" />
+          <score-range-time-editor ref="scoreRangeTimeEditorRef" v-model="model.markDelay" />
         </template>
       </base-form>
     </el-card>
@@ -163,7 +163,7 @@ const model = reactive<ExtractApiParams<'addMainQuestion'>>({
   startNumber: 1,
   relationMainNumber: void 0,
   markSpeedLimit: false,
-  markLevelSpeedLimitList: [],
+  markDelay: [],
 })
 const compareChange = (val: string) => {
   if (val == '0') {
@@ -442,6 +442,7 @@ if (isEdit) {
       result.remarkNumber = (result.remarkNumber || 0) / 60
     }
     Object.assign(model, omit(result, 'examId'))
+    model.markDelay = result.markDelay ? JSON.parse(result.markDelay || '[]') : []
     // levelRangValues.value = result.levelRange.slice(0)
     levelRangValues.value = result.levelRange.slice(0).map((item) => {
       return item * 100
@@ -474,7 +475,7 @@ const onSubmit = async () => {
         { ...model, levelRange: model.levelRange || [], category: model.category || void 0 },
         { remarkNumber: model.remarkType === 'TIME' ? (model.remarkNumber || 0) * 60 : model.remarkNumber }
       )
-      data.markLevelSpeedLimitList = JSON.stringify(data.markLevelSpeedLimitList || [])
+      data.markDelay = JSON.stringify(data.markDelay || [])
       await (isEdit ? editMainQuestion(data) : addMainQuestion(data))
       ElMessage.success('保存成功')
       back()

+ 43 - 0
src/store/mark.ts

@@ -3,21 +3,64 @@ import { defineStore } from 'pinia'
 interface MarkStoreState {
   // 前端评卷试题的分值
   curQuestionScore: number | null
+  // 倒计时相关状态
+  countdownTime: number
+  countdownTimer: NodeJS.Timeout | null
 }
 
 interface MarkStoreActions {
   setCurQuestionScore: (val: number | null) => void
+  startCountdown: (markSpeedLimit?: number) => void
+  clearCountdown: () => void
+  updateCountdownTime: (time: number) => void
 }
+
 const useMarkStore = defineStore<'mark', MarkStoreState, Record<string, any>, MarkStoreActions>('mark', {
   state() {
     return {
       curQuestionScore: null,
+      countdownTime: 0,
+      countdownTimer: null,
     }
   },
+  getters: {
+    isCountingDown: (state) => state.countdownTime > 0,
+    buttonText: (state) => (state.countdownTime > 0 ? `${state.countdownTime}s` : '确定'),
+  },
   actions: {
     setCurQuestionScore(val: number | null) {
       this.curQuestionScore = val
     },
+
+    startCountdown(markSpeedLimit?: number) {
+      // 清除之前的计时器
+      this.clearCountdown()
+
+      if (!markSpeedLimit || markSpeedLimit <= 0) {
+        this.countdownTime = 0
+        return
+      }
+
+      this.countdownTime = markSpeedLimit
+      this.countdownTimer = setInterval(() => {
+        this.countdownTime--
+        if (this.countdownTime <= 0) {
+          this.clearCountdown()
+        }
+      }, 1000)
+    },
+
+    clearCountdown() {
+      if (this.countdownTimer) {
+        clearInterval(this.countdownTimer)
+        this.countdownTimer = null
+      }
+      this.countdownTime = 0
+    },
+
+    updateCountdownTime(time: number) {
+      this.countdownTime = time
+    },
   },
 })