From e69cc83c653ce78691aad2eedd4c71ca70f559c4 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期三, 15 二月 2023 17:53:46 +0800
Subject: [PATCH] 2023-02-15

---
 public/options.json                                                   |   10 
 src/tabviews/custom/components/module/voucher/voucherTable/index.jsx  |   16 
 package-lock.json                                                     |  115 ++++++++++
 src/tabviews/custom/components/module/voucher/index.jsx               |   31 +-
 package.json                                                          |    1 
 src/tabviews/custom/components/module/voucher/printVoucher/index.jsx  |  354 ++++++++++++++++++++++++++++++++
 src/tabviews/custom/components/module/voucher/printVoucher/index.scss |  126 +++++++++++
 7 files changed, 624 insertions(+), 29 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index a469c79..f445383 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3158,6 +3158,12 @@
       "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
       "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw=="
     },
+    "@types/raf": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.0.tgz",
+      "integrity": "sha512-taW5/WYqo36N7V39oYyHP9Ipfd5pNFvGTIQsNGj86xV88YQ7GnI30/yMfKDF7Zgin0m3e+ikX88FvImnK4RjGw==",
+      "optional": true
+    },
     "@types/react": {
       "version": "16.9.2",
       "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.2.tgz",
@@ -5216,6 +5222,11 @@
         "node-int64": "^0.4.0"
       }
     },
+    "btoa": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz",
+      "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g=="
+    },
     "buffer": {
       "version": "4.9.1",
       "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
@@ -5407,6 +5418,45 @@
       "version": "1.0.30001399",
       "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001399.tgz",
       "integrity": "sha512-4vQ90tMKS+FkvuVWS5/QY1+d805ODxZiKFzsU8o/RsVJz49ZSRR8EjykLJbqhzdPgadbX6wB538wOzle3JniRA=="
+    },
+    "canvg": {
+      "version": "3.0.10",
+      "resolved": "https://registry.npmjs.org/canvg/-/canvg-3.0.10.tgz",
+      "integrity": "sha512-qwR2FRNO9NlzTeKIPIKpnTY6fqwuYSequ8Ru8c0YkYU7U0oW+hLUvWadLvAu1Rl72OMNiFhoLu4f8eUjQ7l/+Q==",
+      "optional": true,
+      "requires": {
+        "@babel/runtime": "^7.12.5",
+        "@types/raf": "^3.4.0",
+        "core-js": "^3.8.3",
+        "raf": "^3.4.1",
+        "regenerator-runtime": "^0.13.7",
+        "rgbcolor": "^1.0.1",
+        "stackblur-canvas": "^2.0.0",
+        "svg-pathdata": "^6.0.3"
+      },
+      "dependencies": {
+        "@babel/runtime": {
+          "version": "7.20.13",
+          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz",
+          "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==",
+          "optional": true,
+          "requires": {
+            "regenerator-runtime": "^0.13.11"
+          }
+        },
+        "core-js": {
+          "version": "3.28.0",
+          "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.28.0.tgz",
+          "integrity": "sha512-GiZn9D4Z/rSYvTeg1ljAIsEqFm0LaN9gVtwDCrKL80zHtS31p9BAjmTxVqTQDMpwlMolJZOFntUG2uwyj7DAqw==",
+          "optional": true
+        },
+        "regenerator-runtime": {
+          "version": "0.13.11",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
+          "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
+          "optional": true
+        }
+      }
     },
     "capture-exit": {
       "version": "2.0.0",
@@ -7025,6 +7075,12 @@
       "requires": {
         "domelementtype": "1"
       }
+    },
+    "dompurify": {
+      "version": "2.4.4",
+      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.4.tgz",
+      "integrity": "sha512-1e2SpqHiRx4DPvmRuXU5J0di3iQACwJM+mFGE2HAkkK7Tbnfk9WcghcAmyWc9CRrjyRRUpmuhPUH6LphQQR3EQ==",
+      "optional": true
     },
     "domutils": {
       "version": "1.7.0",
@@ -9504,6 +9560,11 @@
       "version": "4.2.1",
       "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz",
       "integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q=="
+    },
+    "fflate": {
+      "version": "0.4.8",
+      "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz",
+      "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA=="
     },
     "figgy-pudding": {
       "version": "3.5.1",
@@ -12699,6 +12760,42 @@
       "version": "0.0.0",
       "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
       "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM="
+    },
+    "jspdf": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/jspdf/-/jspdf-2.5.1.tgz",
+      "integrity": "sha512-hXObxz7ZqoyhxET78+XR34Xu2qFGrJJ2I2bE5w4SM8eFaFEkW2xcGRVUss360fYelwRSid/jT078kbNvmoW0QA==",
+      "requires": {
+        "@babel/runtime": "^7.14.0",
+        "atob": "^2.1.2",
+        "btoa": "^1.2.1",
+        "canvg": "^3.0.6",
+        "core-js": "^3.6.0",
+        "dompurify": "^2.2.0",
+        "fflate": "^0.4.8",
+        "html2canvas": "^1.0.0-rc.5"
+      },
+      "dependencies": {
+        "@babel/runtime": {
+          "version": "7.20.13",
+          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz",
+          "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==",
+          "requires": {
+            "regenerator-runtime": "^0.13.11"
+          }
+        },
+        "core-js": {
+          "version": "3.28.0",
+          "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.28.0.tgz",
+          "integrity": "sha512-GiZn9D4Z/rSYvTeg1ljAIsEqFm0LaN9gVtwDCrKL80zHtS31p9BAjmTxVqTQDMpwlMolJZOFntUG2uwyj7DAqw==",
+          "optional": true
+        },
+        "regenerator-runtime": {
+          "version": "0.13.11",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
+          "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
+        }
+      }
     },
     "jsprim": {
       "version": "1.4.1",
@@ -18887,6 +18984,12 @@
       "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz",
       "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM="
     },
