From afeeed281e60466b576fbe74d339634cc5d07b82 Mon Sep 17 00:00:00 2001 From: Codex Assistant <codex@example.com> Date: 星期三, 08 十月 2025 08:56:42 +0800 Subject: [PATCH] 修复评审功能和用户认证问题 --- web/src/views/review-detail.vue | 114 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 97 insertions(+), 17 deletions(-) diff --git a/web/src/views/review-detail.vue b/web/src/views/review-detail.vue index 848948b..fd0a3be 100644 --- a/web/src/views/review-detail.vue +++ b/web/src/views/review-detail.vue @@ -168,13 +168,17 @@ <!-- 鏂囦欢棰勮瀵硅瘽妗� --> <el-dialog v-model="previewVisible" title="鏂囦欢棰勮" width="80%" center> <div class="preview-content"> - <iframe - v-if="previewUrl" - :src="previewUrl" - style="width: 100%; height: 500px; border: none;" - ></iframe> + <!-- 鍥剧墖棰勮 --> + <img v-if="previewType === 'image' && previewUrl" :src="previewUrl" style="max-width: 100%; max-height: 70vh; object-fit: contain;" /> + <!-- 瑙嗛棰勮 --> + <video v-else-if="previewType === 'video' && previewUrl" :src="previewUrl" controls style="width: 100%; max-height: 70vh;"></video> + <!-- PDF 棰勮 --> + <iframe v-else-if="previewType === 'pdf' && previewUrl" :src="previewUrl" style="width: 100%; height: 70vh; border: none;"></iframe> + <!-- DOCX 棰勮 --> + <div v-else-if="previewType === 'docx'" ref="docxContainer" class="docx-preview"></div> + <!-- 鍏跺畠涓嶆敮鎸� --> <div v-else class="preview-error"> - <el-empty description="鏃犳硶棰勮姝ゆ枃浠剁被鍨�" /> + <el-empty description="鏃犳硶棰勮姝ゆ枃浠剁被鍨嬶紝璇蜂笅杞芥煡鐪�" /> </div> </div> </el-dialog> @@ -204,6 +208,8 @@ const ratingComment = ref('') const previewVisible = ref(false) const previewUrl = ref('') +const previewType = ref('') // image | video | pdf | docx | unknown +const docxContainer = ref(null) // 鏉冮檺楠岃瘉鐩稿叧 const currentJudge = ref(null) @@ -446,17 +452,84 @@ } } -// 鏂囦欢棰勮 -const previewFile = (file) => { - // 鏍规嵁鏂囦欢绫诲瀷鍐冲畾棰勮鏂瑰紡 - const fileExtension = file.name.split('.').pop().toLowerCase() - const previewableTypes = ['pdf', 'txt', 'jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'mp4', 'avi', 'mov', 'wmv', 'flv', 'webm'] - - if (previewableTypes.includes(fileExtension)) { - // 鍦ㄦ柊绐楀彛涓墦寮�棰勮 - window.open(file.url, '_blank') - } else { - ElMessage.warning('姝ゆ枃浠剁被鍨嬩笉鏀寔棰勮锛岃涓嬭浇鏌ョ湅') +/** + * 鏂囦欢棰勮锛氭寜鎵╁睍鍚嶅垎鍙戝埌鍥剧墖/瑙嗛/PDF/DOCX + */ +const previewFile = async (file) => { + const ext = (file.name?.split('.').pop() || '').toLowerCase() + previewVisible.value = true + previewUrl.value = '' + previewType.value = '' + // 缁熶竴鍙栧彲鐢ㄧ殑瀹屾暣 URL + const url = file.url || file.fullUrl || file.full_path || file.path + + const imageExts = ['jpg','jpeg','png','gif','bmp','webp'] + const videoExts = ['mp4','webm','ogg','avi','mov','wmv','flv','mkv'] + + if (imageExts.includes(ext)) { + previewType.value = 'image' + previewUrl.value = url + return + } + if (videoExts.includes(ext)) { + previewType.value = 'video' + previewUrl.value = url + return + } + if (ext === 'pdf') { + previewType.value = 'pdf' + previewUrl.value = url + return + } + if (ext === 'docx') { + previewType.value = 'docx' + try { + await renderDocx(url) + } catch (e) { + console.error('DOCX 棰勮澶辫触:', e) + ElMessage.warning('DOCX 棰勮澶辫触锛屽缓璁笅杞芥煡鐪�') + previewType.value = 'unknown' + } + return + } + if (ext === 'doc') { + ElMessage.info('鏆備笉鏀寔 .doc 棰勮锛岃涓嬭浇鏌ョ湅') + previewType.value = 'unknown' + return + } + + ElMessage.warning('姝ゆ枃浠剁被鍨嬩笉鏀寔棰勮锛岃涓嬭浇鏌ョ湅') + previewType.value = 'unknown' +} + +/** + * 鍔ㄦ�佸姞杞� docx-preview 骞舵覆鏌� DOCX + */ +const renderDocx = async (url) => { + const ensureScript = () => new Promise((resolve, reject) => { + if (window.docx && window.docx.renderAsync) return resolve(true) + const existed = document.querySelector('script[data-docx-preview]') + if (existed) { + existed.addEventListener('load', () => resolve(true)) + existed.addEventListener('error', reject) + return + } + const s = document.createElement('script') + s.src = 'https://unpkg.com/docx-preview/dist/docx-preview.min.js' + s.async = true + s.setAttribute('data-docx-preview', '1') + s.onload = () => resolve(true) + s.onerror = reject + document.head.appendChild(s) + }) + + await ensureScript() + const res = await fetch(url, { credentials: 'include' }) + if (!res.ok) throw new Error('鑾峰彇 DOCX 澶辫触: ' + res.status) + const blob = await res.blob() + if (docxContainer.value) { + docxContainer.value.innerHTML = '' + await window.docx.renderAsync(blob, docxContainer.value, null, { inWrapper: true }) } } @@ -699,6 +772,13 @@ .preview-content { text-align: center; } +.docx-preview { + text-align: left; + max-height: 70vh; + overflow: auto; + background: #fff; + padding: 12px; +} .preview-error { padding: 40px 0; -- Gitblit v1.8.0