张延森 3 лет назад
Родитель
Сommit
6d7827bd49

+ 1
- 1
package.json Просмотреть файл

@@ -64,7 +64,7 @@
64 64
     "md5": "^2.3.0",
65 65
     "moment": "^2.29.1",
66 66
     "omit.js": "^2.0.2",
67
-    "qrcodejs2": "^0.0.2",
67
+    "qrcode": "^1.5.0",
68 68
     "rc-menu": "^9.1.0",
69 69
     "rc-util": "^5.16.0",
70 70
     "react": "^17.0.0",

+ 59
- 5
src/components/QRCode/index.jsx Просмотреть файл

@@ -1,9 +1,63 @@
1
-import React from 'react'
1
+import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useImperativeHandle } from 'react'
2
+import classNames from 'classnames'
3
+import QRCode from 'qrcode'
4
+import html2canvas from 'html2canvas'
5
+import styles from './style.less'
6
+
7
+export default forwardRef((props, ref) => {
8
+  const { className, width = 430, border, content, title, fileName, onError } = props
9
+
10
+  const rootRef = useRef()
11
+  const canvasRef = useRef()
12
+
13
+  const { style1, style2 } = useMemo(() => {
14
+    return {
15
+      style1: {
16
+        border: border ? '2px solid rgba(0,0,0)' : 'none',
17
+        borderRadius: border ? '8px' : 'none'
18
+      },
19
+      style2: {
20
+        width: `${width}px`,
21
+        height: `${width}px`,
22
+      }
23
+    }
24
+  }, [width, border])
25
+
26
+  const qrOption = useMemo(() => ({
27
+    margin: 0,
28
+    width: width,
29
+    errorCorrectionLevel: 'M'
30
+  }), [width])
31
+
32
+  useEffect(() => {
33
+    if (content) {
34
+      QRCode.toCanvas(canvasRef.current, content, qrOption, onError)
35
+    }
36
+  }, [content, qrOption, onError])
37
+
38
+  useImperativeHandle(ref, () => ({
39
+    download: () => {
40
+      return new Promise((resolve, reject) => {
41
+        html2canvas(rootRef.current).then((canvas) => {
42
+          const imageData = canvas.toDataURL('image/png', .8);
43
+          const link = document.createElement('a');
44
+          link.download = `${fileName || 'qrcode'}.png`
45
+          link.href = imageData
46
+          link.click()
47
+          resolve()
48
+        }).catch(reject)
49
+      })
50
+    }
51
+  }), [fileName])
2 52
 
3
-export default (props) => {
4 53
   return (
5
-    <div>
6
-      <div></div>
54
+    <div className={classNames(className, styles['qrcode-box'])} ref={rootRef}>
55
+      <div className={styles['qrcode-container']} style={style1}>
56
+        <canvas ref={canvasRef} style={style2}/>
57
+      </div>
58
+      {
59
+        title && <h3>{title}</h3>
60
+      }
7 61
     </div>
8 62
   )
9
-}
63
+})

+ 18
- 0
src/components/QRCode/style.less Просмотреть файл

@@ -0,0 +1,18 @@
1
+
2
+.qrcode-box {
3
+  display: flex;
4
+  align-items: center;
5
+  justify-content: center;
6
+  flex-direction: column;
7
+
8
+  .qrcode-container {
9
+    padding: 16px;
10
+    flex: none;
11
+  }
12
+
13
+  h3 {
14
+    font-size: 18px;
15
+    font-weight: bold;
16
+    line-height: 3em;
17
+  }
18
+}

+ 5
- 27
src/components/RightContent/QrCode/QrCode.jsx Просмотреть файл

@@ -1,43 +1,21 @@
1 1
 import React, {useState, useRef, useEffect, useCallback} from 'react'
2 2
 import { useModel } from 'umi'
3 3
 import { Button, Spin } from 'antd';
4
-import QRCode from 'qrcodejs2'
4
+import QRCode from '@/components/QRCode'
5 5
 import styles from './style.less';
6 6
 
