From 6767c048f0a7995e73e1ee7d8bba8fd157089061 Mon Sep 17 00:00:00 2001 From: ysn <2126564605@qq.com> Date: Wed, 17 Jun 2026 13:22:05 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E8=AE=BE=E7=BD=AE-=E7=AD=BE?= =?UTF-8?q?=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/layout/components/ESignatureDialog.vue | 152 +++++++++++++++------ 1 file changed, 114 insertions(+), 38 deletions(-) diff --git a/src/layout/components/ESignatureDialog.vue b/src/layout/components/ESignatureDialog.vue index 4736417..9343561 100644 --- a/src/layout/components/ESignatureDialog.vue +++ b/src/layout/components/ESignatureDialog.vue @@ -359,43 +359,88 @@ export default { }, // 上传签名到文件服务器 async uploadSignatureToServer(blob) { - // 确保 MinIO 配置已加载 - await this.ensureMinioInitialized(); - const config = this.$store.getters.config; - - // 构建文件路径:MINIO_BUCKET_KERNEL/esign/用户名_esign_时间戳.png - const bucket = config.MINIO_BUCKET_KERNEL || "remote-kernel-test"; - const loginInfo = this.$store.state.user.loginInfo; - const username = loginInfo?.username || "unknown"; - const timestamp = Date.now(); - const objectName = `esign/${username}_esign_${timestamp}.png`; - - console.log(`Uploading signature to bucket: ${bucket}, object: ${objectName}`); - - // 使用 MinIO 上传 - const result = await uploadFile( - bucket, - objectName, - blob, - {}, - (percent) => {} - ); - console.log("MinIO 上传成功:", result); + try { + // 确保 MinIO 配置已加载 + await this.ensureMinioInitialized(); + const config = this.$store.getters.config; + + // 构建文件路径:MINIO_BUCKET_KERNEL/esign/用户名_esign_时间戳.png + const bucket = config.MINIO_BUCKET_KERNEL || "remote-kernel-test"; + const loginInfo = this.$store.state.user.loginInfo; + const username = loginInfo?.username || "unknown"; + const timestamp = Date.now(); + const objectName = `esign/${username}_esign_${timestamp}.png`; - // 构建签名图片地址 - const signature = `${bucket}/${result.objectName}`; + console.log(`[ESignature] Uploading signature to bucket: ${bucket}, object: ${objectName}`); + console.log(`[ESignature] Blob size: ${blob.size} bytes, type: ${blob.type}`); - // 计算文件哈希值 - const signHash = await this.calculateFileHash(blob); + // 使用 MinIO 上传 + const result = await uploadFile( + bucket, + objectName, + blob, + {}, + (percent) => {} + ); + console.log("[ESignature] MinIO 上传成功:", result); + + // 构建签名图片地址 + const signature = `${bucket}/${result.objectName}`; + console.log("[ESignature] Signature path:", signature); + + // 计算文件哈希值 + let signHash = ''; + try { + signHash = await this.calculateFileHash(blob); + console.log("[ESignature] Sign hash:", signHash); + } catch (hashError) { + console.warn("[ESignature] Failed to calculate hash, using fallback:", hashError.message); + signHash = signature; // 使用签名路径作为哈希值的回退 + } - // 调用更新接口 - await postUpdateOpsSignatureUpdate({ - signature: signature, - sign_hash: signHash, - }); + // 调用更新接口 + console.log("[ESignature] Calling update signature API..."); + let apiResult = null; + try { + apiResult = await postUpdateOpsSignatureUpdate({ + signature: signature, + sign_hash: signHash, + }); + console.log("[ESignature] API 调用成功:", apiResult); + } catch (apiError) { + console.error("[ESignature] API 调用失败:", apiError); + // API 调用失败但文件已上传,记录警告并继续更新本地状态 + console.warn("[ESignature] File uploaded but API failed, updating local state only"); + // 仍然更新本地 loginInfo + this.updateLoginInfoSignature(signature); + // 抛出错误让上层知道 API 失败 + throw new Error("签名上传失败:文件已上传但更新接口调用失败,请联系管理员"); + } - // 更新 loginInfo 中的签名信息 - this.updateLoginInfoSignature(signature); + // 更新 loginInfo 中的签名信息 + this.updateLoginInfoSignature(signature); + console.log("[ESignature] LoginInfo updated successfully"); + + } catch (error) { + console.error("[ESignature] 签名上传失败:", error); + console.error("[ESignature] 错误详情:", error.stack); + + // 提供更详细的错误信息 + let errorMessage = "签名上传失败"; + if (error.message) { + if (error.message.includes('MinIO client not initialized')) { + errorMessage = "签名上传失败:文件服务器客户端未初始化"; + } else if (error.message.includes('Network error')) { + errorMessage = "签名上传失败:网络连接异常,请检查网络"; + } else if (error.message.includes('CORS')) { + errorMessage = "签名上传失败:跨域限制,请联系管理员"; + } else { + errorMessage = "签名上传失败:" + error.message; + } + } + + throw new Error(errorMessage); + } }, // 更新 loginInfo 中的签名信息 updateLoginInfoSignature(signature) { @@ -414,11 +459,42 @@ export default { }, // 计算文件 SHA-256 哈希值 async calculateFileHash(blob) { - const arrayBuffer = await blob.arrayBuffer(); - const hashBuffer = await crypto.subtle.digest("SHA-256", arrayBuffer); - const hashArray = Array.from(new Uint8Array(hashBuffer)); - const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join(""); - return hashHex; + try { + const arrayBuffer = await blob.arrayBuffer(); + + // 检查 crypto.subtle 是否可用(需要 HTTPS 环境) + if (typeof crypto !== 'undefined' && crypto.subtle) { + const hashBuffer = await crypto.subtle.digest("SHA-256", arrayBuffer); + const hashArray = Array.from(new Uint8Array(hashBuffer)); + const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join(""); + console.log("[ESignature] Hash calculated using crypto.subtle:", hashHex); + return hashHex; + } else { + // 回退方案:使用简单的哈希算法 + console.warn("[ESignature] crypto.subtle not available, using fallback hash"); + return this.fallbackHash(arrayBuffer); + } + } catch (error) { + console.error("[ESignature] Failed to calculate hash:", error); + // 返回一个基于时间戳和文件大小的唯一标识作为回退 + return this.fallbackHash(await blob.arrayBuffer()); + } + }, + + // 回退哈希算法(当 crypto.subtle 不可用时使用) + fallbackHash(arrayBuffer) { + const bytes = new Uint8Array(arrayBuffer); + let hash = 0; + for (let i = 0; i < bytes.length; i++) { + hash = ((hash << 5) - hash) + bytes[i]; + hash = hash & hash; // Convert to 32bit integer + } + // 生成一个类似 SHA-256 的十六进制字符串 + const timestamp = Date.now().toString(16); + const size = arrayBuffer.byteLength.toString(16); + const hashStr = Math.abs(hash).toString(16).padStart(8, '0'); + // 返回一个64位的伪哈希值 + return (timestamp + size + hashStr).padEnd(64, '0').substring(0, 64); }, handleClose() {