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