From 0db8c9b94a9ac655549d5eba5c2a6c92ac386c06 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期四, 08 十月 2026 11:20:56 +0800
Subject: [PATCH] 提交最新代码

---
 culture/src/components/SignatureCanvas.vue |  166 ++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 122 insertions(+), 44 deletions(-)

diff --git a/culture/src/components/SignatureCanvas.vue b/culture/src/components/SignatureCanvas.vue
index e996394..11b773a 100644
--- a/culture/src/components/SignatureCanvas.vue
+++ b/culture/src/components/SignatureCanvas.vue
@@ -1,27 +1,11 @@
 <template>
-  <el-dialog
-    title="确认签字"
-    :visible.sync="visible"
-    :width="dialogWidth"
-    :close-on-click-modal="false"
-    custom-class="signature-dialog"
-    append-to-body
-    @close="$emit('update:visible', false)"
-  >
+  <el-dialog title="确认签字" :visible.sync="visible" :width="dialogWidth" :close-on-click-modal="false"
+    custom-class="signature-dialog" append-to-body @close="$emit('update:visible', false)">
     <div class="signature-container">
       <div class="signature-content">
-        <canvas
-          ref="signatureCanvas"
-          :width="canvasWidth"
-          :height="canvasHeight"
-          @mousedown="startDrawing"
-          @mousemove="draw"
-          @mouseup="stopDrawing"
-          @mouseleave="stopDrawing"
-          @touchstart="handleTouchStart"
-          @touchmove="handleTouchMove"
-          @touchend="stopDrawing"
-        ></canvas>
+        <canvas ref="signatureCanvas" :width="canvasWidth" :height="canvasHeight" @mousedown="startDrawing"
+          @mousemove="draw" @mouseup="stopDrawing" @mouseleave="stopDrawing" @touchstart="handleTouchStart"
+          @touchmove="handleTouchMove" @touchend="stopDrawing"></canvas>
       </div>
       <div class="signature-footer">
         <el-button type="default" @click="clearCanvas">重置</el-button>
@@ -32,6 +16,8 @@
 </template>
 
 <script>
