From 1f47e645733ed0d42c1bb70e41ff0e0ecc8e8f5a Mon Sep 17 00:00:00 2001 From: ysn <2126564605@qq.com> Date: Wed, 17 Jun 2026 14:50:38 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E7=97=85=E4=BE=8B=E5=BA=93-=E8=AF=A6?= =?UTF-8?q?=E6=83=85-=E5=A4=8D=E5=88=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/cases/detail.vue | 151 ++++++++++++++++++++++++++++++++----- 1 file changed, 131 insertions(+), 20 deletions(-) diff --git a/src/views/cases/detail.vue b/src/views/cases/detail.vue index bbd00ee..0900706 100644 --- a/src/views/cases/detail.vue +++ b/src/views/cases/detail.vue @@ -283,7 +283,7 @@ v-model="form.text_comment" type="textarea" :rows="9" - :disabled=" + :readonly=" form.status != 1 && form.status != 5 && form.status != 15 @@ -297,7 +297,7 @@ v-model="form.text_conclusion" type="textarea" :rows="4" - :disabled=" + :readonly=" form.status != 1 && form.status != 5 && form.status != 15 @@ -319,10 +319,12 @@ v-model="item.user_comment" type="textarea" :rows="3" - :disabled=" - form.status != 1 && - form.status != 5 && - form.status != 15 + :readonly=" + (form.status != 1 && + form.status != 5 && + form.status != 15) || + item.confirm > 0 || + item.expert_id != userInfo.id " />
@@ -330,10 +332,13 @@ type="text" icon="el-icon-document-copy" :disabled=" - form.status != 1 && - form.status != 5 && - form.status != 15 + (form.status != 1 && + form.status != 5 && + form.status != 15) || + !item.user_comment || + !item.user_comment.trim() " + @click="handleCopyAllExpertComments(item)" > 全部复制 @@ -345,18 +350,25 @@ form.status != 5 && form.status != 15 " - v-if="item.confirm == 0" + v-if=" + item.confirm == 0 && item.expert_id == userInfo.id + " > 一键同意 + + 专家已确认 + 待确认 @@ -1484,6 +1496,110 @@ export default { } }); }, + async handleCopyAllExpertComments(item) { + const text = item.user_comment || ""; + if (!text || !text.trim()) { + // this.$modal.msgWarning('没有可复制的内容'); + return; + } + try { + if (navigator.clipboard && window.isSecureContext) { + console.log("复制策略 - 使用 Clipboard API"); + await navigator.clipboard.writeText(text); + this.$modal.msgSuccess("复制成功"); + } else { + console.log("复制策略 - 使用 execCommand fallback"); + const textarea = document.createElement("textarea"); + textarea.value = text; + textarea.style.position = "fixed"; + textarea.style.left = "-9999px"; + document.body.appendChild(textarea); + textarea.select(); + const success = document.execCommand("copy"); + document.body.removeChild(textarea); + if (success) { + console.log("execCommand 返回 true"); + this.$modal.msgSuccess("复制成功"); + } else { + console.log("execCommand 返回 false,使用兜底方案"); + this.showCopyFallback(text); + } + } + } catch (err) { + console.error("复制失败 - 捕获异常:", err); + this.showCopyFallback(text); + } + }, + showCopyFallback(text) { + const dialog = document.createElement("div"); + dialog.style.cssText = ` + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: #fff; + padding: 20px; + border-radius: 8px; + box-shadow: 0 2px 12px rgba(0,0,0,0.15); + z-index: 9999; + max-width: 80%; + max-height: 80vh; + overflow-y: auto; + `; + const title = document.createElement("h3"); + title.textContent = "复制内容"; + title.style.margin = "0 0 12px 0"; + title.style.fontSize = "16px"; + dialog.appendChild(title); + + const textarea = document.createElement("textarea"); + textarea.value = text; + textarea.style.width = "400px"; + textarea.style.height = "200px"; + textarea.style.marginBottom = "12px"; + textarea.style.padding = "8px"; + textarea.style.border = "1px solid #e4e7ed"; + textarea.style.borderRadius = "4px"; + textarea.addEventListener("focus", () => textarea.select()); + dialog.appendChild(textarea); + + const btn = document.createElement("button"); + btn.textContent = "确定"; + btn.style.cssText = ` + display: block; + margin: 0 auto; + padding: 8px 24px; + background: #409eff; + color: #fff; + border: none; + border-radius: 4px; + cursor: pointer; + `; + btn.addEventListener("click", () => { + document.body.removeChild(dialog); + document.body.removeChild(mask); + }); + dialog.appendChild(btn); + + const mask = document.createElement("div"); + mask.style.cssText = ` + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0,0,0,0.5); + z-index: 9998; + `; + mask.addEventListener("click", () => { + document.body.removeChild(dialog); + document.body.removeChild(mask); + }); + + document.body.appendChild(mask); + document.body.appendChild(dialog); + textarea.select(); + }, }, }; @@ -1613,9 +1729,4 @@ export default { display: inline-block; cursor: pointer; } - -// 禁用输入框字体颜色改为黑色 -::v-deep .el-textarea__inner:disabled { - color: #000; -} \ No newline at end of file From ab741ed4d161dfde34f0b6e15968d41e9348f293 Mon Sep 17 00:00:00 2001 From: ysn <2126564605@qq.com> Date: Wed, 17 Jun 2026 14:51:28 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E8=AE=BE=E7=BD=AE-?= =?UTF-8?q?=E7=AD=BE=E5=90=8D-=E5=8A=9F=E8=83=BD=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/requestMinio.js | 85 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 3 deletions(-) diff --git a/src/utils/requestMinio.js b/src/utils/requestMinio.js index 783f4b1..5f63fc0 100644 --- a/src/utils/requestMinio.js +++ b/src/utils/requestMinio.js @@ -49,8 +49,14 @@ export function getMinioClient() { */ export async function uploadFile(bucket, objectName, file, metaData = {}, onProgress) { return new Promise((resolve, reject) => { + // 检查 MinIO 客户端是否初始化 if (!s3Client) { - return reject(new Error('MinIO client not initialized')) + console.error('❌ MinIO client not initialized, attempting fallback upload...') + + // 回退到使用 HTTP 表单上传 + return fallbackUpload(bucket, objectName, file, metaData, onProgress) + .then(resolve) + .catch(reject) } console.log('=== MinIO Upload ===') @@ -90,12 +96,85 @@ export async function uploadFile(bucket, objectName, file, metaData = {}, onProg }) }) .catch((err) => { - console.error('❌ Upload failed:', err) - reject(new Error('Upload failed: ' + err.message)) + console.error('❌ AWS SDK Upload failed:', err) + console.log('Attempting fallback upload...') + + // 尝试回退上传 + fallbackUpload(bucket, objectName, file, metaData, onProgress) + .then(resolve) + .catch((fallbackErr) => { + reject(new Error('Upload failed: ' + fallbackErr.message)) + }) }) }) } +/** + * 回退上传方法 - 使用 HTTP POST 表单上传 + * @param {string} bucket - 存储桶名称 + * @param {string} objectName - 对象名称 + * @param {File} file - 文件对象 + * @param {object} metaData - 元数据 + * @param {function} onProgress - 进度回调 + * @returns {Promise} - 上传结果 + */ +async function fallbackUpload(bucket, objectName, file, metaData, onProgress) { + return new Promise((resolve, reject) => { + const config = window._globalConfig || {} + const uploadUrl = config.MINIO_UPLOAD_URL || '/api/upload/minio' + + console.log('=== Fallback Upload ===') + console.log('Upload URL:', uploadUrl) + console.log('Bucket:', bucket) + console.log('Object:', objectName) + + const formData = new FormData() + formData.append('bucket', bucket) + formData.append('objectName', objectName) + formData.append('file', file, file.name) + + // 添加元数据 + for (const key in metaData) { + formData.append('meta_' + key, metaData[key]) + } + + const xhr = new XMLHttpRequest() + + xhr.upload.addEventListener('progress', (event) => { + if (event.lengthComputable && onProgress) { + const percent = Math.round((event.loaded / event.total) * 100) + onProgress(percent) + } + }) + + xhr.addEventListener('load', () => { + try { + const response = JSON.parse(xhr.responseText) + if (xhr.status >= 200 && xhr.status < 300) { + console.log('✅ Fallback upload successful:', response) + resolve({ + bucket, + objectName: response.objectName || objectName, + etag: response.etag, + url: response.url || `${uploadUrl}/${bucket}/${objectName}` + }) + } else { + reject(new Error(response.message || 'Upload failed')) + } + } catch (e) { + reject(new Error('Failed to parse response: ' + e.message)) + } + }) + + xhr.addEventListener('error', () => { + reject(new Error('Network error during upload')) + }) + + xhr.open('POST', uploadUrl, true) + xhr.send(formData) + }) +} + /** * 下载文件(获取预签名 URL) * @param {string} bucket - 存储桶名称