<template> <view class="page"> <VNavigationBar background-color="rgba(0,0,0,0)" title="客户签名" title-color="#333"></VNavigationBar> <view class="container"> <view class="instruction"> 确定维修项目无误后请客户签字确认 </view> <canvas canvas-id="signatureCanvas" class="canvas" :disable-scroll="true" @touchstart="startSign" @touchmove="drawSign" @touchend="endSign" ></canvas> <view class="buttons"> <button @click="clearSign">清除</button> <button @click="saveSign">保存</button> </view> </view> </view> </template> <script> import upload from "@/utils/upload"; import VNavigationBar from "@/components/VNavigationBar.vue"; import request from "@/utils/request"; export default { components: { VNavigationBar }, data() { return { context: null, // Canvas上下文 isSigning: false, // 是否正在签名中 data: {} }; }, onLoad(data) { // 获取 canvas 上下文 this.context = uni.createCanvasContext("signatureCanvas", this); this.context.fillStyle = "white"; if (data.data) { console.log('传递过来的内容', JSON.parse(data.data)); this.data = JSON.parse(data.data); } }, methods: { // 开始签名 startSign(e) { const { x, y } = e.touches[0]; this.context.moveTo(x, y); this.context.beginPath(); this.isSigning = true; }, // 签名进行中 drawSign(e) { if (!this.isSigning) return; const { x, y } = e.touches[0]; this.context.lineTo(x, y); this.context.setStrokeStyle("#000000"); // 设定笔触颜色 this.context.setLineWidth(2); // 设定线条宽度 this.context.setLineCap("round"); // 圆形笔触 this.context.stroke(); // 实线 this.context.draw(true); // 连续绘制 }, // 结束签名 endSign() { this.isSigning = false; }, // 清除签名 clearSign() { this.context.clearRect(0, 0, 750, 750); // 清空 Canvas this.context.draw(); }, // 保存签名 saveSign() { uni.canvasToTempFilePath({ canvasId: "signatureCanvas", success: (res) => { const tempFilePath = res.tempFilePath; uni.showToast({ title: "签名已保存", icon: "success", }); upload({ url: '/admin-api/common/upload', filePath: tempFilePath, }).then((res) => { console.log('服务器返回图片地址', res); this.data.image = res.data.url; console.log('提交的内容', this.data); request({ url: '/admin-api/repair/tickets/create', method: 'POST', data: this.data }).then(res => { uni.showToast({ title: '创建工单成功', icon: 'success' }); uni.navigateTo({ url: `/pages-order/orderDetail/orderDetail?id=${res.data.id}&isDetail=0` }); }); }); }, fail: (err) => { console.log("保存签名失败:", err); }, }); }, }, }; </script> <style> .page { display: flex; flex-direction: column; height: 100vh; background-color: #f5f5f5; } .VNavigationBar { padding: 20rpx; display: flex; align-items: center; justify-content: center; z-index: 10; position: relative; } .container { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20rpx; background-color: #f5f5f5; } .instruction { font-size: 32rpx; color: #333; margin-bottom: 20rpx; text-align: center; } .canvas { width: 100%; height: 600rpx; /* 加宽画布高度以适配横屏 */ border: 1px solid #ccc; border-radius: 10rpx; box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1); margin-bottom: 20rpx; background-color: #fff; } .buttons { display: flex; gap: 10rpx; margin-top: 20rpx; } button { padding: 15rpx 30rpx; background-color: #007aff; color: #fff; border: none; border-radius: 5rpx; font-size: 28rpx; box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1); transition: background-color 0.3s ease; } button:hover { background-color: #0066cc; } button:active { background-color: #0055aa; } </style>