7 7
 export default (props) => {
8 8
   const { initialState } = useModel('@@initialState');
9 9
   const [isLoading, setLoading] = useState(false);
10
+
10 11
   const qrcodeRef = useRef()
11
-  const linkRef = useRef()
12 12
 
13 13
   const downloadQrcode = useCallback(() => {
14
-    if (linkRef.current) {
15
-      linkRef.current.click();
14
+    if (qrcodeRef.current) {
15
+      qrcodeRef.current.download();
16 16
     }
17 17
   }, [])
18 18
 
19
-
20
-  useEffect(() => {
21
-    // 初始化二维码
22
-    const qrcode = new QRCode(qrcodeRef.current, {
23
-      width: 200,
24
-      height: 200, // 高度
25
-      text: initialState.report_url
26
-    })
27
-
28
-    const canvas = qrcodeRef.current.querySelector('canvas')
29
-
30
-    // 创建下载链接
31
-    const aElement = document.createElement('a');
32
-    linkRef.current = aElement;
33
-    linkRef.current.download = 'qrcode.png'
34
-
35
-    // 构造链接地址
36
-    setLoading(true);
37
-    linkRef.current.href = canvas.toDataURL('image/jpg')
38
-    setLoading(false);
39
-  }, [])
40
-
41 19
   return isLoading ?
42 20
     <Spin
43 21
       size="small"
@@ -49,7 +27,7 @@ export default (props) => {
49 27
   : (
50 28
       <div className={styles.qrcodebox}>
51 29
         <p>疫情监测结果表入口</p>
52
-        <div ref={qrcodeRef} />
30
+        <QRCode ref={qrcodeRef} width={200} content={initialState.report_url} />
53 31
         <p><Button onClick={downloadQrcode}>下载</Button></p>
54 32
       </div>
55 33
     )

+ 7
- 19
src/pages/org/org/Edit.jsx Просмотреть файл

@@ -1,9 +1,9 @@
1
-import React, { useEffect, useState, useCallback, useRef } from 'react'
1
+import React, { useEffect, useState, useCallback, useRef, useMemo } from 'react'
2 2
 import { useModel } from 'umi'
3 3
 import { Form, Input, Button, message } from 'antd';
4 4
 import ProCard from '@ant-design/pro-card';
5 5
 import { PageHeaderWrapper } from '@ant-design/pro-layout';
6
-import QRCode from 'qrcodejs2'
6
+import QRCode from '@/components/QRCode'
7 7
 import md5 from 'md5';
8 8
 import { getDetail, saveOrg, updateOrg, saveOrgUser, getOrgAdminDetail } from '@/services/org';
9 9
 
@@ -16,17 +16,18 @@ export default (props) => {
16 16
   const [formData, setFormData] = useState()
17 17
   const [loading, setLoading] = useState(false)
18 18
   const qrcodeRef = useRef()
19
-  const linkRef = useRef()
19
+  const qrcodeText = useMemo(() => initialState.report_url + '#resume-work-form?org=' + id, [id, initialState.report_url])
20 20
 
21 21
   const [adminForm] = Form.useForm();
22 22
   const [adminFormData, setAdminFormData] = useState()
23 23
   const [adminLoading, setAdminLoading] = useState(false)
24 24
 
25 25
   const downloadQrcode = useCallback(() => {
26
-    if (linkRef.current) {
27
-      linkRef.current.click();
26
+    if (qrcodeRef.current) {
27
+      qrcodeRef.current.download();
28 28
     }
29 29
   }, [])
30
+
30 31
   const onFinish = (values) => {
31 32
     setLoading(true)
32 33
     if (id) {
@@ -72,19 +73,6 @@ export default (props) => {
72 73
       getDetail(id).then(res => {
73 74
         setFormData(res);
74 75
         form.setFieldsValue(res);
75
-
76
-        // 初始化二维码
77
-        const qrcode = new QRCode(qrcodeRef.current, {
78
-          width: 160,
79
-          height: 160, // 高度
80
-          text: initialState.report_url + '#resume-work-form?org=' + id
81
-        })
82
-        const canvas = qrcodeRef.current.querySelector('canvas')
83
-        // 创建下载链接
84
-        const aElement = document.createElement('a');
85
-        linkRef.current = aElement;
86
-        linkRef.current.download = res.orgName + '.png'
87
-        linkRef.current.href = canvas.toDataURL('image/jpg')
88 76
       })
89 77
       getOrgAdminDetail(id).then((res) => {
90 78
         setAdminFormData(res);
@@ -124,7 +112,7 @@ export default (props) => {
124 112
               </Form.Item>
125 113
               {
126 114
                 id && <Form.Item label=' ' colon={false} wrapperCol={{ offset: 3 }}>
127
-                  <div ref={qrcodeRef} />
115
+                  <QRCode ref={qrcodeRef} border width={200} content={qrcodeText} title={formData?.orgName} fileName={formData?.orgName} />
128 116
                 </Form.Item>
129 117
               }
130 118
               <Form.Item label=' ' colon={false} >