From 08eb7248ecec88582d72b20d2ab47e16c1a8c22e Mon Sep 17 00:00:00 2001 From: shawko Date: Sun, 10 May 2026 14:48:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=AE=B2=E8=A7=A3=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=B1=95=E5=BC=80=E6=94=B6=E8=B5=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../question-bank/task-mgr/paper-explain.vue | 135 ++++++++++++++++-- 1 file changed, 122 insertions(+), 13 deletions(-) diff --git a/playground/src/views/question-bank/task-mgr/paper-explain.vue b/playground/src/views/question-bank/task-mgr/paper-explain.vue index 0280f19..c39c613 100644 --- a/playground/src/views/question-bank/task-mgr/paper-explain.vue +++ b/playground/src/views/question-bank/task-mgr/paper-explain.vue @@ -2,10 +2,9 @@ import { computed, onActivated, onBeforeUnmount, onMounted, ref } from 'vue' import { useRoute, useRouter } from 'vue-router' -import hud from '#/utils/hud' - import { taskMgrService } from '#/api/service/question-bank/task-mgr' import PaperQuestionItem from '#/components/paper-question-item/index.vue' +import hud from '#/utils/hud' import ViewStudents from './components/viewStudents.vue' @@ -89,10 +88,10 @@ onActivated(() => { }) // ======================== 倒计时 ======================== -type ExplainPhase = 'detail' | 'countdown' | 'explaining' +type ExplainPhase = 'countdown' | 'detail' | 'explaining' const phase = ref('detail') const countdown = ref(3) -let countdownTimer: ReturnType | null = null +let countdownTimer: null | ReturnType = null function startCountdown() { document.documentElement.requestFullscreen?.().catch(() => {}) @@ -214,15 +213,23 @@ function resetZoom() { const currentIndex = ref(0) const answerExpanded = ref(false) const explanationExpanded = ref(false) +const answerPanelCollapsed = ref(false) const currentQuestion = computed(() => { return paperDetail.value[currentIndex.value] || null }) -const hasAnswer = computed(() => Boolean(currentQuestion.value?.xkwTitle?.answer)) +const hasAnswer = computed(() => + Boolean(currentQuestion.value?.xkwTitle?.answer), +) const hasExplanation = computed(() => Boolean(currentQuestion.value?.xkwTitle?.explanation), ) +const leftPanelStyle = computed(() => { + return answerPanelCollapsed.value + ? { flex: '1 1 auto' } + : { flex: `0 0 ${leftWidth.value}px` } +}) function getTitleKey(item: any) { return ( @@ -243,6 +250,10 @@ function toggleExplanation() { explanationExpanded.value = !explanationExpanded.value } +function toggleAnswerPanel() { + answerPanelCollapsed.value = !answerPanelCollapsed.value +} + async function enterExplaining() { initLeftWidth() resetZoom() @@ -294,7 +305,7 @@ function endExplaining() { hud.confirm({ content: '确定要结束讲解吗?', title: '提示', - zIndex: 999999, + zIndex: 999_999, onConfirm: async () => { const lastQuestion = paperDetail.value[paperDetail.value.length - 1] const lastQuestionId = getTitleKey(lastQuestion) @@ -422,7 +433,7 @@ async function getTitleStudentInfo(titleId: string, markType: number) { @wheel="onZoomWheel" > -
+
第 {{ currentIndex + 1 }} 题
@@ -457,10 +468,34 @@ async function getTitleStudentInfo(titleId: string, markType: number) {
-
+
+ +
-
+
答案与解析
@@ -475,7 +510,9 @@ async function getTitleStudentInfo(titleId: string, markType: number) {
- {{ hasAnswer ? '答案已收起,点击底部“展开答案”查看' : '暂无答案' }} + {{ + hasAnswer ? '答案已收起,点击底部“展开答案”查看' : '暂无答案' + }}
@@ -491,7 +528,11 @@ async function getTitleStudentInfo(titleId: string, markType: number) {
- {{ hasExplanation ? '解析已收起,点击底部“展开解析”查看' : '暂无解析' }} + {{ + hasExplanation + ? '解析已收起,点击底部“展开解析”查看' + : '暂无解析' + }}
@@ -714,8 +755,12 @@ async function getTitleStudentInfo(titleId: string, markType: number) { } .resize-handle { + position: relative; + display: flex; flex-shrink: 0; - width: 6px; + align-items: center; + justify-content: center; + width: 28px; cursor: col-resize; background: transparent; transition: background 0.2s; @@ -723,8 +768,72 @@ async function getTitleStudentInfo(titleId: string, markType: number) { .resize-handle:hover, .resize-handle:active { + background: #ecf5ff; +} + +.resize-handle::before { + width: 2px; + height: 100%; + content: ''; + background: #dcdfe6; + border-radius: 2px; + transition: background 0.2s; +} + +.resize-handle:hover::before, +.resize-handle:active::before { background: #409eff; - border-radius: 3px; +} + +.resize-handle.collapsed { + cursor: default; +} + +.answer-panel-toggle { + position: absolute; + top: 50%; + left: 50%; + z-index: 2; + display: inline-flex; + flex-direction: column; + gap: 2px; + align-items: center; + justify-content: center; + width: 42px; + height: 72px; + padding: 0; + font-size: 13px; + font-weight: 500; + color: #409eff; + cursor: pointer; + background: #fff; + border: 1px solid #d9ecff; + border-radius: 21px; + box-shadow: 0 2px 10px rgb(64 158 255 / 18%); + transform: translate(-50%, -50%); + transition: + color 0.2s, + background 0.2s, + border-color 0.2s, + box-shadow 0.2s; +} + +.answer-panel-toggle:hover, +.answer-panel-toggle:focus-visible { + color: #fff; + background: #409eff; + border-color: #409eff; + box-shadow: 0 4px 14px rgb(64 158 255 / 28%); + outline: none; +} + +.toggle-arrow { + font-size: 18px; + line-height: 1; +} + +.toggle-text { + line-height: 1.2; } .explain-panel-header {