+import { customUploadRequest, getUploadedFilePath } from '@/utils/utils'
+import {editSignPicture} from './service'
 export default {
   name: 'SignatureCanvas',
   props: {
@@ -42,10 +28,12 @@
   },
   data() {
     return {
+      roleType: JSON.parse(sessionStorage.getItem('userInfo')).roleType || 1,  // 1.超级管理员 2.审批人 3.工程师 4.实验员
       isDrawing: false,
       context: null,
       lastX: 0,
-      lastY: 0
+      lastY: 0,
+      hasDrawn: false
     }
   },
   computed: {
@@ -67,6 +55,10 @@
       if (val) {
         this.$nextTick(() => {
           this.initCanvas()
+          // 如果是实验员,加载保存的签名
+          if (this.roleType == 4 || this.roleType == 3) {
+            this.loadSavedSignature()
+          }
           // 添加窗口大小改变的监听
           window.addEventListener('resize', this.handleResize)
         })
@@ -81,6 +73,10 @@
       // 窗口大小改变时重新初始化画布
       this.$nextTick(() => {
         this.initCanvas()
+        // 如果是实验员,重新加载保存的签名
+        if ((this.roleType === 4 || this.roleType == 3) && this.savedSignature) {
+          this.loadSavedSignature()
+        }
       })
     },
     initCanvas() {
@@ -90,11 +86,11 @@
       this.context.lineWidth = 2
       this.context.lineCap = 'round'
       this.context.lineJoin = 'round'
-      
+
       // 清空画布并绘制虚线边框
       this.clearCanvas()
     },
-    
+
     drawDashedBorder() {
       const ctx = this.context
       ctx.setLineDash([5, 5])
@@ -113,18 +109,19 @@
 
     draw(event) {
       if (!this.isDrawing) return
-      
+
       const rect = this.$refs.signatureCanvas.getBoundingClientRect()
       const x = event.clientX - rect.left
       const y = event.clientY - rect.top
-      
+
       this.context.beginPath()
       this.context.moveTo(this.lastX, this.lastY)
       this.context.lineTo(x, y)
       this.context.stroke()
-      
+
       this.lastX = x
       this.lastY = y
+      this.hasDrawn = true
     },
 
     handleTouchStart(event) {
@@ -139,19 +136,20 @@
     handleTouchMove(event) {
       event.preventDefault()
       if (!this.isDrawing) return
-      
+
       const touch = event.touches[0]
       const rect = this.$refs.signatureCanvas.getBoundingClientRect()
       const x = touch.clientX - rect.left
       const y = touch.clientY - rect.top
-      
+
       this.context.beginPath()
       this.context.moveTo(this.lastX, this.lastY)
       this.context.lineTo(x, y)
       this.context.stroke()
-      
+
       this.lastX = x
       this.lastY = y
+      this.hasDrawn = true
     },
 
     stopDrawing() {
@@ -161,33 +159,111 @@
     clearCanvas() {
       this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
       this.drawDashedBorder()
+      this.hasDrawn = false
     },
 
     confirmSignature() {
       const canvas = this.$refs.signatureCanvas
       const ctx = this.context
-      
+
+      // 校验是否签名
+      if (this.isCanvasBlank()) {
+        this.$message && this.$message.warning('请先确认签名')
+        return
+      }
+
       // 保存当前画布内容
       const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
-      
+
       // 先填充背景色
       ctx.fillStyle = 'rgba(239, 248, 250, 1)'
       ctx.fillRect(0, 0, canvas.width, canvas.height)
-      
+
       // 创建一个临时画布来保存签名内容
       const tempCanvas = document.createElement('canvas')
       tempCanvas.width = canvas.width
       tempCanvas.height = canvas.height
       const tempCtx = tempCanvas.getContext('2d')
       tempCtx.putImageData(imageData, 0, 0)
-      
+
       // 将签名内容绘制到主画布上
       ctx.drawImage(tempCanvas, 0, 0)
-      
-      // 导出图片
-      const signatureImage = canvas.toDataURL('image/png')
-      this.$emit('confirm', 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg')
-    }
+      // 导出图片为base64
+      const base64Data = canvas.toDataURL('image/png');
+
+      // 如果是实验员,保存签名到sessionStorage
+      if (this.roleType == 4 || this.roleType == 3) {
+        // 保存当前画布内容(包括背景色)
+        // 保存到sessionStorage
+        sessionStorage.setItem('experimenterSignature', base64Data)
+      }
+
+      // base64转blob
+      const blob = this.dataURLtoBlob(base64Data);
+      // 新增:生成带时间戳的文件名
+      const timestamp = Date.now();
+      const fileName = `signature_${timestamp}.png`;
+      const file = new File([blob], fileName, { type: blob.type });
+      // 上传
+      customUploadRequest({
+        file,
+        onSuccess: (res) => {
+          const url = getUploadedFilePath(res)
+          if (!url) {
+            this.$message.error('上传接口未返回文件地址')
+            return
+          }
+          editSignPicture({ signPicture: url }).then(result => {
+            if (result.code == 200) {
+              this.$message.success('签名成功');
+              this.$emit('confirm', url);
+            }
+          })
+        },
+        onError: (err) => {
+          this.$message && this.$message.error ? this.$message.error('上传签名失败') : alert('上传签名失败');
+        }
+      });
+    },
+    // 加载保存的签名到画布(允许修改)
+    loadSavedSignature() {
+      const savedData = sessionStorage.getItem('experimenterSignature');
+      console.log('savedData:,', savedData)
+      if (savedData) {
+        const canvas = this.$refs.signatureCanvas
+        const ctx = this.context
+        const img = new Image()
+        img.onload = () => {
+          // 清空画布
+          ctx.clearRect(0, 0, canvas.width, canvas.height)
+          // 绘制保存的签名
+          ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
+          // 重新绘制虚线边框
+          this.drawDashedBorder()
+          this.hasDrawn = true
+          this.savedSignature = savedData
+          // 不锁定画布,允许修改
+        }
+        img.src = savedData
+      }
+    },
+    // 新增:base64转blob
+    dataURLtoBlob(dataurl) {
+      const arr = dataurl.split(',');
+      const mime = arr[0].match(/:(.*?);/)[1];
+      const bstr = atob(arr[1]);
+      let n = bstr.length;
+      const u8arr = new Uint8Array(n);
+      while (n--) {
+        u8arr[n] = bstr.charCodeAt(n);
+      }
+      return new Blob([u8arr], { type: mime });
+    },
+
+    // 新增方法:判断画布是否为空白
+    isCanvasBlank() {
+      return !this.hasDrawn
+    },
   },
   beforeDestroy() {
     // 组件销毁前移除监听
@@ -201,6 +277,7 @@
   :deep(.el-dialog__body) {
     padding: 0;
   }
+
   :deep(.el-dialog) {
     margin-top: 10vh !important;
   }
@@ -209,12 +286,12 @@
 .signature-container {
   background: #fff;
   border-radius: 4px;
-  
+
   .signature-content {
     padding: 20px;
     display: flex;
     justify-content: center;
-    
+
     canvas {
       border-radius: 4px;
       background: rgba(239, 248, 250, 1);
@@ -222,16 +299,17 @@
       height: 100%;
     }
   }
-  
+
   .signature-footer {
     padding: 20px;
     border-top: 1px solid #dcdfe6;
     display: flex;
     justify-content: flex-end;
     gap: 12px;
-    button{
+
+    button {
       width: 150px;
     }
   }
 }
-</style> 
\ No newline at end of file
+</style>

--
Gitblit v1.7.1