2025-11-15 11:39:20 +08:00
|
|
|
import { Button, Image, message, Modal } from "antd";
|
|
|
|
|
import dayjs from "dayjs";
|
2025-11-15 17:13:57 +08:00
|
|
|
import { useEffect, useRef, useState } from "react";
|
2025-11-15 11:39:20 +08:00
|
|
|
import SignatureCanvas from "react-signature-canvas";
|
|
|
|
|
import { base642File } from "../../utils";
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 签字组件
|
|
|
|
|
*/
|
|
|
|
|
function Signature(props) {
|
|
|
|
|
const {
|
|
|
|
|
onConfirm,
|
|
|
|
|
width = 752,
|
|
|
|
|
height = 300,
|
2025-11-15 17:13:57 +08:00
|
|
|
url = "",
|
2025-11-15 11:39:20 +08:00
|
|
|
...restProps
|
|
|
|
|
} = props;
|
|
|
|
|
|
|
|
|
|
const [signatureModalOpen, setSignatureModalOpen] = useState(false);
|
|
|
|
|
const signatureCanvas = useRef(null);
|
|
|
|
|
const [base64, setBase64] = useState("");
|
2025-11-15 17:13:57 +08:00
|
|
|
useEffect(() => {
|
|
|
|
|
setBase64(url);
|
|
|
|
|
}, [url]);
|
2025-11-15 11:39:20 +08:00
|
|
|
|
|
|
|
|
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 (
|
|
|
|
|
<>
|
|
|
|
|
<div>
|
|
|
|
|
<Button
|
|
|
|
|
type="primary"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setSignatureModalOpen(true);
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{base64 ? "重新签字" : "手写签字"}
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
{base64 && (
|
|
|
|
|
<div style={{ border: "1px dashed #d9d9d9", width, height, marginTop: 16 }}>
|
2025-11-15 17:13:57 +08:00
|
|
|
<Image src={base64} style={{ width, height, objectFit: "contain" }} />
|
2025-11-15 11:39:20 +08:00
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
<Modal
|
|
|
|
|
title="签字"
|
|
|
|
|
width={800}
|
|
|
|
|
open={signatureModalOpen}
|
|
|
|
|
onCancel={() => setSignatureModalOpen(false)}
|
|
|
|
|
footer={[
|
|
|
|
|
<Button key="clear" onClick={() => signatureCanvas.current.clear()}>重签</Button>,
|
|
|
|
|
<Button
|
|
|
|
|
key="cancel"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setSignatureModalOpen(false);
|
|
|
|
|
signatureCanvas.current.clear();
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
取消
|
|
|
|
|
</Button>,
|
|
|
|
|
<Button key="ok" type="primary" onClick={onOk}>确定</Button>,
|
|
|
|
|
]}
|
|
|
|
|
>
|
|
|
|
|
<div style={{ border: "1px dashed #d9d9d9" }}>
|
|
|
|
|
<SignatureCanvas
|
|
|
|
|
ref={signatureCanvas}
|
|
|
|
|
penColor="black"
|
|
|
|
|
canvasProps={{ width, height }}
|
|
|
|
|
{...restProps}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</Modal>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default Signature;
|