| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | { |
| | | "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": "", |
| | |
| | | "transfer": "false", |
| | | "keepPassword": "true", |
| | | "platforms": ["H5", "wechat", "android", "ios", "wxMiniProgram"], |
| | | "host": "http://demo.mk9h.cn", |
| | | "service": "erp_new/" |
| | | "host": "http://qingqiumarket.cn", |
| | | "service": "MKWMS/" |
| | | } |
| | |
| | | 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 { |
| | |
| | | } |
| | | } |
| | | |
| | | // config.wrap.type = 'checkVoucher' |
| | | // BID = '20230214130744811P0K95RQ155KG0QIQOFV' |
| | | config.wrap.type = 'checkVoucher' |
| | | BID = '20230214130744811P0K95RQ155KG0QIQOFV' |
| | | |
| | | // config.wrap.type = 'checkTemp' |
| | | // BID = '20230214174458780MFR8IA576ON4VKNOLVH' |
| | |
| | | }) |
| | | } |
| | | |
| | | triggerprint = () => { |
| | | |
| | | } |
| | | |
| | | dataChange = (data) => { |
| | | this.setState({ |
| | | status: 'change', |
| | |
| | | _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) |
| | |
| | | num = 0 |
| | | } |
| | | |
| | | this.setState({attachlist: vals, attachments: num}) |
| | | this.setState({status: 'change', attachlist: vals, attachments: num}) |
| | | } |
| | | |
| | | triggermore = () => { |
| | |
| | | } |
| | | |
| | | 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> |
| | |
| | | </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"> |
New file |
| | |
| | | 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],html页面生成的canvas在pdf中图片的宽高 |
| | | 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) |
| | | // 一页pdf显示html页面生成的canvas高度; |
| | | const pageHeight = (contentWidth / 592.28) * 841.89 |
| | | // 未生成pdf的html页面高度 |
| | | 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 |
| | | // 转换完毕,save保存名称后浏览器会自动下载 |
| | | // 当内容未超过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 { |
| | | // 未转换到最后一页时,pdf增加一页 |
| | | 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 = '' // 正负值标记 |
| | | |
| | | 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 |
New file |
| | |
| | | .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; |
| | | } |
| | | } |
| | |
| | | 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 |
| | | } |
| | | }) |
| | | } |