+    "rgbcolor": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz",
+      "integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==",
+      "optional": true
+    },
     "rimraf": {
       "version": "2.7.1",
       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
@@ -19982,6 +20085,12 @@
       "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz",
       "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA=="
     },
+    "stackblur-canvas": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.5.0.tgz",
+      "integrity": "sha512-EeNzTVfj+1In7aSLPKDD03F/ly4RxEuF/EX0YcOG0cKoPXs+SLZxDawQbexQDBzwROs4VKLWTOaZQlZkGBFEIQ==",
+      "optional": true
+    },
     "stacktrace-parser": {
       "version": "0.1.10",
       "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz",
@@ -20260,6 +20369,12 @@
       "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.2.tgz",
       "integrity": "sha512-1gtApepKFweigFZj3sGO8KT8LvVZK8io146EzXrpVuWCDAbISz/yMucco3hWTkpZNoPabM+dnMOpy6Swue68Zg=="
     },
+    "svg-pathdata": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz",
+      "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==",
+      "optional": true
+    },
     "svgo": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.0.tgz",
diff --git a/package.json b/package.json
index 5ae1493..2f95956 100644
--- a/package.json
+++ b/package.json
@@ -61,6 +61,7 @@
     "jest-watch-typeahead": "0.3.1",
     "js-table2excel": "^1.0.3",
     "jsbarcode": "^3.11.3",
+    "jspdf": "^2.5.1",
     "jssha": "^3.2.0",
     "jszip": "^3.10.0",
     "md5": "^2.2.1",
diff --git a/public/options.json b/public/options.json
index bedcbee..4e405d0 100644
--- a/public/options.json
+++ b/public/options.json
@@ -1,12 +1,12 @@
 {
-  "appId": "202108312122504607B107A83F55B40C98CCF",
-  "appkey": "20210831212235413F287EC3BF489424496C8",
+  "appId": "201912040924165801464FF1788654BC5AC73",
+  "appkey": "20191106103859640976D6E924E464D029CF0",
   "mainSystemApi": "http://sso.mk9h.cn/cloud/webapi/dostars",
   "systemType": "",
   "externalDatabase": "",
   "lineColor": "",
   "filter": "false",
-  "defaultApp": "mkindustry",
+  "defaultApp": "mk",
   "defaultLang": "zh-CN",
   "WXAppID": "",
   "WXminiAppID": "",
@@ -17,6 +17,6 @@
   "transfer": "false",
   "keepPassword": "true",
   "platforms": ["H5", "wechat", "android", "ios", "wxMiniProgram"],
-  "host": "http://demo.mk9h.cn",
-  "service": "erp_new/"
+  "host": "http://qingqiumarket.cn",
+  "service": "MKWMS/"
 }
