feat(web): 题目页的「开启同步」换成「求助」
学生发起求助,状态与排队位置显示在按钮旁。 教师端入口不在题目页,所以对教师隐藏这个按钮。 顺带修正 handleHelpCancel:去掉 request.socket !== ws 的校验。 学生取消自己的求助,不管从他哪个标签页发起都合法—— getRequest(ws.data.userId) 已经把范围锁在这一个用户上了, 不是跨用户操作,不需要再比对是不是同一条连接。这层校验此前 会让「第二个标签页点取消」被服务端静默丢弃,前端却已经乐观 地把按钮变回「求助」,是一处 UI 说谎;现在两边状态一致。 handleCollabClose 里排队分支的 socket 归属校验不受影响, 那里的关闭事件是顺带触发的,仍然需要认出是不是本人这条连接。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K1d8B3f4SXJwDvUY625eQd
This commit is contained in:
1 parent
ab8fcc2d42
commit
6f873be367
4 files changed
+46
-165
No files matched your search
@@ -2,7 +2,6 @@
|
||||
import { storeToRefs } from "pinia"
|
||||
import { useCodeStore } from "oj/store/code"
|
||||
import { useProblemStore } from "oj/store/problem"
|
||||
import { provideSyncStatus } from "oj/composables/syncStatus"
|
||||
import { SOURCES } from "utils/constants"
|
||||
import SyncCodeEditor from "shared/components/SyncCodeEditor.vue"
|
||||
import { useBreakpoints } from "shared/composables/breakpoints"
|
||||
@@ -15,7 +14,6 @@ const FlowchartEditor = defineAsyncComponent(
|
||||
)
|
||||
|
||||
const route = useRoute()
|
||||
const formRef = useTemplateRef<InstanceType<typeof Form>>("formRef")
|
||||
const flowchartEditorRef = useTemplateRef("flowchartEditorRef")
|
||||
|
||||
const codeStore = useCodeStore()
|
||||
@@ -24,10 +22,6 @@ const { problem } = storeToRefs(problemStore)
|
||||
|
||||
const { isDesktop } = useBreakpoints()
|
||||
|
||||
const sync = ref(false)
|
||||
// 提供同步状态给子组件使用
|
||||
const syncStatus = provideSyncStatus()
|
||||
|
||||
const contestID = route.params.contestID || null
|
||||
const storageKey = computed(
|
||||
() =>
|
||||
@@ -72,38 +66,13 @@ const changeLanguage = (v: LANGUAGE) => {
|
||||
)
|
||||
}
|
||||
|
||||
const toggleSync = (value: boolean) => {
|
||||
sync.value = value
|
||||
if (!value) {
|
||||
syncStatus.reset()
|
||||
}
|
||||
}
|
||||
|
||||
const handleSyncClosed = () => {
|
||||
sync.value = false
|
||||
syncStatus.reset()
|
||||
formRef.value?.resetSyncStatus()
|
||||
}
|
||||
|
||||
const handleSyncStatusChange = (status: {
|
||||
otherUser?: { name: string; isSuperAdmin: boolean }
|
||||
}) => {
|
||||
syncStatus.setOtherUser(status.otherUser)
|
||||
}
|
||||
|
||||
// 提供FlowchartEditor的ref给子组件
|
||||
provide("flowchartEditorRef", flowchartEditorRef)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-flex vertical>
|
||||
<Form
|
||||
ref="formRef"
|
||||
:storage-key="storageKey"
|
||||
:is-connected="sync"
|
||||
@change-language="changeLanguage"
|
||||
@toggle-sync="toggleSync"
|
||||
/>
|
||||
<Form :storage-key="storageKey" @change-language="changeLanguage" />
|
||||
<FlowchartEditor
|
||||
v-if="codeStore.code.language === 'Flowchart'"
|
||||
ref="flowchartEditorRef"
|
||||
@@ -111,13 +80,10 @@ provide("flowchartEditorRef", flowchartEditorRef)
|
||||
<SyncCodeEditor
|
||||
v-else
|
||||
v-model:value="codeStore.code.value"
|
||||
:sync="sync"
|
||||
:problem="problem!._id"
|
||||
:language="codeStore.code.language"
|
||||
:height="editorHeight"
|
||||
@update:model-value="changeCode"
|
||||
@sync-closed="handleSyncClosed"
|
||||
@sync-status-change="handleSyncStatusChange"
|
||||
/>
|
||||
</n-flex>
|
||||
</template>
|
||||
Reference in new issue
Block a user