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