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 - 存储桶名称