\ No newline at end of file
diff --git a/src/tabviews/custom/components/module/voucher/index.jsx b/src/tabviews/custom/components/module/voucher/index.jsx
index b5cef0f..a670376 100644
--- a/src/tabviews/custom/components/module/voucher/index.jsx
+++ b/src/tabviews/custom/components/module/voucher/index.jsx
@@ -12,8 +12,10 @@
 import ResetRemark from './resetRemark'
 import ResetAttach from './resetAttach'
 import LoadFromTemp from './loadFromTemp'
+import asyncComponent from '@/utils/asyncComponent'
 import './index.scss'
 
+const PrintVoucher = asyncComponent(() => import('./printVoucher'))
 const { confirm } = Modal
 
 class VoucherModule extends Component {
@@ -80,8 +82,8 @@
       }
     }
 
-    // config.wrap.type = 'checkVoucher'
-    // BID = '20230214130744811P0K95RQ155KG0QIQOFV'
+    config.wrap.type = 'checkVoucher'
+    BID = '20230214130744811P0K95RQ155KG0QIQOFV'
 
     // config.wrap.type = 'checkTemp'
     // BID = '20230214174458780MFR8IA576ON4VKNOLVH'
@@ -906,10 +908,6 @@
     })
   }
 
-  triggerprint = () => {
-
-  }
-
   dataChange = (data) => {
     this.setState({
       status: 'change',
@@ -926,12 +924,13 @@
       _val = parseInt(val)
     }
     
-    this.setState({attachments: _val})
+    this.setState({attachments: _val, status: 'change'})
   }
 
   changeVouDate = (val) => {
     const { type, status, saved } = this.state
-    this.setState({vouDate: val})
+
+    this.setState({vouDate: val, status: 'change'})
 
     if (type === 'createVoucher' && val && !saved && (status === 'empty' || status === 'change')) {
       this.updateVoucherChar(val)
@@ -1011,7 +1010,7 @@
       num = 0
     }
 
-    this.setState({attachlist: vals, attachments: num})
+    this.setState({status: 'change', attachlist: vals, attachments: num})
   }
 
   triggermore = () => {
@@ -1095,14 +1094,14 @@
   }
 
   render() {
-    const { type, status, loading, config, orgcode, typeOptions, tempTypes, charType, charInt, data, vouDate, username, remark, attachments, title, attachlist, tempTypeClass } = this.state
+    const { type, status, loading, config, orgcode, orgname, typeOptions, tempTypes, charType, charName, charInt, data, vouDate, username, remark, attachments, title, attachlist, tempTypeClass } = this.state
 
     return (
       <div className="menu-voucher-wrap" style={config.style}>
         {type === 'createVoucher' ? <div className="voucher-header">
           <Button className="add-background header-btn" disabled={status === 'empty'} onClick={() => this.triggersave('add')}>淇濆瓨骞舵柊澧�</Button>
           <Button className="add-background header-btn" disabled={status === 'empty' || status === 'saved'} onClick={() => this.triggersave()}>淇濆瓨</Button>
-          <Button className="print-background header-btn" disabled={status !== 'saved'} onClick={this.triggerprint}>鎵撳嵃</Button>
+          <PrintVoucher ID={config.uuid + 'print'} data={data} orgname={orgname} vouDate={vouDate} charName={charName} charInt={charInt} attachments={attachments} disabled={status !== 'saved'}/>
           <Dropdown overlay={<div className="mk-voucher-dropdown-wrap">
             <SaveAsTemp tempTypes={tempTypes} onChange={this.triggerTempsave}/>
             <div className="split"></div>
@@ -1113,29 +1112,29 @@
         </div> : null}
         {type === 'checkVoucher' ? <div className="voucher-header">
           <Button className="add-background header-btn" disabled={status === 'empty' || status === 'saved'} onClick={() => this.triggersave()}>淇濆瓨</Button>
-          <Button className="print-background header-btn" disabled={status !== 'saved'} onClick={this.triggerprint}>鎵撳嵃</Button>
+          <PrintVoucher ID={config.uuid + 'print'} data={data} orgname={orgname} vouDate={vouDate} charName={charName} charInt={charInt} attachments={attachments} disabled={status !== 'saved'}/>
           <Button className="out-background header-btn" onClick={this.triggerclose}>鍏抽棴</Button>
         </div> : null}
         <div className="voucher-body" style={{padding: `0px ${config.wrap.space || 0}px`}}>
           {type === 'createVoucher' || type === 'checkVoucher' ? <div className="pre-wrap">
             <div className="voucher-code">
-              <Select value={charType} dropdownClassName="mk-vcode-dropdown" onChange={(val, option) => this.setState({charType: val, charName: option.props.charName, charInt: option.props.charint})}>
+              <Select value={charType} dropdownClassName="mk-vcode-dropdown" onChange={(val, option) => this.setState({status: 'change', charType: val, charName: option.props.charName, charInt: option.props.charint})}>
                 {typeOptions.map(option =>
                   <Select.Option key={option.voucher_char_int} value={option.voucher_class} charName={option.voucher_char} charint={option.voucher_char_int}>{option.voucher_char}</Select.Option>
                 )}
               </Select>
-              <InputNumber precision={0} min={1} value={charInt} autoComplete="off" onChange={(val) => this.setState({charInt: val})}/> 鍙�
+              <InputNumber precision={0} min={1} value={charInt} autoComplete="off" onChange={(val) => this.setState({status: 'change', charInt: val})}/> 鍙�
             </div>
             <div className="voucher-date">
               鏃ユ湡锛�<DatePicker value={vouDate} onChange={this.changeVouDate}/>
             </div>
             <div className="voucher-text">
-              <Input value={title} placeholder="鍑瘉鏂囨湰" autoComplete="off" onChange={(e) => this.setState({title: e.target.value})}/>
+              <Input value={title} placeholder="鍑瘉鏂囨湰" autoComplete="off" onChange={(e) => this.setState({status: 'change', title: e.target.value})}/>
             </div>
             <div className="voucher-affix">
               闄勫崟鎹� <InputNumber precision={0} value={attachments || 0} autoComplete="off" onChange={this.changeAttach}/> 寮�
               <ResetAttach config={config} orgcode={orgcode} voucherCode={this.state.voucherCode} attachlist={attachlist} onChange={this.resetAttachList}/>
-              <ResetRemark remark={remark} ID={config.uuid + 'remark'} onChange={(val) => this.setState({remark: val})}/>
+              <ResetRemark remark={remark} ID={config.uuid + 'remark'} onChange={(val) => this.setState({status: 'change', remark: val})}/>
             </div>
           </div> : null}
           {type === 'createTemp' || type === 'checkTemp' ? <div className="pre-temp-wrap">
diff --git a/src/tabviews/custom/components/module/voucher/printVoucher/index.jsx b/src/tabviews/custom/components/module/voucher/printVoucher/index.jsx
new file mode 100644
index 0000000..d4fcd37
--- /dev/null
+++ b/src/tabviews/custom/components/module/voucher/printVoucher/index.jsx
@@ -0,0 +1,354 @@
+import React, {Component} from 'react'
+import { Button } from 'antd'
+import moment from 'moment'
+import html2Canvas from 'html2canvas'
+import JsPDF from 'jspdf'
+
+import './index.scss'
+
+class printVoucher extends Component {
+  state = {
+    loading: false
+  }
+
+  trigger = () => {
+    this.setState({loading: true})
+
+    setTimeout(() => {
+      this.getCanvas()
+    }, 200)
+  }
+
+  getCanvas = () => {
+    const { ID } = this.props
+    let wrap = document.getElementById(ID)
+    let elements = wrap.querySelectorAll('.mk-voucher-print-pdf-wrap')
+    let  pageArr = []
+    const opts = {
+      scale: 1.5,        // 缂╂斁姣斾緥锛屾彁楂樼敓鎴愬浘鐗囨竻鏅板害
+      useCORS: false,    // 鍏佽鍔犺浇璺ㄥ煙鐨勫浘鐗�
+      allowTaint: false, // 鍏佽鍥剧墖璺ㄥ煙锛屽拰 useCORS 浜岃�呬笉鍙叡鍚屼娇鐢�
+      tainttest: false,  // 妫�娴嬫瘡寮犲浘鐗囧凡缁忓姞杞藉畬鎴�
+      logging: false     // 鏃ュ織寮�鍏筹紝鍙戝竷鐨勬椂鍊欒寰楁敼鎴� false
+    }
+    
+    elements = Array.from(elements)
+
+    for (let index = 0; index < elements.length; index++) {
+      // eslint-disable-next-line
+      html2Canvas(elements[index], opts).then(canvas => {
+        // a4绾哥殑灏哄[595.28,841.89]锛宧tml椤甸潰鐢熸垚鐨刢anvas鍦╬df涓浘鐗囩殑瀹介珮
+        const contentWidth = canvas.width
+        const contentHeight = canvas.height
+        const imgWidth = 595.28
+        const imgHeight = (592.28 / contentWidth) * contentHeight
+        const pageData = canvas.toDataURL('image/jpeg', 1.0)
+        // 涓�椤祊df鏄剧ずhtml椤甸潰鐢熸垚鐨刢anvas楂樺害;
+        const pageHeight = (contentWidth / 592.28) * 841.89
+        // 鏈敓鎴恜df鐨刪tml椤甸潰楂樺害
+        const leftHeight = contentHeight
+        pageArr.push({ pageData: pageData, pageHeight: pageHeight, leftHeight: leftHeight, imgWidth: imgWidth, imgHeight: imgHeight })
+
+        if (pageArr.length === elements.length) {
+          this.getPdf(pageArr)
+        }
+      })
+    }
+  }
+
+  getPdf = (pageArr) => {
+    const { orgname, vouDate, charName, charInt } = this.props
+    let title = moment(vouDate).format('YYYY-MM-DD') + charName + '-' + charInt + orgname + moment().format('YYYYMMDDHHmmss')
+    const PDF = new JsPDF('', 'pt', 'a4')
+
+    pageArr.forEach((data, index) => {
+      // 椤甸潰鍋忕Щ
+      let position = 0
+      // 杞崲瀹屾瘯锛宻ave淇濆瓨鍚嶇О鍚庢祻瑙堝櫒浼氳嚜鍔ㄤ笅杞�
+      // 褰撳唴瀹规湭瓒呰繃pdf涓�椤垫樉绀虹殑鑼冨洿锛屾棤闇�鍒嗛〉
+      if (data.leftHeight < data.pageHeight) {
+        // addImage(pageData, 'JPEG', 宸︼紝涓婏紝瀹藉害锛岄珮搴�)璁剧疆
+        PDF.addImage(data.pageData, 'JPEG', 0, 0, data.imgWidth, data.imgHeight)
+      } else {
+        // 瓒呰繃涓�椤垫椂锛屽垎椤垫墦鍗帮紙姣忛〉楂樺害841.89锛�
+        while (data.leftHeight > 0) {
+          PDF.addImage(data.pageData, 'JPEG', 0, position, data.imgWidth, data.imgHeight)
+          data.leftHeight -= data.pageHeight
+          position -= 841.89
+          if (data.leftHeight > 0) {
+            PDF.addPage()
+          }
+        }
+      }
+
+      if (index + 1 === pageArr.length) {
+        PDF.save(title + '.pdf')
+
+        this.setState({loading: false})
+      } else {
+        // 鏈浆鎹㈠埌鏈�鍚庝竴椤垫椂锛宲df澧炲姞涓�椤�
+        PDF.addPage()
+      }
+    })
+  }
+
+  getContent = () => {
+    const { data, orgname, vouDate, charName, charInt, attachments } = this.props
+
+    let list = []
+    let items = []
+    let index = 0
+
+    data.forEach((cell, i) => {
+      if (index < 10) {
+        items.push(cell)
+        index++
+      } else {
+        list.push([...items])
+        index = 0
+        items = []
+      }
+    })
+
+    if (items.length > 0) {
+      while (items.length < 5) {
+        items.push({uuid: index + ''})
+        index++
+      }
+
+      list.push(items)
+    } else if (list.length === 0) {
+      list = [[{uuid: '1'}, {uuid: '2'}, {uuid: '3'}, {uuid: '4'}, {uuid: '5'}]]
+    }
+
+    let total = this.getTotalLine(data)
+
+    if (total.debit) {
+      total.debit = total.debit.toFixed(2)
+    }
+    if (total.credit) {
+      total.credit = total.credit.toFixed(2)
+    }
+
+    return <>
+      {list.map((page, i) => (<div className="mk-voucher-print-pdf-wrap" key={i}>
+        <div className="print-header">
+          <div className="line">
+            <div className="left"></div>
+            <div className="center">璁拌处鍑瘉</div>
+            <div className="right">闄勫崟鎹暟锛歿attachments}</div>
+          </div>
+          <div className="line">
+            <div className="left">鍗曚綅锛歿orgname}</div>
+            <div className="center">鏃ユ湡锛歿moment(vouDate).format('YYYY-MM-DD')}</div>
+            <div className="right">鍑瘉鍙凤細{charName}-{charInt}{list.length > 1 ? `(${i + 1}/${list.length})` : ''}</div>
+          </div>
+        </div>
+        <div className="print-body">
+          <div className="print-line" key="0">
+            <div className="remark" style={{textAlign: 'center'}}>鎽樿</div>
+            <div className="subject" style={{textAlign: 'center'}}>绉戠洰</div>
+            <div className="credit" style={{textAlign: 'center'}}>鍊熸柟閲戦</div>
+            <div className="credit" style={{textAlign: 'center'}}>璐锋柟閲戦</div>
+          </div>
+          {page.map(record => {
+            let remark = record.subject_voucher_text || ''
+
+            if (record.count_type === 'Y') {
+              remark += `锛堟暟閲�:${record.fcc_count !== undefined ? record.fcc_count : ''}锛屽崟浠�:${record.net_unitprice !== undefined ? record.net_unitprice : ''}锛塦
+            }
+            if (record.foreign_currency_type === 'Y') {
+              remark += `锛堣揣甯侊細${record.exratename || ''}锛屾眹鐜囷細${record.unitratio !== undefined ? record.unitratio : ''}锛屽師甯侊細${record.foreign_amount !== undefined ? record.foreign_amount : ''}锛塦
+            }
+
+            let val = ''
+            if (record.subject_code) {
+              val = (record.subject_code || '') + ' ' + (record.subject_name || '')
+  
+              if (record.sup_accounting && record.supAccounts) {
+                record.supAccounts.forEach(item => {
+                  if (item.sup_acc_type === 'supplier') {
+                    val += item.suppliername ? '_'  + item.suppliername : ''
+                  } else if (item.sup_acc_type === 'customer') {
+                    val += item.customername ? '_'  + item.customername : ''
+                  } else if (item.sup_acc_type === 'department') {
+                    val += item.co_pro_name ? '_' + item.co_pro_name : ''
+                  } else if (item.sup_acc_type === 'project') {
+                    val += item.projectname ? '_' + item.projectname : ''
+                  } else if (item.sup_acc_type === 'inventory') {
+                    val += item.productname ? '_' + item.productname : ''
+                  } else if (item.sup_acc_type === 'employee') {
+                    val += item.workername ? '_' + item.workername : ''
+                  } else if (item.sup_acc_type === 'cash_flow') {
+                    val += item.cash_flow_name ? '_' + item.cash_flow_name : ''
+                  } else if (item.sup_acc_name) {
+                    val += '_' + item.sup_acc_name
+                  }
+                })
+              }
+            }
+
+            let debit = record.debit || record.debit === 0 ? record.debit : ''
+            let credit = record.credit || record.credit === 0 ? record.credit : ''
+
+            if (debit) {
+              debit = debit.toFixed(2)
+            }
+            if (credit) {
+              credit = credit.toFixed(2)
+            }
+
+            return <div className="print-line" key={record.uuid}>
+              <div className="remark">{remark}</div>
+              <div className="subject">{val}</div>
+              <div className="credit">{debit}</div>
+              <div className="credit">{credit}</div>
+            </div>
+          })}
+          <div className="print-line" key="total">
+            <div className="remark" style={{width: '60%'}}>鍚堣锛歿total.subject_voucher_text}</div>
+            <div className="credit">{total.debit}</div>
+            <div className="credit">{total.credit}</div>
+          </div>
+        </div>
+        <div className="print-footer">
+          <div>涓荤锛�</div>
+          <div>璁拌处锛�</div>
+          <div>瀹℃牳锛�</div>
+          <div>鍑虹撼锛�</div>
+          <div>鍒跺崟锛�</div>
+        </div>
+      </div>))}
+    </>
+  }
+
+  getTotalLine = (data) => {
+    let totalLine = {uuid: 'total', type: 'total'}
+    let debit = ''
+    let credit = ''
+
+    data.forEach(item => {
+      if (!isNaN(item.debit) && item.debit !== '') {
+        if (debit === '') {
+          debit = 0
+        }
+
+        debit += item.debit
+      } else if (!isNaN(item.credit) && item.credit !== '') {
+        if (debit === '') {
+          debit = 0
+        }
+        if (credit === '') {
+          credit = 0
+        }
+        credit += item.credit
+      }
+    })
+
+    totalLine.debit = debit
+    totalLine.credit = credit
+
+    totalLine.subject_voucher_text = this.changeMoneyToChinese(debit)
+    
+    return totalLine
+  }
+  
+  changeMoneyToChinese = (money) => {
+    let cnNums = ['闆�', '澹�', '璐�', '鍙�', '鑲�', '浼�', '闄�', '鏌�', '鎹�', '鐜�']
+    let cnIntRadice = ['', '鎷�', '浣�', '浠�']
+    let cnIntUnits = ['', '涓�', '浜�', '鍏�']
+    let cnDecUnits = ['瑙�', '鍒�', '姣�', '鍘�']
+    let cnInteger = '鏁�'
+    let cnIntLast = '鍏�'
+    let maxNum = 999999999999999.9999 // 鏈�澶у鐞嗙殑鏁板瓧
+    let IntegerNum = null
+    let DecimalNum = null
+    let ChineseStr = ''
+    let parts = null // 鍒嗙閲戦鍚庣敤鐨勬暟缁勶紝棰勫畾涔�
+    let Symbol = ''  // 姝h礋鍊兼爣璁�
+
+    if (money === '') return ''
+
+    if (money >= maxNum) return '瓒呭嚭鏈�澶у鐞嗘暟瀛�'
+
+    if (money === 0) {
+      ChineseStr = cnNums[0] + cnIntLast + cnInteger;
+      return ChineseStr
+    }
+    if(money < 0) {
+      money = -money
+      Symbol = '璐�'       
+    }
+    money = money.toString() // 杞崲涓哄瓧绗︿覆
+    if (money.indexOf('.') === -1) {
+      IntegerNum = money
+      DecimalNum = ''
+    } else {
+      parts = money.split('.')
+      IntegerNum = parts[0]
+      DecimalNum = parts[1].substr(0, 4)
+    }
+
+    if (parseInt(IntegerNum, 10) > 0) { // 鑾峰彇鏁村瀷閮ㄥ垎杞崲
+      let zeroCount = 0
+      let IntLen = IntegerNum.length
+      for (let i = 0; i < IntLen; i++) {
+        let n = IntegerNum.substr(i, 1)
+        let p = IntLen - i - 1
+        let q = p / 4
+        let m = p % 4
+        
+        if (n === '0') {
+          zeroCount++
+        } else {
+          if (zeroCount > 0) {
+            ChineseStr += cnNums[0]
+          }
+          zeroCount = 0 // 褰掗浂
+          ChineseStr += cnNums[parseInt(n)] + cnIntRadice[m]
+        }
+
+        if (m === 0 && zeroCount < 4) {
+          ChineseStr += cnIntUnits[q]
+        }
+      }
+      ChineseStr += cnIntLast
+    }
+
+    if (DecimalNum !== '') { // 灏忔暟閮ㄥ垎
+      let decLen = DecimalNum.length
+
+      for (let i = 0; i < decLen; i++) {
+        let n = DecimalNum.substr(i, 1)
+        if (n !== '0') {
+          ChineseStr += cnNums[Number(n)] + cnDecUnits[i]
+        }
+      }
+    }
+    if (ChineseStr === '') {
+      ChineseStr += cnNums[0] + cnIntLast + cnInteger
+    } else if (DecimalNum === '') {
+      ChineseStr += cnInteger
+    }
+
+    ChineseStr = Symbol + ChineseStr
+    
+    return ChineseStr
+  }
+
+  render() {
+    const { disabled, ID } = this.props
+    const { loading } = this.state
+
+    return (
+      <>
+        <Button className="print-background header-btn" loading={loading} disabled={disabled} onClick={this.trigger}>鎵撳嵃</Button>
+        {loading ? <div id={ID} className="mk-voucher-print-wrap">
+          {this.getContent()}
+        </div> : null}
+      </>
+    )
+  }
+}
+
+export default printVoucher
\ No newline at end of file
diff --git a/src/tabviews/custom/components/module/voucher/printVoucher/index.scss b/src/tabviews/custom/components/module/voucher/printVoucher/index.scss
new file mode 100644
index 0000000..4ad7c24
--- /dev/null
+++ b/src/tabviews/custom/components/module/voucher/printVoucher/index.scss
@@ -0,0 +1,126 @@
+.mk-voucher-print-wrap {
+  position: absolute;
+  width: 0;
+  height: 0;
+  overflow: hidden;
+}
+
+.mk-voucher-print-pdf-wrap {
+  width: 1200px;
+  padding: 80px;
+  color: #000000;
+  background: #ffffff;
+  .print-header {
+    .line {
+      display: flex;
+      margin-bottom: 10px;
+
+      div {
+        flex: 1;
+        width: 33.33%;
+        min-height: 5px;
+      }
+      .center {
+        text-align: center;
+      }
+      .right {
+        text-align: right;
+      }
+    }
+    .line:first-child {
+      .center {
+        font-size: 24px;
+      }
+      .right {
+        padding-top: 15px;
+      }
+    }
+  }
+  .print-footer {
+    display: flex;
+
+    div {
+      flex: 1;
+      width: 20%;
+    }
+  }
+  .print-body {
+    position: relative;
+    border: 1px solid #000000;
+    margin: 20px 0px;
+
+    .print-line {
+      position: relative;
+      height: 60px;
+      .remark {
+        display: inline-block;
+        width: 25%;
+        padding: 0 3px;
+      }
+      .subject {
+        display: inline-block;
+        width: 35%;
+        padding: 0 3px;
+      }
+      .credit {
+        display: inline-block;
+        width: 20%;
+        line-height: 60px;
+        text-align: right;
+        padding: 0 3px;
+      }
+
+      .remark::after {
+        content: '';
+        position: absolute;
+        width: 0px;
+        height: 60px;
+        left: 25%;
+        top: 0;
+        border-right: 1px solid #000000;
+      }
+    }
+    .print-line:first-child {
+      > div {
+        text-align: center;
+      }
+    }
+    .print-line:last-child {
+      .remark {
+        width: 60%;
+      }
+      .remark::after {
+        display: none;
+      }
+    }
+    .print-line:not(:last-child)::after {
+      // border: 1px solid #000000;
+      content: '';
+      position: absolute;
+      width: 100%;
+      height: 0px;
+      left: 0;
+      bottom: 0;
+      border-bottom: 1px solid #000000;
+    }
+  }
+
+  .print-body::before {
+    content: '';
+    position: absolute;
+    width: 0px;
+    height: 100%;
+    left: 60%;
+    top: 0;
+    border-right: 1px solid #000000;
+  }
+  .print-body:after {
+    content: '';
+    position: absolute;
+    width: 0px;
+    height: 100%;
+    left: 80%;
+    top: 0;
+    border-right: 1px solid #000000;
+  }
+}
\ No newline at end of file
diff --git a/src/tabviews/custom/components/module/voucher/voucherTable/index.jsx b/src/tabviews/custom/components/module/voucher/voucherTable/index.jsx
index 68aa28d..327a6c9 100644
--- a/src/tabviews/custom/components/module/voucher/voucherTable/index.jsx
+++ b/src/tabviews/custom/components/module/voucher/voucherTable/index.jsx
@@ -748,21 +748,21 @@
             if (record.sup_accounting && record.supAccounts) {
               record.supAccounts.forEach(item => {
                 if (item.sup_acc_type === 'supplier') {
-                  val += item.suppliercode ? '_' + item.suppliercode : ''
+                  val += item.suppliercode ? '_' + item.suppliercode + ' ' + item.suppliername : ''
                 } else if (item.sup_acc_type === 'customer') {
-                  val += item.customercode ? '_' + item.customercode : ''
+                  val += item.customercode ? '_' + item.customercode + ' ' + item.customername : ''
                 } else if (item.sup_acc_type === 'department') {
-                  val += item.co_pro_code ? '_' + item.co_pro_code : ''
+                  val += item.co_pro_code ? '_' + item.co_pro_code + ' ' + item.co_pro_name : ''
                 } else if (item.sup_acc_type === 'project') {
-                  val += item.projectcode ? '_' + item.projectcode : ''
+                  val += item.projectcode ? '_' + item.projectcode + ' ' + item.projectname : ''
                 } else if (item.sup_acc_type === 'inventory') {
-                  val += item.productcode ? '_' + item.productcode : ''
+                  val += item.productcode ? '_' + item.productcode + ' ' + item.productname : ''
                 } else if (item.sup_acc_type === 'employee') {
-                  val += item.workercode ? '_' + item.workercode : ''
+                  val += item.workercode ? '_' + item.workercode + ' ' + item.workername : ''
                 } else if (item.sup_acc_type === 'cash_flow') {
-                  val += item.cash_flow_code ? '_' + item.cash_flow_code : ''
+                  val += item.cash_flow_code ? '_' + item.cash_flow_code + ' ' + item.cash_flow_name : ''
                 } else if (item.sup_acc_code) {
-                  val += '_' + item.sup_acc_code
+                  val += '_' + item.sup_acc_code + ' ' + item.sup_acc_name
                 }
               })
             }

--
Gitblit v1.8.0