From a4e026b838ebcedde033e48adae2829157a7fd23 Mon Sep 17 00:00:00 2001 From: LiuJiaNan <15703339975@163.com> Date: Sat, 15 Nov 2025 11:39:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9ESignature=E7=AD=BE=E5=AD=97?= =?UTF-8?q?=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/FormBuilder/FormBuilder.js | 2 +- components/Signature/index.d.ts | 24 ++++++++ components/Signature/index.js | 87 +++++++++++++++++++++++++++ package.json | 3 +- utils/index.d.ts | 5 ++ utils/index.js | 17 ++++++ 6 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 components/Signature/index.d.ts create mode 100644 components/Signature/index.js diff --git a/components/FormBuilder/FormBuilder.js b/components/FormBuilder/FormBuilder.js index 8d63e89..1b85b0b 100644 --- a/components/FormBuilder/FormBuilder.js +++ b/components/FormBuilder/FormBuilder.js @@ -59,12 +59,12 @@ const FormBuilder = (props) => { {submitButtonText} )} + {extraActionButtons} {showCancelButton && ( )} - {extraActionButtons} )} diff --git a/components/Signature/index.d.ts b/components/Signature/index.d.ts new file mode 100644 index 0000000..4ba402a --- /dev/null +++ b/components/Signature/index.d.ts @@ -0,0 +1,24 @@ +import type { FC } from "react"; + +export interface SignatureValue { + /** 签字时间,YYYY-MM-DD HH:mm:ss */ + time: string; + /** 签字图片的base64编码 */ + base64: string; +} + +export interface SignatureProps { + /** 确认签字回调 */ + onConfirm: (value: SignatureValue) => void; + /** 签字区域宽度,默认为 752 */ + width?: number; + /** 签字区域高度,默认为 300 */ + height?: number; +} + +/** + * 签字组件 + */ +declare const Signature: FC; + +export default Signature; diff --git a/components/Signature/index.js b/components/Signature/index.js new file mode 100644 index 0000000..4d2e7e2 --- /dev/null +++ b/components/Signature/index.js @@ -0,0 +1,87 @@ +import { Button, Image, message, Modal } from "antd"; +import dayjs from "dayjs"; +import { useRef, useState } from "react"; +import SignatureCanvas from "react-signature-canvas"; +import { base642File } from "../../utils"; + +/** + * 签字组件 + */ +function Signature(props) { + const { + onConfirm, + width = 752, + height = 300, + ...restProps + } = props; + + const [signatureModalOpen, setSignatureModalOpen] = useState(false); + const signatureCanvas = useRef(null); + const [base64, setBase64] = useState(""); + + const onOk = () => { + if (signatureCanvas.current.isEmpty()) { + message.warning("请签名"); + return; + } + const base64 = signatureCanvas.current.toDataURL(); + setBase64(base64); + onConfirm({ + time: dayjs().format("YYYY-MM-DD HH:mm:ss"), + base64, + file: base642File(base64), + }); + signatureCanvas.current.clear(); + setSignatureModalOpen(false); + }; + + return ( + <> +
+ +
+ {base64 && ( +
+ +
+ )} + setSignatureModalOpen(false)} + footer={[ + , + , + , + ]} + > +
+ +
+
+ + ); +} + +export default Signature; diff --git a/package.json b/package.json index e4d5ab8..1734989 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "dayjs": "^1.11.18", "lodash-es": "^4.17.21", "react": "^18.3.1", - "react-pdf": "^10.2.0" + "react-pdf": "^10.2.0", + "react-signature-canvas": "^1.1.0-alpha.2" } } diff --git a/utils/index.d.ts b/utils/index.d.ts index 16abcf4..d2fbfe6 100644 --- a/utils/index.d.ts +++ b/utils/index.d.ts @@ -261,6 +261,11 @@ export function getIndexColumn(pagination: false | BasePaginationConfig): { */ export function getFileUrl(): string; +/** + * base64转File对象 + */ +export function base642File(base64: string, filename?: string): File; + /** * 获取树形节点路径 */ diff --git a/utils/index.js b/utils/index.js index 3b3eb11..bfc6421 100644 --- a/utils/index.js +++ b/utils/index.js @@ -61,6 +61,23 @@ export function image2Base642(file) { }); } +/** + base64转File对象 + */ +export function base642File(base64, filename = "file") { + const arr = base64.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 File([u8arr], filename, { type: mime }); +} + /** * 判断图片是否可访问成功 */