import React, { useState, useRef } from ‘react‘;
import { QrcodeOutlined } from ‘@ant-design/icons‘;
import ‘@ant-design/compatible/assets/index.css‘;
import { Modal, Button, message } from ‘antd‘;
import { useObserver } from ‘mobx-react‘;
import { useHistory, useLocation } from ‘react-router-dom‘;
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
import QrCode from ‘qrcode-reader‘;
import jsQR from ‘jsqr‘;
import ajax from ‘@/lib/axios‘;
import { Wrapper, SuccessWrapper, UploadImgWrapper } from ‘./link-qrcode-style‘;
interface IProps {
merchantId: string;
branchName: string;
merchantName: string;
personInCharge: string;
}
const LinkQrCode = (props: IProps) => {
const qr = new QrCode();
const [showConfirmModal, setShowConfirmModal] = useState<boolean>(false);
const [showSuccessModal, setShowSuccessModal] = useState<boolean>(false);
const [showUploadModal, setShowUploadModal] = useState<boolean>(false);
const [uploadButtonLoading, setUploadButtonLoading] = useState<boolean>(false);
const [confirmButtonLoading, setConfirmButtonLoading] = useState<boolean>(false);
const [qrCodeUrl, setQrCodeUrl] = useState<string>(‘‘);
const [qrDecode, setQrDecode] = useState<string>(‘‘);
const [uploadImgUrl, setUploadImgUrl] = useState<string>(‘‘);
const [uploadImgFile, setUploadImgFile] = useState<object>({});
const history = useHistory();
const location = useLocation();
const fileInputRef = useRef<HTMLInputElement>(null);
// const ua = navigator.userAgent.toLowerCase();
// const isIos = ua.indexOf(‘iphone‘) !== -1 || ua.indexOf(‘ipad‘) !== -1;
const backToListPage = () => {
const to = `${location.pathname}${location.search}`;
history.push(to);
};
const getFileUrl = (file: object) => {
if (file === undefined) return;
let url = null;
if ((window as any).createObjectURL != undefined) {
// basic
url = (window as any).createObjectURL(file);
} else if (window.URL != undefined) {
// mozilla(firefox)
url = window.URL.createObjectURL(file);
} else if (window.webkitURL != undefined) {
// webkit or chrome
url = window.webkitURL.createObjectURL(file);
}
return url;
};
const getQrCode = () => {
console.log(‘beibei111‘, uploadImgFile);
qr.decode(uploadImgUrl);
qr.callback = async function(error: any, resCode: any) {
if (error) {
Modal.error({
content: error,
});
return;
}
const decodeArr = resCode.result.split(‘/‘);
const cutQrDecode = decodeArr[decodeArr.length - 1];
console.log(‘beibei1113333‘, resCode.result, cutQrDecode, uploadImgFile);
setQrDecode(cutQrDecode);
// 请求后端接口进行解析
try {
const {
data: { data },
} = await ajax.get(`/qrcode/validate/${cutQrDecode}`);
console.log(‘beibei 是否有效‘, data);
setUploadButtonLoading(false);
setShowUploadModal(false);
if (data) {
setShowConfirmModal(true);
} else {
Modal.error({
content: "Sorry, we can‘t process this picture, please make sure you use a clear picture of valid QR code.",
onOk() {
const to = `${location.pathname}${location.search}`;
history.push(to);
},
});
}
} catch (e) {
message.error(e.message);
}
};
};
const handleLinkButton = (e: React.MouseEvent) => {
e.preventDefault();
if (!!fileInputRef) {
(fileInputRef as any).current.click();
}
};
const handleFileChange = (e: any) => {
const files = e.target.files;
if (files[0] !== undefined) {
const fr = new FileReader();
fr.readAsDataURL(files[0]);
fr.addEventListener(‘load‘, () => {
setUploadImgUrl(fr.result as string);
setUploadImgFile(files[0]);
setShowUploadModal(true);
// qrCodeUploadedHandler(fr.result as string);
drawImg(files[0]);
});
} else {
setUploadImgUrl(‘‘);
setUploadImgFile({});
}
};
const drawImg = (file: any) => {
createImageBitmap(file).then(bmp => {
const canvas = document.createElement(‘canvas‘);
const width: number = bmp.width;
const height: number = bmp.height;
canvas.width = bmp.width;
canvas.height = bmp.height;
const ctx = canvas.getContext(‘2d‘) as any;
ctx.drawImage(bmp, 0, 0);
const qrCodeImageFormat = ctx.getImageData(0, 0, bmp.width, bmp.height);
const qrDecoded = jsQR(qrCodeImageFormat.data, qrCodeImageFormat.width, qrCodeImageFormat.height);
alert(qrDecoded.data);
console.log(‘beibeicccmmmmm‘, qrCodeImageFormat, qrDecoded);
});
};
const qrCodeUploadedHandler = (fileImageUrl: string) => {
const img = new Image();
// img.src = fileImageUrl;
img.onload = () => {
const canvas = document.createElement(‘canvas‘);
const originWidth = img.width;
const originHeight = img.height;
// const maxWidth = 1600;
// const maxHeight = 1200;
// let targetWidth = originWidth;
// let targetHeight = originHeight;
// if (originWidth > maxWidth || originHeight > maxHeight) {
// if (originWidth / originHeight > maxWidth / maxHeight) {
// // 更宽,按照宽度限定尺寸
// targetWidth = maxWidth;
// targetHeight = Math.round(maxWidth * (originHeight / originWidth));
// } else {
// targetHeight = maxHeight;
// targetWidth = Math.round(maxHeight * (originWidth / originHeight));
// }
// };
// canvas对图片进行缩放
canvas.width = originWidth;
canvas.height = originHeight;
const context = canvas.getContext(‘2d‘) as any;
// 清除画布
// context.clearRect(0, 0, targetWidth, targetHeight);
// 图片压缩
context.drawImage(img, 0, 0);
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
const code = jsQR(imageData.data, imageData.width, imageData.height);
console.log(‘beibeiccc222‘, imageData, code);
canvas.remove();
};
img.onerror = () => console.error(‘Upload file of image format please.‘);
img.src = fileImageUrl;
};
const handleUploadButton = (e: React.MouseEvent) => {
e.preventDefault();
setUploadButtonLoading(true);
getQrCode();
};
const handleConfirmLink = async (e: React.MouseEvent) => {
e.preventDefault();
setConfirmButtonLoading(true);
try {
const {
data: { data },
} = await ajax.post(‘/qrcode/bind‘, { qrcode: qrDecode, bindObjectId: props.merchantId });
if (data.length > 0) {
setQrCodeUrl(data[0]);
setConfirmButtonLoading(false);
setShowConfirmModal(false);
setShowSuccessModal(true);
}
} catch (e) {
message.error(e.message);
}
};
const handleConfirmModalCancel = (e: React.MouseEvent) => {
e.preventDefault();
setShowConfirmModal(false);
backToListPage();
};
const handleSuccessModalCancel = (e: React.MouseEvent) => {
e.preventDefault();
setShowSuccessModal(false);
backToListPage();
};
return useObserver(() => (
<>
<div>
<Button onClick={handleLinkButton} style={{ width: ‘100%‘, marginTop: 5 }} type="default" size="small">
<QrcodeOutlined />
Link QR code
</Button>
<input
type="file"
name="cover"
accept="image/*"
ref={fileInputRef}
style={{ width: 0, height: 0 }}
onChange={handleFileChange}
/>
</div>
<Modal
destroyOnClose={true}
title="Confirm Information"
visible={showConfirmModal}
style={{ top: 20 }}
width={‘50%‘}
maskClosable={false}
footer={[
<Button
type="primary"
key="confirm"
loading={confirmButtonLoading}
htmlType="button"
onClick={handleConfirmLink}>
Confirm
</Button>,
<Button key="cancel" htmlType="button" onClick={handleConfirmModalCancel}>
Cancel
</Button>,
]}
onCancel={handleConfirmModalCancel}>
<Wrapper>
<p>
{/* eslint-disable-next-line react/no-unescaped-entities */}
You‘re linking the QR code you scaned to the following merchant. Please check the merchant information
throughly.
</p>
<div className="confirm-information">
<div className="confirm-information-item">
<span>Merchant ID:</span>
<p>{props.merchantId}</p>
</div>
<div className="confirm-information-item">
<span>Branch Name:</span>
<p>{props.branchName}</p>
</div>
<div className="confirm-information-item">
<span>Merchant Name:</span>
<p>{props.merchantName}</p>
</div>
<div className="confirm-information-item">
<span>Person in Charge:</span>
<p>{props.personInCharge}</p>
</div>
</div>
</Wrapper>
</Modal>
<Modal
destroyOnClose={true}
visible={showSuccessModal}
style={{ top: 20 }}
width={‘50%‘}
maskClosable={false}
footer={null}
onCancel={handleSuccessModalCancel}>
<SuccessWrapper>
<p className="top-tip">QR code has been successfully linked!</p>
<div className="branch-name">
<span>Branch Name:</span>
<p>{props.branchName}</p>
</div>
<div className="qr-code">
<span>QR Code:</span>
<img src={qrCodeUrl} alt="图片加载失败" />
</div>
</SuccessWrapper>
</Modal>
<Modal
destroyOnClose={true}
visible={showUploadModal}
style={{ top: 20, textAlign: ‘center‘ }}
width={‘50%‘}
maskClosable={false}
closable={false}
footer={null}>
<UploadImgWrapper>
<img src={uploadImgUrl} style={{ maxWidth: ‘400px‘ }} />
</UploadImgWrapper>
<Button
type="primary"
key="confirm"
loading={uploadButtonLoading}
size="large"
htmlType="button"
style={{ margin: ‘20px‘ }}
onClick={handleUploadButton}>
UPLOAD
</Button>
</Modal>
</>
));
};
export default LinkQrCode;
原文:https://www.cnblogs.com/chenbeibei520/p/12526522.html