From c1f8ac072aa2fbd4741a7cb10d4c39a45c5afec6 Mon Sep 17 00:00:00 2001 From: zhangxiaohua <827885272@qq.com> Date: Thu, 22 Jan 2026 15:54:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=AE=A1=E7=90=86=E7=AB=AF?= =?UTF-8?q?=E4=BD=9C=E5=93=81=E8=AF=A6=E6=83=853D=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E9=A2=84=E8=A7=88=E5=A4=B1=E8=B4=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 添加 parsedFiles 计算属性正确解析 files 字段(可能是 JSON 字符串) 2. 修改 hasModelFile 和 modelFileUrl 使用解析后的数组 3. 修改跳转方式使用 sessionStorage + router.push(与学生端一致) Co-Authored-By: Claude Opus 4.5 --- .../contests/components/WorkDetailModal.vue | 46 +++++++++++++++---- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/frontend/src/views/contests/components/WorkDetailModal.vue b/frontend/src/views/contests/components/WorkDetailModal.vue index c66a545..08e72c2 100644 --- a/frontend/src/views/contests/components/WorkDetailModal.vue +++ b/frontend/src/views/contests/components/WorkDetailModal.vue @@ -174,6 +174,21 @@ const drawerTitle = computed(() => { return "作品详情" }) +// 解析 files 字段(可能是 JSON 字符串) +const parsedFiles = computed(() => { + if (!workDetail.value) return [] + let files = workDetail.value.files || [] + if (typeof files === "string") { + try { + files = JSON.parse(files) + } catch { + files = [] + } + } + if (!Array.isArray(files)) files = [] + return files +}) + // 预览图URL const previewImageUrl = computed(() => { if (!workDetail.value) return "" @@ -182,8 +197,8 @@ const previewImageUrl = computed(() => { return workDetail.value.previewUrl } // 其次从 files 数组中查找图片 - const imageFromFiles = workDetail.value.files?.find( - (url) => /\.(jpg|jpeg|png|gif|webp)$/i.test(url) + const imageFromFiles = parsedFiles.value.find( + (url: string) => /\.(jpg|jpeg|png|gif|webp)$/i.test(url) ) if (imageFromFiles) return imageFromFiles // 最后从 attachments 中查找 @@ -204,7 +219,7 @@ const isModelFile = (urlOrFileName: string): boolean => { const hasModelFile = computed(() => { if (!workDetail.value) return false // 检查 files 数组 - const hasInFiles = workDetail.value.files?.some((url) => isModelFile(url)) + const hasInFiles = parsedFiles.value.some((url: string) => isModelFile(url)) if (hasInFiles) return true // 检查 attachments 数组 const hasInAttachments = workDetail.value.attachments?.some( @@ -217,7 +232,7 @@ const hasModelFile = computed(() => { const modelFileUrl = computed(() => { if (!workDetail.value) return "" // 优先从 files 数组中查找 - const modelFromFiles = workDetail.value.files?.find((url) => isModelFile(url)) + const modelFromFiles = parsedFiles.value.find((url: string) => isModelFile(url)) if (modelFromFiles) return modelFromFiles // 其次从 attachments 中查找 const modelAtt = workDetail.value.attachments?.find( @@ -272,12 +287,27 @@ const handleImageError = (e: Event) => { const handleView3DModel = () => { const tenantCode = route.params.tenantCode as string console.log("3D模型预览 - modelFileUrl:", modelFileUrl.value) - console.log("3D模型预览 - files:", workDetail.value?.files) + console.log("3D模型预览 - parsedFiles:", parsedFiles.value) console.log("3D模型预览 - attachments:", workDetail.value?.attachments) if (modelFileUrl.value) { - const url = `/${tenantCode}/workbench/model-viewer?url=${encodeURIComponent(modelFileUrl.value)}` - console.log("3D模型预览 - 跳转URL:", url) - window.open(url, "_blank") + // 收集所有3D模型URL + const allModelUrls = parsedFiles.value.filter((url: string) => isModelFile(url)) + + // 使用 sessionStorage 存储模型URL(与学生端保持一致) + if (allModelUrls.length > 1) { + sessionStorage.setItem("model-viewer-urls", JSON.stringify(allModelUrls)) + sessionStorage.setItem("model-viewer-index", "0") + sessionStorage.removeItem("model-viewer-url") + } else { + sessionStorage.setItem("model-viewer-url", modelFileUrl.value) + sessionStorage.removeItem("model-viewer-urls") + sessionStorage.removeItem("model-viewer-index") + } + + // 使用 router.push 跳转 + router.push({ + path: `/${tenantCode}/workbench/model-viewer`, + }) } else { message.warning("未找到3D模型文件") }