feat: 讲解模式新增展开收起
Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CI / CI OK (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Deploy Website on push / Rerun on failure (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CI / CI OK (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Deploy Website on push / Rerun on failure (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
This commit is contained in:
parent
adbfc847ec
commit
08eb7248ec
@ -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<ExplainPhase>('detail')
|
||||
const countdown = ref(3)
|
||||
let countdownTimer: ReturnType<typeof setInterval> | null = null
|
||||
let countdownTimer: null | ReturnType<typeof setInterval> = 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"
|
||||
>
|
||||
<!-- 左侧:题目 -->
|
||||
<div class="explain-left" :style="{ flex: `0 0 ${leftWidth}px` }">
|
||||
<div class="explain-left" :style="leftPanelStyle">
|
||||
<div class="explain-panel-header">
|
||||
<span class="panel-title">第 {{ currentIndex + 1 }} 题</span>
|
||||
</div>
|
||||
@ -457,10 +468,34 @@ async function getTitleStudentInfo(titleId: string, markType: number) {
|
||||
</div>
|
||||
|
||||
<!-- 拖动分隔条 -->
|
||||
<div class="resize-handle" @mousedown="onResizeStart"></div>
|
||||
<div
|
||||
class="resize-handle"
|
||||
:class="{ collapsed: answerPanelCollapsed }"
|
||||
@mousedown="!answerPanelCollapsed && onResizeStart($event)"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="answer-panel-toggle"
|
||||
:aria-label="answerPanelCollapsed ? '展开答案解析' : '收起答案解析'"
|
||||
:title="answerPanelCollapsed ? '展开答案解析' : '收起答案解析'"
|
||||
@mousedown.stop
|
||||
@click.stop="toggleAnswerPanel"
|
||||
>
|
||||
<span class="toggle-arrow">
|
||||
{{ answerPanelCollapsed ? '<' : '>' }}
|
||||
</span>
|
||||
<span class="toggle-text">
|
||||
{{ answerPanelCollapsed ? '展开' : '收起' }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 右侧:答案、解析、统计 -->
|
||||
<div class="explain-right" style="flex: 1; width: 0">
|
||||
<div
|
||||
v-show="!answerPanelCollapsed"
|
||||
class="explain-right"
|
||||
style="flex: 1; width: 0"
|
||||
>
|
||||
<div class="explain-panel-header">
|
||||
<span class="panel-title">答案与解析</span>
|
||||
</div>
|
||||
@ -475,7 +510,9 @@ async function getTitleStudentInfo(titleId: string, markType: number) {
|
||||
<latex-text :text="currentQuestion.xkwTitle.answer" />
|
||||
</div>
|
||||
<div v-else class="answer-analysis-collapsed">
|
||||
{{ hasAnswer ? '答案已收起,点击底部“展开答案”查看' : '暂无答案' }}
|
||||
{{
|
||||
hasAnswer ? '答案已收起,点击底部“展开答案”查看' : '暂无答案'
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -491,7 +528,11 @@ async function getTitleStudentInfo(titleId: string, markType: number) {
|
||||
<latex-text :text="currentQuestion.xkwTitle.explanation" />
|
||||
</div>
|
||||
<div v-else class="answer-analysis-collapsed">
|
||||
{{ hasExplanation ? '解析已收起,点击底部“展开解析”查看' : '暂无解析' }}
|
||||
{{
|
||||
hasExplanation
|
||||
? '解析已收起,点击底部“展开解析”查看'
|
||||
: '暂无解析'
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user