|
|
|
|
@ -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() { |
|
|
|
|
|