From e2ac71fbc53b7119ae87c5a3b08cdcf830b497e2 Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期五, 06 三月 2020 18:52:03 +0800 Subject: [PATCH] 2020-03-06 --- src/assets/img/qrcode.png | 0 src/assets/img/barcode.jpg | 0 src/views/printTemplate/option.js | 862 ++++++++++++++++++ src/views/printTemplate/index.jsx | 735 +++++++++++++++ src/assets/img/shunfeng.jpg | 0 src/views/printTemplate/index.scss | 40 src/views/printTemplate/mutilform/index.jsx | 257 +++++ src/templates/formtabconfig/index.jsx | 18 src/views/printTemplate/fileupload/index.jsx | 140 +++ src/templates/comtableconfig/index.jsx | 19 src/views/printTemplate/dragelement/index.jsx | 37 src/views/printTemplate/mutilform/index.scss | 50 + /dev/null | 8 src/templates/modalconfig/index.jsx | 27 src/views/printTemplate/print.js | 407 ++++++++ src/api/index.js | 88 + src/views/printTemplate/dragelement/index.scss | 10 src/tabviews/commontable/index.jsx | 10 src/views/printTemplate/fileupload/index.scss | 5 src/utils/utils.js | 20 20 files changed, 2,653 insertions(+), 80 deletions(-) diff --git a/src/api/index.js b/src/api/index.js index 5a879a0..19c2481 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -117,6 +117,43 @@ } /** + * @description 鑾峰彇鎴栦慨鏀逛簯绔厤缃� + */ + getCloudConfig (param) { + param.lang = localStorage.getItem('lang') || '' + param.appkey = window.GLOB.appkey || '' + + if (sessionStorage.getItem('CloudUserID') && options.cloudServiceApi) { // 瀛樺湪浜戠鐧诲綍淇℃伅锛屼笖瀛樺湪浜戠鍦板潃 + param.rduri = options.cloudServiceApi + param.userid = sessionStorage.getItem('CloudUserID') + param.SessionUid = sessionStorage.getItem('CloudSessionUid') || '' + param.LoginUID = sessionStorage.getItem('CloudLoginUID') || '' + } else if (window.GLOB.mainSystemApi) { + param.rduri = window.GLOB.mainSystemApi + param.userid = sessionStorage.getItem('UserID') + param.SessionUid = sessionStorage.getItem('SessionUid') || '' + param.LoginUID = sessionStorage.getItem('LoginUID') || '' + } else { + param.userid = sessionStorage.getItem('UserID') + param.SessionUid = sessionStorage.getItem('SessionUid') || '' + param.LoginUID = sessionStorage.getItem('LoginUID') || '' + } + + param.nonc = Utils.getuuid() + + let keys = Object.keys(param).sort() + keys = keys.filter(key => key !== 'rduri') + let values = keys.map(key => key + param[key]).join('') + param.sign = md5(values) + param.t = new Date().getTime() + + return axios({ + url: '/webapi/dostars', + data: param + }) + } + + /** * @description 鑾峰彇鎴栦慨鏀圭郴缁熼厤缃紝澧炲姞appkey */ getSystemConfig (param) { @@ -306,6 +343,57 @@ } /** + * @description 涓婁紶base64 + * @param {String} base64 base64鍥剧墖缂栫爜 + */ + fileuploadbase64 (base64, service = 'local') { + let param = { + BasePath: 'Content/Upload', + lang: localStorage.getItem('lang') || '', + appkey: window.GLOB.appkey || '', + Base64Img: base64 + } + + if (service === 'sso' && window.GLOB.mainSystemApi) { + param.rduri = window.GLOB.mainSystemApi + param.userid = sessionStorage.getItem('UserID') + param.SessionUid = sessionStorage.getItem('SessionUid') || '' + param.LoginUID = sessionStorage.getItem('LoginUID') || '' + } else if (service === 'cloud' && options.cloudServiceApi) { + param.rduri = options.cloudServiceApi + param.userid = sessionStorage.getItem('CloudUserID') + param.SessionUid = sessionStorage.getItem('CloudSessionUid') || '' + param.LoginUID = sessionStorage.getItem('CloudLoginUID') || '' + } else { + param.userid = sessionStorage.getItem('UserID') + param.SessionUid = sessionStorage.getItem('SessionUid') || '' + param.LoginUID = sessionStorage.getItem('LoginUID') || '' + } + + param.nonc = Utils.getuuid() + + let keys = Object.keys(param).sort() + keys = keys.filter(key => key !== 'rduri') + let values = keys.map(key => key + param[key]).join('') + param.sign = md5(values) + param.t = new Date().getTime() + + if (param.rduri) { + param.rduri = param.rduri.replace(/webapi(.*)$/, 'webapi/SaveBase64Image') + + return axios({ + url: '/webapi/dostars', + data: param + }) + } else { + return axios({ + url: '/webapi/SaveBase64Image', + data: param + }) + } + } + + /** * @description 鏂囦欢涓婁紶 */ getFileUpload (param) { diff --git a/src/assets/img/barcode.jpg b/src/assets/img/barcode.jpg new file mode 100644 index 0000000..252e89c --- /dev/null +++ b/src/assets/img/barcode.jpg Binary files differ diff --git a/src/assets/img/qrcode.png b/src/assets/img/qrcode.png new file mode 100644 index 0000000..895b409 --- /dev/null +++ b/src/assets/img/qrcode.png Binary files differ diff --git a/src/assets/img/shunfeng.jpg b/src/assets/img/shunfeng.jpg new file mode 100644 index 0000000..ed6f520 --- /dev/null +++ b/src/assets/img/shunfeng.jpg Binary files differ diff --git a/src/tabviews/commontable/index.jsx b/src/tabviews/commontable/index.jsx index 526ae53..fa3a891 100644 --- a/src/tabviews/commontable/index.jsx +++ b/src/tabviews/commontable/index.jsx @@ -836,6 +836,16 @@ this.loadconfig() } + componentDidMount () { + document.onkeydown = (event) => { + let e = event || window.event + + if(e && e.keyCode === 27) { + console.log(this.props.MenuID) + } + } + } + UNSAFE_componentWillReceiveProps(nextProps) { if (nextProps.refreshTab && nextProps.refreshTab.MenuID === this.props.MenuID) { if (nextProps.refreshTab.position === 'grid') { diff --git a/src/templates/comtableconfig/index.jsx b/src/templates/comtableconfig/index.jsx index 7fb6751..bd48173 100644 --- a/src/templates/comtableconfig/index.jsx +++ b/src/templates/comtableconfig/index.jsx @@ -171,10 +171,19 @@ originMenu: JSON.parse(JSON.stringify(menu)), selectedTables: _config.tables || [], menuformlist: [ + // { + // type: 'select', + // key: 'firparentId', + // label: '涓�绾ц彍鍗�', + // initVal: menu.ParentID, + // required: true, + // readonly: false, + // options: this.props.supMenuList + // }, { type: 'select', key: 'parentId', - label: this.state.dict['header.menu.supMenu'], + label: '浜岀骇鑿滃崟', initVal: menu.ParentID, required: true, readonly: false, @@ -1531,6 +1540,7 @@ getFuncNames = (data, funcNames, tableNames) => { data.forEach(item => { + console.log(item) if (item.subfuncs) { this.getFuncNames(item.subfuncs, funcNames, tableNames) } else { @@ -1538,11 +1548,10 @@ tableNames.push(item.tableName) } if (item.innerFunc) { + // funcNames.push({func: item.innerFunc, label: item}) funcNames.push(item.innerFunc) } - // if (item.outerFunc) { - // funcNames.push(item.outerFunc) - // } + if (item.callbackFunc) { funcNames.push(item.callbackFunc) } @@ -1788,7 +1797,7 @@ Sort: (this.props.supMenuList.length + 1) * 10, PageParam: JSON.stringify(_pageParam), LongParam: _LongParam, - LText: _funcs.map(item => `select '${menu.MenuID}' as MenuID,'${item}' as ProcName`), + LText: _funcs.map(item => `select '${menu.MenuID}' as MenuID,'${item}' as ProcName,'${item}' as MenuName`), LTexttb: _tables.map(item => `select '${menu.MenuID}' as MenuID,'${item}' as tbName`) } diff --git a/src/templates/formtabconfig/index.jsx b/src/templates/formtabconfig/index.jsx index 0005835..ee46115 100644 --- a/src/templates/formtabconfig/index.jsx +++ b/src/templates/formtabconfig/index.jsx @@ -595,6 +595,7 @@ } let _groups = null + let fieldrepet = false // 瀛楁閲嶅 if (card.iscopy) { _groups = config.groups.map(group => { @@ -602,6 +603,10 @@ group.sublist.forEach((item, index) => { if (item.uuid === card.originUuid) { _index = index + } + + if (item.uuid !== res.uuid && item.field === res.field) { + fieldrepet = true } }) @@ -617,6 +622,10 @@ } else { _groups = config.groups.map(group => { group.sublist = group.sublist.map(item => { + if (item.uuid !== res.uuid && item.field === res.field) { + fieldrepet = true + } + if (item.uuid === res.uuid) { return res } else { @@ -630,6 +639,15 @@ }) } + if (fieldrepet) { + notification.warning({ + top: 92, + message: '瀛楁鍚嶉噸澶嶏紒', + duration: 10 + }) + return + } + this.setState({ config: {...config, groups: _groups}, optionLibs: optionLibs, diff --git a/src/templates/modalconfig/index.jsx b/src/templates/modalconfig/index.jsx index b655b80..4f50489 100644 --- a/src/templates/modalconfig/index.jsx +++ b/src/templates/modalconfig/index.jsx @@ -499,6 +499,8 @@ }) } + let fieldrepet = false // 瀛楁閲嶅 + if (modalType === 'copy' && card.originUuid) { if (_config.groups.length > 0) { _config.groups = _config.groups.map(group => { @@ -506,6 +508,10 @@ group.sublist.forEach((item, index) => { if (item.uuid === card.originUuid) { _index = index + } + + if (item.uuid !== res.uuid && item.field === res.field) { + fieldrepet = true } }) @@ -521,6 +527,10 @@ if (item.uuid === card.originUuid) { _index = index } + + if (item.uuid !== res.uuid && item.field === res.field) { + fieldrepet = true + } }) _config.fields.splice(_index + 1, 0, res) @@ -529,6 +539,10 @@ if (_config.groups.length > 0) { _config.groups.forEach(group => { group.sublist = group.sublist.map(item => { + if (item.uuid !== res.uuid && item.field === res.field) { + fieldrepet = true + } + if (item.uuid === res.uuid) { return res } else { @@ -538,6 +552,10 @@ }) } else { _config.fields = _config.fields.map(item => { + if (item.uuid !== res.uuid && item.field === res.field) { + fieldrepet = true + } + if (item.uuid === res.uuid) { return res } else { @@ -546,6 +564,15 @@ }) } } + + if (fieldrepet) { + notification.warning({ + top: 92, + message: '瀛楁鍚嶉噸澶嶏紒', + duration: 10 + }) + return + } _config.fields = _config.fields.filter(item => !item.origin) diff --git a/src/utils/utils.js b/src/utils/utils.js index b5c9245..9edfb85 100644 --- a/src/utils/utils.js +++ b/src/utils/utils.js @@ -1,5 +1,6 @@ import moment from 'moment' import md5 from 'md5' +import options from '@/store/options.js' const service = window.GLOB.service ? (/\/$/.test(window.GLOB.service) ? window.GLOB.service : window.GLOB.service + '/') : '' @@ -391,6 +392,7 @@ */ static getrealurl (url) { if (!url) return '' + let baseurl = '' if (process.env.NODE_ENV === 'production') { baseurl = document.location.origin + '/' + service @@ -405,6 +407,24 @@ } /** + * @description 鑾峰彇浜戠鍥剧墖鐪熷疄璺緞 + * @return {String} url 鍥剧墖璺緞 + */ + static getcloudurl (url) { + if (!url) return '' + + let baseurl = '' + + if (options.cloudServiceApi) { + baseurl = options.cloudServiceApi.replace(/webapi(.*)$/, '') + } else { + baseurl = document.location.origin + '/' + service + } + + return url.match(/^http/) || url.match(/^\/\//) ? url : baseurl + url + } + + /** * @description 鑾峰彇涓嬫媺鎼滅储鏌ヨ鏉′欢 * @return {String} item 鎼滅储鏉′欢淇℃伅 */ diff --git a/src/views/printTemplate/dragelement/card.jsx b/src/views/printTemplate/dragelement/card.jsx deleted file mode 100644 index 5419ea0..0000000 --- a/src/views/printTemplate/dragelement/card.jsx +++ /dev/null @@ -1,158 +0,0 @@ -import React from 'react' -import { useDrag, useDrop } from 'react-dnd' -import { Icon, Button, Select, DatePicker, Input } from 'antd' -import moment from 'moment' -import ItemTypes from './itemtypes' -import './index.scss' - -const { MonthPicker, WeekPicker, RangePicker } = DatePicker -// const { Paragraph } = Typography - -const Card = ({ id, type, card, moveCard, findCard, editCard, delCard, copyCard, profileCard, hasDrop, showfield }) => { - const originalIndex = findCard(id).index - const [{ isDragging }, drag] = useDrag({ - item: { type: ItemTypes[type], id, originalIndex }, - collect: monitor => ({ - isDragging: monitor.isDragging(), - }), - }) - const [, drop] = useDrop({ - accept: ItemTypes[type], - canDrop: () => true, - drop: (item) => { - if (!item.hasOwnProperty('originalIndex')) { - hasDrop(card) - } - }, - hover({ id: draggedId }) { - if (!draggedId) return - if (draggedId !== id) { - const { index: overIndex } = findCard(id) - moveCard(draggedId, overIndex) - } - }, - }) - const opacity = isDragging ? 0 : 1 - - const edit = () => { - editCard(id) - } - - const del = () => { - delCard(id) - } - - const copy = () => { - copyCard(id) - } - - const profile = () => { - profileCard(id) - } - - let _defaultValue = '' // 涓嬫媺鎼滅储銆佹椂闂磋寖鍥寸被鍨嬶紝鍒濆鍊奸渶瑕侀澶勭悊 - - if (type === 'search' && (card.type === 'multiselect' || card.type === 'select' || card.type === 'link')) { - if (card.initval) { - let _option = card.options.filter(option => option.Value === card.initval)[0] - if (_option) { - _defaultValue = _option.Text || '' - } else { - _defaultValue = '' - } - } else if (card.setAll === 'true') { - _defaultValue = '鍏ㄩ儴' - } - } else if (type === 'search' && card.type === 'daterange') { - _defaultValue = [null, null] - if (card.initval) { - try { - let _initval = JSON.parse(card.initval) - _defaultValue = [moment().subtract(_initval[0], 'days'), moment().subtract(_initval[1], 'days')] - } catch { - _defaultValue = [null, null] - } - } - } - - let hasProfile = false - if (type === 'action') { - if (['pop', 'prompt', 'exec'].includes(card.OpenType) && card.intertype === 'inner' && !card.innerFunc) { - hasProfile = true - } else if (card.OpenType === 'excelIn' || card.OpenType === 'excelOut') { - hasProfile = true - } - } - - return ( - <div className="page-card" style={type === 'columns' ? { flex: card.Width, opacity: opacity} : { opacity: opacity}}> - <div ref={node => drag(drop(node))}> - {type === 'search' ? - <div className="ant-row ant-form-item"> - <div className="ant-col ant-form-item-label"> - <label title={card.label}>{card.label}</label> - </div> - <div className="ant-col ant-form-item-control-wrapper"> - {card.type === 'text' ? - <Input style={{marginTop: '4px'}} defaultValue={card.initval} /> : null - } - {(card.type === 'multiselect' || card.type === 'select' || card.type === 'link') ? - <Select defaultValue={_defaultValue}></Select> : null - } - {card.type === 'date' ? - <DatePicker defaultValue={card.initval ? moment().subtract(card.initval, 'days') : null} /> : null - } - {card.type === 'dateweek' ? - <WeekPicker defaultValue={card.initval ? moment().subtract(card.initval * 7, 'days') : null} /> : null - } - {card.type === 'datemonth' ? - <MonthPicker defaultValue={card.initval ? moment().subtract(card.initval, 'month') : null} /> : null - } - {card.type === 'daterange' ? - <RangePicker - className="data-range" - placeholder={['寮�濮嬫棩鏈�', '缁撴潫鏃ユ湡']} - renderExtraFooter={() => 'extra footer'} - defaultValue={_defaultValue} - /> : null - } - <div className="input-mask"></div> - </div> - </div> : null - } - {type === 'action' ? - <Button - className={'mk-btn mk-' + card.class} - icon={card.icon} - key={card.uuid} - > - {card.label}{card.position === 'grid' && <Icon type="table" />} - </Button> : null - } - {type === 'columns' ? - <span className="ant-table-header-column"> - <div className="ant-table-column-sorters" title={card.label} style={{textAlign: card.Align}}> - <span className="ant-table-column-title">{card.label}</span> - {card.IsSort === 'true' ? - <span className="ant-table-column-sorter"> - <Icon type="caret-up" /> - <Icon type="caret-down" /> - </span> : null - } - </div> - {showfield ? - <div className="ant-table-column-fields"> - <span className="ant-table-column-title">{card.type === 'colspan' ? card.subfield : card.field}</span> - </div> : null - } - </span> : null - } - </div> - <Icon className="edit" title="缂栬緫" type="edit" onClick={edit} /> - <Icon className="edit close" title="鍒犻櫎" type="close" onClick={del} /> - {type === 'action' ? <Icon className="edit copy" title="澶嶅埗" type="copy" onClick={copy} /> : null} - {hasProfile ? <Icon className="edit profile" title="鏍¢獙瑙勫垯" type="profile" onClick={profile} /> : null} - </div> - ) -} -export default Card diff --git a/src/views/printTemplate/dragelement/index.jsx b/src/views/printTemplate/dragelement/index.jsx index 291bb24..242eb21 100644 --- a/src/views/printTemplate/dragelement/index.jsx +++ b/src/views/printTemplate/dragelement/index.jsx @@ -1,44 +1,19 @@ -import React, { useState } from 'react' +import React from 'react' import { useDrop } from 'react-dnd' -import { is, fromJS } from 'immutable' -import update from 'immutability-helper' -import { Col, Icon } from 'antd' -import Utils from '@/utils/utils.js' -import Card from './card' -import ItemTypes from './itemtypes' import './index.scss' -const Container = ({list, type }) => { - - const [cards, setCards] = useState(list) - const moveCard = (id, atIndex) => { - const { card, index } = findCard(id) - const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] }) - handleList(type, _cards) - } - - if (!is(fromJS(cards), fromJS(list))) { - setCards(list) - } - - const findCard = id => { - const card = cards.filter(c => `${c.uuid}` === id)[0] - return { - card, - index: cards.indexOf(card), - } - } +const Container = ({dropcard}) => { const [, drop] = useDrop({ - accept: ItemTypes[type], + accept: 'print', drop(item) { - + dropcard(item) } }) return ( - <div ref={drop} className="ant-row"> - + <div ref={drop} className="print-area"> + <canvas id="darea"></canvas> </div> ) } diff --git a/src/views/printTemplate/dragelement/index.scss b/src/views/printTemplate/dragelement/index.scss index 90174bc..bf335cf 100644 --- a/src/views/printTemplate/dragelement/index.scss +++ b/src/views/printTemplate/dragelement/index.scss @@ -11,3 +11,13 @@ margin-left: 10px; } } +.print-area { + display: inline-block; + margin: 0 auto; + margin-right: 30px; + + canvas { + box-shadow: 0px 0px 7px rgba(0, 0, 0, 0.2); + } +} + diff --git a/src/views/printTemplate/dragelement/itemtypes.js b/src/views/printTemplate/dragelement/itemtypes.js deleted file mode 100644 index 9ea1f2c..0000000 --- a/src/views/printTemplate/dragelement/itemtypes.js +++ /dev/null @@ -1,8 +0,0 @@ -export default { - CARD: 'card', - form: 'form', - search: 'search', - action: 'action', - columns: 'columns', - tab: 'tab' -} diff --git a/src/views/printTemplate/fileupload/index.jsx b/src/views/printTemplate/fileupload/index.jsx new file mode 100644 index 0000000..682498f --- /dev/null +++ b/src/views/printTemplate/fileupload/index.jsx @@ -0,0 +1,140 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { Upload, message, Button, Icon, Progress } from 'antd' +import Api from '@/api' +import './index.scss' + +let service = window.GLOB.service ? (/\/$/.test(window.GLOB.service) ? window.GLOB.service : window.GLOB.service + '/') : '' +let Url = '/Upload' +if (process.env.NODE_ENV === 'production') { + Url = document.location.origin + '/' + service + 'zh-CN/Home/Upload' +} + +class FileUpload extends Component { + static propTpyes = { + value: PropTypes.array // 鎸夐挳淇℃伅銆佽〃鍗曞垪琛� + } + + state = { + baseUrl: Url, + percent: 0, + showprogress: false + } + + init = async () => { + try { + const OSSData = await this.mockGetOSSData() + + this.setState({ + OSSData + }) + } catch (error) { + message.error(error) + } + } + + onChange = ({ fileList }) => { + const { onChange } = this.props + + if (onChange) { + onChange([...fileList]) + } + } + + onRemove = file => { + const { value, onChange } = this.props + + const files = value.filter(v => v.url !== file.url) + + if (onChange) { + onChange(files) + } + } + + getExtraData = () => { + return { + RootPath: 'Content/images/upload/' + } + } + + shardupload = (file, shardSize, shardCount, i, fileList) => { + let start = i * shardSize + let end = Math.min(file.size, start + shardSize) + let form = new FormData() + + form.append('file', file.slice(start, end)) //slice鏂规硶鐢ㄤ簬鍒囧嚭鏂囦欢鐨勪竴閮ㄥ垎 + form.append('RootPath', 'Content/images/upload/') + form.append('name', file.name) + form.append('total', shardCount) + form.append('index', i + 1) + + if (i < shardCount) { + i++ + Api.getFileUpload(form).then(res => { + if (res) { + this.setState({ + percent: Math.floor(100 * (i / shardCount)) + }) + this.shardupload(file, shardSize, shardCount, i, fileList) + } + }) + } else { + this.setState({ + percent: 100 + }, () => { + setTimeout(() => { + this.setState({ + showprogress: false, + percent: 0 + }) + }, 200) + }) + } + } + + beforeUpload = (file, fileList) => { + let shardSize = 2 * 1024 * 1024 + // let shardSize = 3 * 1024 + + if (file.size > shardSize) { + this.setState({ + showprogress: true, + percent: 0 + }) + let shardCount = Math.ceil(file.size / shardSize) + this.shardupload(file, shardSize, shardCount, 0, fileList) + return false + } else { + return true + } + } + + render() { + const { value } = this.props + const { showprogress, percent, baseUrl } = this.state + + const props = { + name: 'file', + disabled: showprogress, + fileList: value, + action: baseUrl, + method: 'post', + multiple: true, + // headers: {'RootPath': 'Content/images/upload/'}, + onChange: this.onChange, + onRemove: this.onRemove, + data: this.getExtraData, + beforeUpload: this.beforeUpload, + } + return ( + <Upload {...props}> + <Button> + <Icon type="upload" /> 鐐瑰嚮涓婁紶 + </Button> + {showprogress ? <Progress percent={percent} size="small" /> : null} + </Upload> + ) + } +} + +export default FileUpload \ No newline at end of file diff --git a/src/views/printTemplate/fileupload/index.scss b/src/views/printTemplate/fileupload/index.scss new file mode 100644 index 0000000..1bee6cc --- /dev/null +++ b/src/views/printTemplate/fileupload/index.scss @@ -0,0 +1,5 @@ +.main-form-field .ant-progress-small.ant-progress-line { + position: absolute; + bottom: -20px; + left: 0px; +} \ No newline at end of file diff --git a/src/views/printTemplate/index.jsx b/src/views/printTemplate/index.jsx index 69f6f17..fc31b6a 100644 --- a/src/views/printTemplate/index.jsx +++ b/src/views/printTemplate/index.jsx @@ -1,43 +1,65 @@ import React, {Component} from 'react' import { DndProvider } from 'react-dnd' +import { is, fromJS } from 'immutable' import HTML5Backend from 'react-dnd-html5-backend' -import { Card } from 'antd' +import { Card, notification, Row, Button, Modal } from 'antd' +import DragElement from './dragelement' +import MutilForm from './mutilform' import SourceElement from './dragelement/source' +import { + printItems, + originConfig, + getpageform, + getTextForm, + getBarcodeForm, + getQrcodeForm, + getImageForm, + getElement, + barurl, + qrurl, + imgurl +} from './option.js' +import Utils from '@/utils/utils.js' +import printCtrl from './print.js' +import Api from '@/api' import './index.scss' -const printItems = [ - { - type: 'print', - label: '鏂囨湰', - subType: 'text', - icon: 'file-text' - }, - { - type: 'print', - label: '鏉″舰鐮�', - subType: 'barcode', - icon: 'barcode' - }, - { - type: 'print', - label: '浜岀淮鐮�', - subType: 'qrcode', - icon: 'qrcode' - }, - { - type: 'print', - label: '鍥剧墖', - subType: 'picture', - icon: 'file-image' - } -] +const { confirm } = Modal +let dropPoint = null +let origin = null +let timer = null +let preorigin = null +let nextorigin = null class PrintTemplate extends Component { state = { - ID: null + config: null, + ID: null, + editItemId: '', + editItemType: '', + fields: [], + formlist: null, + saveloading: false } - componentDidMount () { + getclickpoint = (e) => { + const { config } = this.state + let scrollTop = document.documentElement.scrollTop || document.body.scrollTop + let screenX = e.clientX + let screenY = e.clientY + scrollTop + let offsetT = screenY - document.getElementById('darea').offsetTop + let offsetL = screenX - document.getElementById('darea').offsetLeft + + let cx = Math.floor(offsetL / parseInt(document.getElementById('darea').style.width) * config.width) + let cy = Math.floor(offsetT / parseInt(document.getElementById('darea').style.height) * config.height) + + return { + cx: cx, + cy: cy + } + } + + UNSAFE_componentWillMount () { let _param = window.atob(this.props.match.params.param) let _params = {} _param.split('&').forEach(cell => { @@ -47,6 +69,632 @@ this.setState({ ID: _params.ID + }) + } + + componentDidMount () { + // 鐐瑰嚮鍒囨崲缂栬緫鍏冪礌 + document.getElementById('darea').addEventListener('click', (e) => { + e.stopPropagation() + let position = this.getclickpoint(e) + let cx = position.cx + let cy = position.cy + let _selectItem = null + + let _config = JSON.parse(JSON.stringify(this.state.config)) + + _config.elements.forEach(element => { + let x = +element.left + let y = +element.top + let width = +element.width + let height = +element.height + let rotate = +element.rotate + if (rotate === 90 || rotate === 270) { + let _c = width + x = x + width / 2 - height / 2 + y = y + height / 2 - width / 2 + width = height + height = _c + } + if (width === 0) { + x -= 4 + width = 8 + } + if (height === 0) { + y -= 4 + height = 8 + } + if (cx > x && cx < x + width && cy > y && cy < y + height) { + _selectItem = element + } + }) + if (!_selectItem) { + _selectItem = _config + } else { + _config.elements = _config.elements.filter(ele => ele.uuid !== _selectItem.uuid) + _config.elements.push(_selectItem) + } + + let _formlist = null + + if (_selectItem.type === 'Template') { + _formlist = getpageform(_selectItem) + } else if (_selectItem.type === 'text') { + _formlist = getTextForm(_selectItem, this.state.fields) + } else if (_selectItem.type === 'barcode') { + _formlist = getBarcodeForm(_selectItem, this.state.fields) + } else if (_selectItem.type === 'qrcode') { + _formlist = getQrcodeForm(_selectItem, this.state.fields) + } else if (_selectItem.type === 'image') { + _formlist = getImageForm(_selectItem, this.state.fields) + } + + this.setState({ + config: _config, + editItemId: _selectItem.uuid, + editItemType: _selectItem.type, + formlist: _formlist + }, () => { + this.resetview() + }) + }) + + // 瑙﹀彂鎷栧姩浜嬩欢 + document.getElementById('darea').addEventListener('mousedown', (e) => { + const { config } = this.state + + if (!this.state.editItemType || this.state.editItemType === 'Template') { + origin = null + return + } + + let _selectItem = JSON.parse(JSON.stringify(this.state.config.elements.filter(ele => ele.uuid === this.state.editItemId)[0])) + let _preItem = JSON.parse(JSON.stringify(_selectItem)) + + let position = this.getclickpoint(e) + let cx = position.cx + let cy = position.cy + let x = +_selectItem.left + let y = +_selectItem.top + let width = +_selectItem.width + let height = +_selectItem.height + let rotate = +_selectItem.rotate + if (rotate === 90 || rotate === 270) { + let _c = width + x = x + width / 2 - height / 2 + y = y + height / 2 - width / 2 + width = height + height = _c + } + if (width === 0) { + x -= 4 + width = 8 + } + if (height === 0) { + y -= 4 + height = 8 + } + + if (cx > x && cx < x + width && cy > y && cy < y + height) { + if (width > 3 && height > 3 && cx > x + width - 3 && cx < x + width + 2 && cy > y + height - 3 && cy < y + height + 2) { + origin = { + cx: cx, + cy: cy, + width: +_selectItem.width, + height: +_selectItem.height + } + timer = setInterval(() => { + if (JSON.stringify(preorigin) !== JSON.stringify(nextorigin)) { + preorigin = nextorigin + let _width = origin.width + (nextorigin.cx - origin.cx) + let _height = origin.height + (nextorigin.cy - origin.cy) + + if (_width < 0) { + _width = 0 + } else if (_selectItem.left + _width > config.width) { + _width = config.width - _selectItem.left + } + if (_height < 0) { + _height = 0 + } else if (_height + _selectItem.top > config.height) { + _height = config.height - _selectItem.top + } + + _selectItem.width = _width + _selectItem.height = _height + + let result = this.resetItem(_selectItem) + + if (!is(fromJS(result), fromJS(_preItem))) { + _preItem = JSON.parse(JSON.stringify(result)) + this.FormRef.resetForm(result) + + config.elements = config.elements.map(item => { + if (item.uuid === result.uuid) return result + + return item + }) + + this.setState({ + config: config + }, () => { + this.resetview() + }) + } + } + }, 100) + } else { + origin = { + cx: cx, + cy: cy, + left: +_selectItem.left, + top: +_selectItem.top + } + timer = setInterval(() => { + if (JSON.stringify(preorigin) !== JSON.stringify(nextorigin)) { + preorigin = nextorigin + let _left = origin.left + (nextorigin.cx - origin.cx) + let _top = origin.top + (nextorigin.cy - origin.cy) + + if (_left < 0) { + _left = 0 + } else if (_left + _selectItem.width > config.width) { + _left = config.width - _selectItem.width + } + if (_top < 0) { + _top = 0 + } else if (_top + _selectItem.height > config.height) { + _top = config.height - _selectItem.height + } + + _selectItem.left = _left + _selectItem.top = _top + + let result = this.resetItem(_selectItem) + + if (!is(fromJS(result), fromJS(_preItem))) { + _preItem = JSON.parse(JSON.stringify(result)) + this.FormRef.resetForm(result) + + config.elements = config.elements.map(item => { + if (item.uuid === result.uuid) return result + + return item + }) + + this.setState({ + config: config + }, () => { + this.resetview() + }) + } + } + }, 100) + } + } else { + origin = null + } + }) + document.getElementById('darea').addEventListener('mousemove', (e) => { + if (!this.state.editItemType || this.state.editItemType === 'Template' || !origin) { + return + } + let position = this.getclickpoint(e) + nextorigin = { + cx: position.cx, + cy: position.cy + } + }) + document.getElementById('darea').addEventListener('mouseup', (e) => { + origin = null + clearInterval(timer) + }) + document.getElementById('darea').addEventListener('mouseleave', (e) => { + origin = null + clearInterval(timer) + }) + + // 鍏冪礌娣诲姞 + document.getElementById('darea').addEventListener('drop', (e) => { + dropPoint = this.getclickpoint(e) + }) + + if (document.body.offsetWidth < 1360) { + document.getElementById('darea').style.width = '600px' + } else if (document.body.offsetWidth < 1500) { + document.getElementById('darea').style.width = '700px' + } else if (document.body.offsetWidth < 1920) { + document.getElementById('darea').style.width = '800px' + } + + this.loadconfig() + } + + resetbox = () => { + const { config } = this.state + + let ratio = (config.height || 1) / (config.width || 1) + + document.getElementById('darea').style.height = parseInt(document.getElementById('darea').style.width) * ratio + 'px' + + printCtrl.sketch(config, null) + } + + resetview () { + const { config, editItemId } = this.state + + printCtrl.sketch(config, editItemId) + } + + /** + * @description 鑾峰彇妯℃澘閰嶇疆淇℃伅 + */ + async loadconfig () { + let param = { + func: 's_PrintTemplateMGetData', + ID: this.state.ID + } + + let result = await Api.getCloudConfig(param) + + if (result.status) { + let _config = '' + if (result.ConfigParam) { + try { + _config = JSON.parse(window.decodeURIComponent(window.atob(result.ConfigParam))) + } catch (e) { + notification.warning({ + top: 92, + message: '閰嶇疆淇℃伅瑙f瀽閿欒锛�', + duration: 10 + }) + _config = '' + } + } + + if (!_config) { + _config = originConfig + } + + _config.name = result.PrintTempName || '' + _config.remark = result.Remark || '' + _config.PrintTempNO = result.PrintTempNO || '' + _config.type = 'Template' + _config.uuid = Utils.getuuid() + + if (result.data && result.data[0] && result.data[0].TableName) { + this.loadFields(result.data[0].TableName) + } + + this.setState({ + config: _config, + editItemId: _config.uuid, + editItemType: _config.type, + formlist: getpageform(_config) + }, () => { + this.resetbox() + }) + } else { + notification.warning({ + top: 92, + message: result.ErrMesg, + duration: 10 + }) + } + } + + /** + * @description 鑾峰彇鍙敤瀛楁 + */ + async loadFields (TBName) { + let param = { + func: 'sPC_Get_FieldName', + TBName: TBName + } + + let result = await Api.getCloudConfig(param) + + if (result.status) { + let _fields = [{ + value: '', + text: '绌�', + type: '' + }] + let _f = new Map() + + result.FDName.forEach(item => { + if (item.FieldName && !_f.has(item.FieldName)) { + _f.set(item.FieldName, true) + + _fields.push({ + value: item.FieldName, + text: item.FieldDec, + type: item.FieldType + }) + } + }) + + this.setState({ + fields: _fields + }) + } else { + notification.warning({ + top: 92, + message: result.ErrMesg, + duration: 10 + }) + } + } + + dropcard = (item) => { + const { config } = this.state + + let position = null + + if (dropPoint) { + position = dropPoint + dropPoint = null + } else { + return + } + + let _width = Math.floor(config.width / 4) + let _height = Math.floor(_width / 2) + let _cx = Math.floor(position.cx - _width / 2) + let _cy = Math.floor(position.cy - _height / 2) + + if (_cx < 0) { // 鍏冪礌娣诲姞鏃讹紝閬垮厤瓒呭嚭杈圭晫 + _cx = 0 + } else if (_cx + _width > config.width) { + _cx = Math.floor(config.width - _width) + } + + if (_cy < 0) { + _cy = 0 + } else if (_cy + _height > config.height) { + _cy = Math.floor(config.height - _height) + } + + let _selectItem = null + let _formlist = null + if (item.subType === 'text') { + _selectItem = getElement(item.subType, Utils.getuuid(), _cx, _cy, _width, _height) + _formlist = getTextForm(_selectItem, this.state.fields) + } else if (item.subType === 'barcode') { + _selectItem = getElement(item.subType, Utils.getuuid(), _cx, _cy, _width, _height, barurl, config.width) + _formlist = getBarcodeForm(_selectItem, this.state.fields) + } else if (item.subType === 'qrcode') { + _selectItem = getElement(item.subType, Utils.getuuid(), _cx, _cy, _width, _height, qrurl) + _formlist = getQrcodeForm(_selectItem, this.state.fields) + } else if (item.subType === 'image') { + _selectItem = getElement(item.subType, Utils.getuuid(), _cx, _cy, _width, _height, imgurl) + _formlist = getImageForm(_selectItem, this.state.fields) + } + + config.elements.push(_selectItem) + + this.setState({ + config: config, + editItemId: _selectItem.uuid, + editItemType: _selectItem.type, + formlist: _formlist + }, () => { + this.resetview() + }) + + } + + resetItem = (item) => { + let _item = JSON.parse(JSON.stringify(item)) + const { config } = this.state + + let _boxwidth = +config.width + let _boxheight = +config.height + let _left = +_item.left + let _top = +_item.top + let _width = +_item.width + let _height = +_item.height + + if (_left < 0) { + _item.left = 0 + } + if (_top < 0) { + _item.top = 0 + } + + if (_left + _width > _boxwidth) { + _item.width = _boxwidth - _left + } + + if (_top + _height > _boxheight) { + _item.height = _boxheight - _top + } + + if (_item.type === 'barcode') { + if (+_item.barcodeWidth > +_item.width) { + _item.barcodeWidth = +_item.width + } + if (+_item.barcodeHeight > +_item.height) { + _item.barcodeHeight = +_item.height + } + } else if (_item.type === 'qrcode') { + if (+_item.qrcodeWidth > +_item.width) { + _item.qrcodeWidth = +_item.width + } + if (+_item.qrcodeWidth > +_item.height) { + _item.qrcodeWidth = +_item.height + } + } else if (_item.type === 'image') { + if (+_item.imgWidth > +_item.width) { + _item.imgWidth = +_item.width + } + if (+_item.imgHeight > +_item.height) { + _item.imgHeight = +_item.height + } + } + + return _item + } + + handleSubmit = () => { + const { config } = this.state + + this.FormRef.handleConfirm().then(res => { + if (res.type === 'Template') { + res.width = parseInt(res.width) + res.height = parseInt(res.height) + + if (res.width < 1) { + res.width = 1 + this.FormRef.resetForm({width: 1}) + } else if (res.height < 1) { + res.height = 1 + this.FormRef.resetForm({height: 1}) + } + + this.setState({ + config: {...config, ...res} + }, () => { + if (res.width !== config.width || res.height !== config.height) { + this.resetbox() + } + }) + } else { + if (res.type === 'barcode') { + res.url = barurl + } else if (res.type === 'qrcode') { + res.url = qrurl + } else if (res.type === 'image') { + res.url = imgurl + } + + let result = this.resetItem(res) + + if (!is(fromJS(result), fromJS(res))) { + this.FormRef.resetForm(result) + } + + config.elements = config.elements.map(item => { + if (item.uuid === result.uuid) return result + + return item + }) + + this.setState({ + config: config + }, () => { + this.resetview() + }) + } + }) + } + + deleteItem = () => { + const _this = this + const { editItemId, config } = this.state + + confirm({ + title: '纭畾鍒犻櫎璇ュ厓绱犲悧锛�', + okText: '纭畾', + cancelText: '鍙栨秷', + onOk() { + config.elements = config.elements.filter(item => item.uuid !== editItemId) + + _this.setState({ + config: config, + editItemId: config.uuid, + editItemType: config.type, + formlist: getpageform(config) + }, () => { + _this.resetview() + }) + }, + onCancel() {} + }) + } + + submitConfig = () => { + const { config } = this.state + + if (config.height / config.width > 10 || config.width / config.height > 10) { + notification.warning({ + top: 92, + message: '绾稿紶绾垫í姣斾笉鍙秴杩�10!', + duration: 10 + }) + return + } + + this.setState({ + saveloading: true + }) + + let _config = '' + + try { + _config = window.btoa(window.encodeURIComponent(JSON.stringify(config))) + } catch { + notification.warning({ + top: 92, + message: '缂栬瘧閿欒!', + duration: 10 + }) + return + } + + let param = { + func: 's_PrintTemplateMSub', + ID: this.state.ID, + ConfigParam: _config, + Images: '', + PrintTempName: config.name, + Remark: config.remark, + PrintTempNO: config.PrintTempNO + } + + new Promise(resolve => { + printCtrl.sketch(config, null).then(res => { + Api.fileuploadbase64(res, 'cloud').then(result => { // 鍥剧墖涓婁紶锛屽苟鑾峰彇鍥剧墖璺緞 + if (result.status) { + resolve(Utils.getcloudurl(result.Images)) + } else { + // notification.warning({ + // top: 92, + // message: result.ErrMesg, + // duration: 10 + // }) + // this.setState({ + // saveloading: false + // }) + // resolve(false) + resolve(true) + } + }) + }) + }).then(res => { + if (!res) return + param.Images = 'http://css.positecgroup.com/Content/Upload/2020-01-08/2020010810525808769824_U000000001.png' + + return Api.getCloudConfig(param) + }).then(res => { + if (!res) return + + if (res.status) { + notification.success({ + top: 92, + message: '淇濆瓨鎴愬姛', + duration: 2 + }) + } else { + notification.warning({ + top: 92, + message: res.ErrMesg, + duration: 10 + }) + } + this.setState({ + saveloading: false + }) }) } @@ -62,10 +710,33 @@ })} </Card> </aside> + <DragElement dropcard={this.dropcard} /> <aside className="setting"> - <Card title="鐘舵�佹爮"> - - </Card> + {this.state.editItemId ? + <Card title="鐘舵�佹爮"> + {this.state.formlist ? + <MutilForm + config={this.state.config} + formlist={this.state.formlist} + inputSubmit={this.handleSubmit} + editItem={{uuid: this.state.editItemId, type: this.state.editItemType}} + wrappedComponentRef={(inst) => this.FormRef = inst} + /> : null + } + <div className="operation"> + {this.state.editItemType === 'Template' ? + <Row gutter={24}> + <Button type="primary" onClick={this.submitConfig} loading={this.state.saveloading}>淇濆瓨</Button> + </Row> : null + } + {this.state.editItemType !== 'Template' ? + <Row gutter={24}> + <Button type="danger" onClick={this.deleteItem}>鍒犻櫎</Button> + </Row> : null + } + </div> + </Card> : null + } </aside> </DndProvider> </div> diff --git a/src/views/printTemplate/index.scss b/src/views/printTemplate/index.scss index a742905..3eb4643 100644 --- a/src/views/printTemplate/index.scss +++ b/src/views/printTemplate/index.scss @@ -1,7 +1,8 @@ .print-template { overflow-x: hidden; min-height: 100%; - padding: 48px 250px 0px 240px; + padding: 75px 250px 30px 240px; + text-align: center; .print-header-container { position: fixed; @@ -23,6 +24,7 @@ top: 47px; left: -1px; bottom: 0px; + text-align: left; .ant-card { height: 100%; .ant-card-head { @@ -38,11 +40,12 @@ } } .setting { - width: 250px; + width: 300px; position: fixed; top: 47px; right: -1px; bottom: 0px; + text-align: left; .ant-card { height: 100%; .ant-card-head { @@ -52,9 +55,38 @@ .ant-card-head-title { padding: 10px 0; } - .ant-card-body { - padding: 24px 12px; + .operation { + text-align: center; + .ant-btn { + height: 35px; + padding: 0px 35px; + } } + .ant-card-body { + overflow-y: auto; + height: calc(100% - 48px); + padding: 10px 12px 20px; + } + .ant-card-body::-webkit-scrollbar { + width: 7px; + } + .ant-card-body::-webkit-scrollbar-thumb { + border-radius: 5px; + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13); + background-color: #f90; + background-image: -webkit-linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent); + } + .ant-card-body::-webkit-scrollbar-track { + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05); + border-radius: 3px; + border: 1px solid rgba(0, 0, 0, 0.07); + background: rgba(0, 0, 0, 0); + } + + } + .ant-form-item { + margin-bottom: 10px; } } + } \ No newline at end of file diff --git a/src/views/printTemplate/mutilform/index.jsx b/src/views/printTemplate/mutilform/index.jsx new file mode 100644 index 0000000..2d3dbf0 --- /dev/null +++ b/src/views/printTemplate/mutilform/index.jsx @@ -0,0 +1,257 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Form, Row, Col, Input, InputNumber, Select } from 'antd' +import { formRule } from '@/utils/option.js' +import FileUpload from '../fileupload' +import './index.scss' + +const { TextArea } = Input + +class MainSearch extends Component { + static propTpyes = { + config: PropTypes.object, // input鍥炶溅鎻愪氦 + inputSubmit: PropTypes.func, // input鍥炶溅鎻愪氦 + editItem: PropTypes.object, // input鍥炶溅鎻愪氦 + formlist: PropTypes.array // input鍥炶溅鎻愪氦 + } + + UNSAFE_componentWillReceiveProps(nextProps) { + if (!is(fromJS(this.props.editItem), fromJS(nextProps.editItem))) { + this.setState({}, () => { + let fieldsvalue = {} + nextProps.formlist.forEach(item => { + if (!item.key) return + + fieldsvalue[item.key] = item.initval + }) + this.props.form.setFieldsValue(fieldsvalue) + }) + } + } + + selectChange = (item, value) => { + if (item.key === 'papertype') { + let option = item.options.filter(op => op.value === value)[0] + + this.props.form.setFieldsValue({ + width: option.width, + height: option.height + }) + } + this.handleSubmit() + } + + resetForm = (param) => { + let _param = JSON.parse(JSON.stringify(param)) + delete _param.type + delete _param.uuid + delete _param.url + + this.props.form.setFieldsValue(_param) + } + + getFields() { + const { getFieldDecorator } = this.props.form + const fields = [] + + this.props.formlist.forEach((item, index) => { + + if (item.type === 'title') { + fields.push( + <Col span={24} key={index}> + <Form.Item label={item.label} style={{margin: '0px'}}> + {item.initval} + </Form.Item> + </Col> + ) + } else if (item.type === 'text') { + let _rules = [] + if (item.regular) { + if (item.regular === 'number') { + _rules = [{ + pattern: /^[0-9]*$/ig, + message: formRule.input.numbermsg + }] + } else if (item.regular === 'letter') { + _rules = [{ + pattern: /^[a-zA-Z]*$/ig, + message: formRule.input.lettermsg + }] + } else if (item.regular === 'letter&number') { + _rules = [{ + pattern: /^[a-zA-Z0-9]*$/ig, + message: formRule.input.letternummsg + }] + } + } + fields.push( + <Col span={24} key={index}> + <Form.Item label={item.label}> + {getFieldDecorator(item.key, { + initialValue: item.initval || '', + rules: [ + { + required: !!item.required, + message: '璇疯緭鍏�' + item.label + '!' + }, + { + max: 512, + message: formRule.input.formMessage.replace('@max', 512) + }, + ..._rules + ] + })(<Input placeholder="" autoComplete="off" onChange={this.handleSubmit} />)} + </Form.Item> + </Col> + ) + } else if (item.type === 'number') { // 鏁板瓧 + let min = item.min || 0 + + fields.push( + <Col span={24} key={index}> + <Form.Item label={item.label}> + {getFieldDecorator(item.key, { + initialValue: item.initval, + rules: [ + { + required: true, + message: '璇疯緭鍏�' + item.label + '!' + } + ] + })(<InputNumber min={min} precision={item.precision} onChange={(value) => {this.handleSubmit('number', value)}} />)} + </Form.Item> + </Col> + ) + } else if (item.type === 'select') { // 涓嬫媺鎼滅储 + fields.push( + <Col span={24} key={index}> + <Form.Item label={item.label}> + {getFieldDecorator(item.key, { + initialValue: item.initval, + rules: [ + { + required: !!item.required, + message: '璇烽�夋嫨' + item.label + '!' + } + ] + })( + <Select + showSearch + filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} + getPopupContainer={() => document.getElementById('print-form-box')} + onChange={(value) => this.selectChange(item, value)} + > + {item.options.map(option => + <Select.Option id={option.value} title={option.text} key={option.value} value={option.value}>{option.text}</Select.Option> + )} + </Select> + )} + </Form.Item> + </Col> + ) + } else if (item.type === 'fileupload') { + let filelist = this.props.data ? this.props.data[item.field] : item.initval + if (filelist && this.state.readin[item.field]) { + try { + filelist = filelist.split(',').map((url, index) => { + return { + uid: `${index}`, + name: url.slice(url.lastIndexOf('/') + 1), + status: 'done', + url: url, + origin: true + } + }) + } catch { + filelist = [] + } + } else { + filelist = [] + } + + fields.push( + <Col span={24} key={index}> + <Form.Item label={item.label}> + {getFieldDecorator(item.key, { + initialValue: filelist, + rules: [ + { + required: item.required, + message: '璇烽�夋嫨' + item.label + '!' + } + ] + })( + <FileUpload /> + )} + </Form.Item> + </Col> + ) + } else if (item.type === 'textarea') { + fields.push( + <Col span={24} key={index}> + <Form.Item label={item.label} > + {getFieldDecorator(item.key, { + initialValue: item.initval || '', + rules: [ + { + required: !!item.required, + message: '璇疯緭鍏�' + item.label + '!' + }, + { + max: 1024, + message: formRule.input.formMessage.replace('@max', 1024) + } + ] + })(<TextArea autosize={{ minRows: 2, maxRows: 6 }} onChange={this.handleSubmit} />)} + </Form.Item> + </Col> + ) + } + }) + + return fields + } + + handleConfirm = () => { + // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭� + return new Promise((resolve, reject) => { + this.props.form.validateFieldsAndScroll((err, values) => { + if (!err) { + values.uuid = this.props.editItem.uuid + values.type = this.props.editItem.type + + resolve(values) + } + }) + }) + } + + handleSubmit = (type, value) => { + if (type === 'number' && isNaN(parseInt(value))) return + + this.setState({}, () => { + this.props.inputSubmit() + }) + } + + render() { + const formItemLayout = { + labelCol: { + xs: { span: 24 }, + sm: { span: 8 } + }, + wrapperCol: { + xs: { span: 24 }, + sm: { span: 16 } + } + } + return ( + <Form {...formItemLayout} className="print-setting-contrl" id="print-form-box"> + <Row gutter={24}>{this.getFields()}</Row> + </Form> + ) + } +} + +export default Form.create()(MainSearch) \ No newline at end of file diff --git a/src/views/printTemplate/mutilform/index.scss b/src/views/printTemplate/mutilform/index.scss new file mode 100644 index 0000000..2b92a82 --- /dev/null +++ b/src/views/printTemplate/mutilform/index.scss @@ -0,0 +1,50 @@ +.print-setting-contrl { + position: relative; + padding: 0px 0px 20px; + .ant-form-item { + display: flex; + } + .ant-form-item-control-wrapper { + flex: 1; + } + .ant-form-item-label { + overflow: hidden; + display: inline-block; + text-overflow: ellipsis; + white-space: nowrap; + } + // .textarea-row { + // .ant-col-sm-3 { + // width: 10.5%; + // } + // .ant-col-sm-21 { + // width: 89.5%; + // } + // } + .ant-input-number { + width: 100%; + } + .ant-form-explain { + overflow:hidden; + text-overflow:ellipsis; + white-space:nowrap; + } + p { + color: #1890ff; + border-bottom: 1px solid #d9d9d9; + } + .ant-input-disabled { + color: rgba(0, 0, 0, 0.65)!important; + cursor: default!important; + } + .ant-input-number-input { + color: rgba(0, 0, 0, 0.65)!important; + cursor: default!important; + } + .ant-select-disabled { + color: rgba(0, 0, 0, 0.65)!important; + .ant-select-selection--multiple .ant-select-selection__choice { + color: rgba(0, 0, 0, 0.65)!important; + } + } +} \ No newline at end of file diff --git a/src/views/printTemplate/option.js b/src/views/printTemplate/option.js new file mode 100644 index 0000000..ca9317b --- /dev/null +++ b/src/views/printTemplate/option.js @@ -0,0 +1,862 @@ +const Fontweight = [ + { + text: 'normal', + value: 'normal' + }, { + text: 'bold', + value: 'bold' + }, { + text: 'bolder', + value: 'bolder' + }, { + text: 'lighter', + value: 'lighter' + } +] +const Color = [ + { + text: '榛戣壊', + value: 'black' + }, { + text: '绾㈣壊', + value: 'red' + }, { + text: '鐏拌壊', + value: 'gray' + }, { + text: '钃濊壊', + value: 'blue' + }, { + text: '缁胯壊', + value: 'green' + }, { + text: '鐧借壊', + value: 'white' + } +] +const Fontfamily = [ + { + text: '瀹嬩綋', + value: 'SimSun' + }, { + text: '寰蒋闆呴粦', + value: 'Microsoft YaHei' + }, { + text: '榛戜綋', + value: 'SimHei' + }, { + text: '寰蒋姝i粦浣�', + value: 'Microsoft JhengHei' + }, { + text: '鏂板畫浣�', + value: 'NSimSun' + }, { + text: '浠垮畫', + value: 'FangSong' + }, { + text: '妤蜂綋', + value: 'KaiTi' + } +] +const Rotate = [ + { + text: '0搴�', + value: 0 + }, { + text: '90搴�', + value: 90 + }, { + text: '180搴�', + value: 180 + }, { + text: '270搴�', + value: 270 + } +] +const Align = [ + { + text: '宸﹀榻�', + value: 'left' + }, { + text: '鍙冲榻�', + value: 'right' + }, { + text: '灞呬腑瀵归綈', + value: 'center' + }, { + text: '涓ょ瀵归綈', + value: 'justify' + } +] +const Barcodealign = [ + { + text: '宸﹀榻�', + value: 'left' + }, { + text: '鍙冲榻�', + value: 'right' + }, { + text: '灞呬腑瀵归綈', + value: 'center' + } +] +const VertialAlign = [ + { + text: '椤堕儴瀵归綈', + value: 'top' + }, { + text: '搴曢儴瀵归綈', + value: 'bottom' + }, { + text: '灞呬腑瀵归綈', + value: 'middle' + } +] +const BarcodeType = [ + { + text: 'code128', + value: 'code128' + }, { + text: 'EAN13', + value: 'EAN13' + } +] +const Boolen = [ + { + text: '鏄剧ず', + value: 'true' + }, { + text: '闅愯棌', + value: 'false' + } +] +const QrcodeType = [ + { + text: 'qrcode', + value: 'qrcode' + } +] + +// 妯℃澘鍏冪礌 +export const printItems = [ + { + type: 'print', + label: '鏂� 鏈�', + subType: 'text', + icon: 'file-text' + }, + { + type: 'print', + label: '鏉″舰鐮�', + subType: 'barcode', + icon: 'barcode' + }, + { + type: 'print', + label: '浜岀淮鐮�', + subType: 'qrcode', + icon: 'qrcode' + }, + { + type: 'print', + label: '鍥� 鐗�', + subType: 'image', + icon: 'file-image' + } +] + +// 妯℃澘鍏冪礌 +export const originConfig = { + name: '', + remark: '', + papertype: 'resize', + width: 210, + height: 297, + isreadonly: false, + PrintTempNO: '', + elements: [] +} + +export function getpageform (config) { + return [ + { + type: 'text', + key: 'name', + label: '妯℃澘鍚嶇О', + initval: config.name, + required: true + }, + { + type: 'textarea', + key: 'remark', + label: '鎻忚堪', + initval: config.remark, + required: false + }, + { + type: 'select', + key: 'papertype', + label: '绾稿紶绫诲瀷', + initval: config.papertype, + required: true, + options: [{ + text: 'A0', + value: 'A0', + width: 841, + height: 1189 + }, { + text: 'A1', + value: 'A1', + width: 594, + height: 841 + }, { + text: 'A2', + value: 'A2', + width: 420, + height: 594 + }, { + text: 'A3', + value: 'A3', + width: 297, + height: 420 + }, { + text: 'A4', + value: 'A4', + width: 210, + height: 297 + }, { + text: '80x50', + value: '80x50', + width: 80, + height: 50 + }, { + text: '60x40', + value: '60x40', + width: 60, + height: 40 + }, { + text: '鑷畾涔�', + value: 'resize', + width: 210, + height: 297 + }] + }, + { + type: 'number', + key: 'width', + label: '瀹藉害', + initval: config.width, + min: 1, + required: true + }, + { + type: 'number', + key: 'height', + label: '楂樺害', + initval: config.height, + min: 1, + required: true + } + ] +} + +export function getElement (type, uuid, cx, cy, width, height, url, boxwidth) { + let item = { + uuid: uuid, + type: type, + name: '', + field: '', + left: cx, + top: cy, + width: width, + height: height, + rotate: 0, + borderSize: 1, + borderColor: 'black', + align: 'center', + vertialAlign: 'middle', + background: 'white' + } + + if (type === 'text') { + item.value = '' + item.fontSize = 12 + item.fontWeight = 'normal' + item.fontColor = 'black' + item.fontFamily = 'SimSun' + item.padding = 1 + item.align = 'left' + item.vertialAlign = 'top' + } else if (type === 'barcode') { + item.url = url + item.barcodeType = 'code128' + item.barcodeWidth = Math.floor(width * 0.6) + item.barcodeHeight = Math.floor(height * 0.4) + item.barcodeLabel = 'true' + item.fontSize = Math.floor(12 * (boxwidth / 210)) + } else if (type === 'qrcode') { + item.url = url + item.qrcodeType = 'qrcode' + item.qrcodeWidth = Math.floor(height * 0.6) + } else if (type === 'image') { + item.url = url + item.imgWidth = Math.floor(width * 0.6) + item.imgHeight = Math.floor(height * 0.5) + } + + return item +} + +export function getTextForm (item, fields) { + return [ + { + type: 'title', + label: '绫诲瀷', + initval: '鏂囨湰', + required: false + }, + { + type: 'text', + key: 'name', + label: '鍚嶇О', + initval: item.name || '', + required: false + }, + { + type: 'textarea', + key: 'value', + label: '鍐呭', + initval: item.value || '', + required: false + }, + { + type: 'select', + key: 'field', + label: '鍏宠仈瀛楁', + initval: item.field || '', + required: false, + options: fields + }, + { + type: 'number', + key: 'left', + label: '璺濆乏', + initval: item.left, + precision: 0, + required: true + }, + { + type: 'number', + key: 'top', + label: '璺濅笂', + initval: item.top, + precision: 0, + required: true + }, + { + type: 'number', + key: 'width', + label: '瀹藉害', + initval: item.width, + precision: 0, + required: true + }, + { + type: 'number', + key: 'height', + label: '楂樺害', + initval: item.height, + precision: 0, + required: true + }, + { + type: 'number', + key: 'fontSize', + label: '瀛椾綋澶у皬', + initval: item.fontSize, + precision: 0, + required: true + }, + { + type: 'select', + key: 'fontWeight', + label: '瀛椾綋绮楃粏', + initval: item.fontWeight, + required: false, + options: Fontweight + }, + { + type: 'select', + key: 'fontColor', + label: '瀛椾綋棰滆壊', + initval: item.fontColor, + required: false, + options: Color + }, + { + type: 'select', + key: 'fontFamily', + label: '瀛椾綋鍚嶇О', + initval: item.fontFamily, + required: false, + options: Fontfamily + }, + { + type: 'select', + key: 'rotate', + label: '鏃嬭浆瑙掑害', + initval: item.rotate, + required: false, + options: Rotate + }, + { + type: 'number', + key: 'borderSize', + label: '杈规瀹藉害', + initval: item.borderSize, + precision: 1, + required: true + }, + { + type: 'select', + key: 'borderColor', + label: '杈规棰滆壊', + initval: item.borderColor, + required: false, + options: Color + }, + { + type: 'number', + key: 'padding', + label: '杈硅窛', + initval: item.padding, + precision: 1, + required: true + }, + { + type: 'select', + key: 'align', + label: '姘村钩瀵归綈', + initval: item.align, + required: false, + options: Align + }, + { + type: 'select', + key: 'vertialAlign', + label: '鍨傜洿瀵归綈', + initval: item.vertialAlign, + required: false, + options: VertialAlign + }, + { + type: 'select', + key: 'background', + label: '鑳屾櫙鑹�', + initval: item.background, + required: false, + options: Color + } + ] +} + +export function getBarcodeForm (item, fields) { + return [ + { + type: 'title', + label: '绫诲瀷', + initval: '鏉″舰鐮�', + required: false + }, + { + type: 'text', + key: 'name', + label: '鍚嶇О', + initval: item.name, + required: false + }, + { + type: 'select', + key: 'field', + label: '鍏宠仈瀛楁', + initval: item.field, + required: true, + options: fields + }, + { + type: 'number', + key: 'left', + label: '璺濆乏', + initval: item.left, + precision: 0, + required: true + }, + { + type: 'number', + key: 'top', + label: '璺濅笂', + initval: item.top, + precision: 0, + required: true + }, + { + type: 'number', + key: 'width', + label: '瀹藉害', + initval: item.width, + precision: 0, + required: true + }, + { + type: 'number', + key: 'height', + label: '楂樺害', + initval: item.height, + precision: 0, + required: true + }, + { + type: 'select', + key: 'rotate', + label: '鏃嬭浆瑙掑害', + initval: item.rotate, + required: false, + options: Rotate + }, + { + type: 'number', + key: 'borderSize', + label: '杈规瀹藉害', + initval: item.borderSize, + precision: 1, + required: true + }, + { + type: 'select', + key: 'borderColor', + label: '杈规棰滆壊', + initval: item.borderColor, + required: false, + options: Color + }, + { + type: 'select', + key: 'align', + label: '姘村钩瀵归綈', + initval: item.align, + required: false, + options: Barcodealign + }, + { + type: 'select', + key: 'vertialAlign', + label: '鍨傜洿瀵归綈', + initval: item.vertialAlign, + required: false, + options: VertialAlign + }, + { + type: 'select', + key: 'barcodeType', + label: '缂栫爜绫诲瀷', + initval: item.barcodeType, + required: true, + options: BarcodeType + }, + { + type: 'number', + key: 'barcodeWidth', + label: '鏉$爜瀹藉害', + initval: item.barcodeWidth, + precision: 0, + required: true + }, + { + type: 'number', + key: 'barcodeHeight', + label: '鏉$爜楂樺害', + initval: item.barcodeHeight, + precision: 0, + required: true + }, + { + type: 'select', + key: 'barcodeLabel', + label: '鏉$爜鏍囪瘑', + initval: item.barcodeLabel, + required: true, + options: Boolen + }, + { + type: 'number', + key: 'fontSize', + label: '瀛椾綋澶у皬', + initval: item.fontSize, + precision: 0, + required: true + }, + { + type: 'select', + key: 'background', + label: '鑳屾櫙鑹�', + initval: item.background, + required: false, + options: Color + } + ] +} + +export function getQrcodeForm (item, fields) { + return [ + { + type: 'title', + label: '绫诲瀷', + initval: '浜岀淮鐮�', + required: false + }, + { + type: 'text', + key: 'name', + label: '鍚嶇О', + initval: item.name, + required: false + }, + { + type: 'select', + key: 'field', + label: '鍏宠仈瀛楁', + initval: item.field, + required: true, + options: fields + }, + { + type: 'number', + key: 'left', + label: '璺濆乏', + initval: item.left, + precision: 0, + required: true + }, + { + type: 'number', + key: 'top', + label: '璺濅笂', + initval: item.top, + precision: 0, + required: true + }, + { + type: 'number', + key: 'width', + label: '瀹藉害', + initval: item.width, + precision: 0, + required: true + }, + { + type: 'number', + key: 'height', + label: '楂樺害', + initval: item.height, + precision: 0, + required: true + }, + { + type: 'select', + key: 'rotate', + label: '鏃嬭浆瑙掑害', + initval: item.rotate, + required: false, + options: Rotate + }, + { + type: 'number', + key: 'borderSize', + label: '杈规瀹藉害', + initval: item.borderSize, + precision: 1, + required: true + }, + { + type: 'select', + key: 'borderColor', + label: '杈规棰滆壊', + initval: item.borderColor, + required: false, + options: Color + }, + { + type: 'select', + key: 'align', + label: '姘村钩瀵归綈', + initval: item.align, + required: false, + options: Barcodealign + }, + { + type: 'select', + key: 'vertialAlign', + label: '鍨傜洿瀵归綈', + initval: item.vertialAlign, + required: false, + options: VertialAlign + }, + { + type: 'select', + key: 'qrcodeType', + label: '缂栫爜绫诲瀷', + initval: item.qrcodeType, + required: true, + options: QrcodeType + }, + { + type: 'number', + key: 'qrcodeWidth', + label: '杈归暱', + initval: item.qrcodeWidth, + precision: 0, + required: true + }, + { + type: 'select', + key: 'background', + label: '鑳屾櫙鑹�', + initval: item.background, + required: false, + options: Color + } + ] +} + +export function getImageForm (item, fields) { + return [ + { + type: 'title', + label: '绫诲瀷', + initval: '鍥剧墖', + required: false + }, + { + type: 'text', + key: 'name', + label: '鍚嶇О', + initval: item.name, + required: false + }, + // { + // type: 'text', + // key: 'value', + // label: '鍥剧墖鍦板潃', + // initval: item.value, + // required: false + // }, + { + type: 'select', + key: 'field', + label: '鍏宠仈瀛楁', + initval: item.field, + required: false, + options: fields + }, + { + type: 'number', + key: 'left', + label: '璺濆乏', + initval: item.left, + precision: 0, + required: true + }, + { + type: 'number', + key: 'top', + label: '璺濅笂', + initval: item.top, + precision: 0, + required: true + }, + { + type: 'number', + key: 'width', + label: '瀹藉害', + initval: item.width, + precision: 0, + required: true + }, + { + type: 'number', + key: 'height', + label: '楂樺害', + initval: item.height, + precision: 0, + required: true + }, + { + type: 'select', + key: 'rotate', + label: '鏃嬭浆瑙掑害', + initval: item.rotate, + required: false, + options: Rotate + }, + { + type: 'number', + key: 'borderSize', + label: '杈规瀹藉害', + initval: item.borderSize, + precision: 1, + required: true + }, + { + type: 'select', + key: 'borderColor', + label: '杈规棰滆壊', + initval: item.borderColor, + required: false, + options: Color + }, + { + type: 'select', + key: 'align', + label: '姘村钩瀵归綈', + initval: item.align, + required: false, + options: Barcodealign + }, + { + type: 'select', + key: 'vertialAlign', + label: '鍨傜洿瀵归綈', + initval: item.vertialAlign, + required: false, + options: VertialAlign + }, + { + type: 'number', + key: 'imgWidth', + label: '鍥剧墖瀹藉害', + initval: item.imgWidth, + precision: 0, + required: true + }, + { + type: 'number', + key: 'imgHeight', + label: '鍥剧墖楂樺害', + initval: item.imgHeight, + precision: 0, + required: true + }, + { + type: 'select', + key: 'background', + label: '鑳屾櫙鑹�', + initval: item.background, + required: false, + options: Color + } + ] +} + +export const barurl = require('@/assets/img/barcode.jpg') +export const qrurl = require('@/assets/img/qrcode.png') +export const imgurl = require('@/assets/img/shunfeng.jpg') \ No newline at end of file diff --git a/src/views/printTemplate/print.js b/src/views/printTemplate/print.js new file mode 100644 index 0000000..f6b5be1 --- /dev/null +++ b/src/views/printTemplate/print.js @@ -0,0 +1,407 @@ +export default class Printctrl { + /** + * @description 缁樺埗妯℃澘鑷崇紦瀛� + * @param {Object} configs 閰嶇疆淇℃伅 + * @param {Boolean} selectId 缂栬緫鍏冪礌 + */ + static sketch (configs, selectId) { + if (!configs.height || !configs.width) return + + if (configs.height / configs.width > 10 || configs.width / configs.height > 10) return + + let ratio = parseInt(document.getElementById('darea').style.width) / configs.width * (window.devicePixelRatio || 1) * 1.5 + let sizeradio = 210 / configs.width * (window.devicePixelRatio || 1) * 1.5 + let canvas = document.createElement('canvas') + + canvas.height = configs.height * ratio + canvas.width = configs.width * ratio + let context = canvas.getContext('2d') + + if (configs.elements.length > 0) { + let elements = JSON.parse(JSON.stringify(configs.elements)) + elements.forEach(element => { + element.left = element.left * ratio + element.top = element.top * ratio + element.width = element.width * ratio + element.height = element.height * ratio + + if (element.type === 'text') { + element.padding = element.padding * ratio + element.fontSize = element.fontSize * sizeradio + } else if (element.type === 'barcode') { + element.barcodeWidth = element.barcodeWidth * ratio + element.barcodeHeight = element.barcodeHeight * ratio + element.fontSize = element.fontSize * sizeradio + } else if (element.type === 'qrcode') { + element.qrcodeWidth = element.qrcodeWidth * ratio + } else if (element.type === 'image') { + element.imgWidth = element.imgWidth * ratio + element.imgHeight = element.imgHeight * ratio + } + }) + return new Promise(resolve => { + this.sketchothers(context, elements, selectId, ratio, resolve) + }) + } else { + return new Promise(resolve => { + this.cachesketch(context, resolve) + }) + } + } + + /** + * @description 缁樺埗鍥剧墖鍙婃枃瀛� + * @param {Object} context 鐢诲竷瀵硅薄 + * @param {Object} elements 鍥剧墖鏂囧瓧淇℃伅 + */ + static sketchothers (context, elements, selectId, ratio, resolve) { + let element = elements.splice(0, 1)[0] // 閫愪釜缁樺埗鍥剧墖鏂囧瓧 + let textLineSpace = 5 // 缁樺埗鏃惰闂磋窛锛岄槻姝㈡枃瀛楅噸鍙� + context.save() + + if (element.rotate) { // 鍏冪礌鏃嬭浆鏃讹紝璁剧疆鐢诲竷鏃嬭浆瑙掑害 + let _cx = element.left + element.width / 2 + let _cy = element.top + element.height / 2 + context.translate(_cx, _cy) // 绉诲姩鍘熺偣 + context.rotate(element.rotate * Math.PI / 180) + context.translate(-_cx, -_cy) // 鎭㈠鍘熺偣 + } + + if (selectId === element.uuid) { // 閫変腑鍏冪礌锛岃缃閮ㄩ槾褰� + context.shadowBlur = 10 + context.shadowColor = '#757575' + context.fillStyle = 'white' + context.fillRect(element.left, element.top, element.width, element.height) + context.shadowBlur = 0 + } + + // 缁樺埗杈规 + // context.rect(element.left + element.borderSize / 2, element.top + element.borderSize / 2, element.width - element.borderSize, element.height - element.borderSize) + if (element.borderSize >= 1) { + context.strokeStyle = element.borderColor + context.lineWidth = element.borderSize + context.rect(element.left, element.top, element.width, element.height) + context.stroke() + } + + // 璁剧疆鑳屾櫙鑹� + if (element.background && element.background !== 'white') { + context.fillStyle = element.background + context.fillRect(element.left, element.top, element.width, element.height) + } + + if (selectId === element.uuid && element.width > 3 * ratio && element.height > 3 * ratio) { // 閫変腑鍏冪礌锛岃缃閮ㄩ槾褰� + context.strokeStyle = 'black' + context.beginPath() + context.moveTo(element.left + element.width - 7, element.top + element.height - 2) + context.lineTo(element.left + element.width - 2, element.top + element.height - 7) + context.moveTo(element.left + element.width - 14, element.top + element.height - 2) + context.lineTo(element.left + element.width - 2, element.top + element.height - 14) + context.stroke() + } + + if (!element.width || !element.height) { + context.restore() // 閲嶇疆鐢诲竷 + if (elements.length > 0) { + this.sketchothers(context, elements, selectId, ratio, resolve) + } else { + this.cachesketch(context, resolve) + } + } else if (element.type === 'text') { + // 缁樺埗鏂囧瓧淇℃伅 + if (element.fontSize < 12) { // 娴忚鍣ㄦ渶灏忓瓧浣� + textLineSpace += 12 - element.fontSize + } + // italic 鏂滀綋 small-caps(鑻辨枃灏忓啓瀛楁瘝鍙樻垚灏忕殑澶у啓) + context.font = 'normal normal ' + element.fontWeight + ' ' + element.fontSize + 'px ' + element.fontFamily + context.fillStyle = element.fontColor + + let lines = element.value.split('\n') + let _y = element.top + element.padding + element.fontSize + element.borderSize + let _left = element.left + element.borderSize + element.padding + let _right = element.left + element.width - element.padding - element.borderSize + let _width = _right - _left + if (element.vertialAlign === 'top') { + lines.forEach(text => { + if (!text) { + _y += element.fontSize + textLineSpace + } + let _textArr = [] + let _text = '' + text.split('').forEach(word => { + if (context.measureText(_text + word).width <= _width) { + _text = _text + word + } else { + _textArr.push(_text) + _text = word + } + }) + _textArr.forEach(word => { + let _l = _left + if (element.align === 'center') { + _l = _left + (_width - context.measureText(word).width) / 2 + } else if (element.align === 'right') { + _l = _right - context.measureText(word).width + } else if (element.align === 'justify') { + _l = _left + (_width - context.measureText(word).width) / 2 + } + context.fillText(word, _l, _y) + _y += element.fontSize + textLineSpace + }) + + if (!_text) { + return + } + + if (element.align === 'left') { + context.fillText(_text, _left, _y) + } else if (element.align === 'center') { + context.fillText(_text, _left + (_width - context.measureText(_text).width) / 2, _y) + } else if (element.align === 'right') { + context.fillText(_text, _right - context.measureText(_text).width, _y) + } else if (element.align === 'justify') { + if (_text.length === 1) { + context.fillText(_text, _left + (_width - context.measureText(_text).width) / 2, _y) + } else { + let _dleft = _left + _text.split('').forEach(_word => { + context.fillText(_word, _dleft, _y) + _dleft += (_width - context.measureText(_text).width) / (_text.length - 1) + context.measureText(_word).width + }) + } + } + + _y += element.fontSize + textLineSpace + }) + } else if (element.vertialAlign === 'middle' || element.vertialAlign === 'bottom') { + let lineheight = 0 + lines.forEach(text => { + if (!text) { + lineheight += element.fontSize + textLineSpace + return + } + lineheight += Math.ceil(context.measureText(text).width / _width) * (element.fontSize + textLineSpace) + }) + + if (element.vertialAlign === 'middle') { + _y += (element.height - element.padding * 2 - element.borderSize * 2 - lineheight) / 2 + } else { + _y += element.height - element.padding * 2 - element.borderSize * 2 - lineheight + } + + lines.forEach(text => { + if (!text) { + _y += element.fontSize + textLineSpace + } + let _textArr = [] + let _text = '' + text.split('').forEach(word => { + if (context.measureText(_text + word).width <= _width) { + _text = _text + word + } else { + _textArr.push(_text) + _text = word + } + }) + _textArr.forEach(word => { + let _l = _left + if (element.align === 'center') { + _l = _left + (_width - context.measureText(word).width) / 2 + } else if (element.align === 'right') { + _l = _right - context.measureText(word).width + } else if (element.align === 'justify') { + _l = _left + (_width - context.measureText(word).width) / 2 + } + context.fillText(word, _l, _y) + _y += element.fontSize + textLineSpace + }) + + if (!_text) { + return + } + + if (element.align === 'left') { + context.fillText(_text, _left, _y) + } else if (element.align === 'center') { + context.fillText(_text, _left + (_width - context.measureText(_text).width) / 2, _y) + } else if (element.align === 'right') { + context.fillText(_text, _right - context.measureText(_text).width, _y) + } else if (element.align === 'justify') { + if (_text.length === 1) { + context.fillText(_text, _left + (_width - context.measureText(_text).width) / 2, _y) + } else { + let _dleft = _left + _text.split('').forEach(_word => { + context.fillText(_word, _dleft, _y) + _dleft += (_width - context.measureText(_text).width) / (_text.length - 1) + context.measureText(_word).width + }) + } + } + + _y += element.fontSize + textLineSpace + }) + } + + context.restore() // 閲嶇疆鐢诲竷 + if (elements.length > 0) { + this.sketchothers(context, elements, selectId, ratio, resolve) + } else { + this.cachesketch(context, resolve) + } + } else if (element.type === 'barcode') { + let _space = 5 + let _left = element.left + let _top = element.top + if (element.vertialAlign === 'middle') { + if (element.barcodeLabel === 'true') { + _top = element.top + (element.height - element.barcodeHeight - element.fontSize - _space) / 2 + } else { + _top = element.top + (element.height - element.barcodeHeight) / 2 + } + } else if (element.vertialAlign === 'bottom') { + if (element.barcodeLabel === 'true') { + _top = element.top + (element.height - element.barcodeHeight - element.fontSize - _space) + } else { + _top = element.top + element.height - element.barcodeHeight + } + } + + if (element.align === 'center') { + _left = element.left + (element.width - element.barcodeWidth) / 2 + } else if (element.align === 'right') { + _left = element.left + element.width - element.barcodeWidth + } + context.font = 'normal normal normal ' + element.fontSize + 'px Microsoft YaHei' + context.fillStyle = 'black' + let text = '1234567890123' + let _tleft = _left + (element.barcodeWidth - context.measureText(text).width) / 2 + let _ttop = _top + element.barcodeHeight + _space + element.fontSize + + let image = new Image() + image.src = element.url + if (image.complete) { + context.drawImage(image, _left, _top, element.barcodeWidth, element.barcodeHeight) + if (element.barcodeLabel === 'true') { + context.fillText(text, _tleft, _ttop) + } + + context.restore() // 閲嶇疆鐢诲竷 + if (elements.length > 0) { + this.sketchothers(context, elements, selectId, ratio, resolve) + } else { + this.cachesketch(context, resolve) + } + } else { + image.onload = () => { + context.drawImage(image, _left, _top, element.barcodeWidth, element.barcodeHeight) + if (element.barcodeLabel === 'true') { + context.fillText(text, _tleft, _ttop) + } + + context.restore() // 閲嶇疆鐢诲竷 + if (elements.length > 0) { + this.sketchothers(context, elements, selectId, ratio, resolve) + } else { + this.cachesketch(context, resolve) + } + } + } + } else if (element.type === 'qrcode') { + let _left = element.left + let _top = element.top + if (element.vertialAlign === 'middle') { + _top = element.top + (element.height - element.qrcodeWidth) / 2 + } else if (element.vertialAlign === 'bottom') { + _top = element.top + element.height - element.qrcodeWidth + } + + if (element.align === 'center') { + _left = element.left + (element.width - element.qrcodeWidth) / 2 + } else if (element.align === 'right') { + _left = element.left + element.width - element.qrcodeWidth + } + + let image = new Image() + image.src = element.url + + if (image.complete) { + context.drawImage(image, _left, _top, element.qrcodeWidth, element.qrcodeWidth) + + context.restore() // 閲嶇疆鐢诲竷 + if (elements.length > 0) { + this.sketchothers(context, elements, selectId, ratio, resolve) + } else { + this.cachesketch(context, resolve) + } + } else { + image.onload = () => { + context.drawImage(image, _left, _top, element.qrcodeWidth, element.qrcodeWidth) + + context.restore() // 閲嶇疆鐢诲竷 + if (elements.length > 0) { + this.sketchothers(context, elements, selectId, ratio, resolve) + } else { + this.cachesketch(context, resolve) + } + } + } + } else if (element.type === 'image') { + let _left = element.left + let _top = element.top + if (element.vertialAlign === 'middle') { + _top = element.top + (element.height - element.imgHeight) / 2 + } else if (element.vertialAlign === 'bottom') { + _top = element.top + element.height - element.imgHeight + } + + if (element.align === 'center') { + _left = element.left + (element.width - element.imgWidth) / 2 + } else if (element.align === 'right') { + _left = element.left + element.width - element.imgWidth + } + + let image = new Image() + image.src = element.value || element.url + + if (image.complete) { + context.drawImage(image, _left, _top, element.imgWidth, element.imgHeight) + + context.restore() // 閲嶇疆鐢诲竷 + if (elements.length > 0) { + this.sketchothers(context, elements, selectId, ratio, resolve) + } else { + this.cachesketch(context, resolve) + } + } else { + image.onload = () => { + context.drawImage(image, _left, _top, element.imgWidth, element.imgHeight) + + context.restore() // 閲嶇疆鐢诲竷 + if (elements.length > 0) { + this.sketchothers(context, elements, selectId, ratio, resolve) + } else { + this.cachesketch(context, resolve) + } + } + } + } + } + + /** + * @description 缁樺埗妯℃澘鍊奸〉闈� + * @param {Object} configs 閰嶇疆淇℃伅 + */ + static cachesketch (context, resolve) { + let cacheCanvas = context.canvas + let canvas = document.getElementById('darea') + canvas.width = cacheCanvas.width + canvas.height = cacheCanvas.height + let ctx = canvas.getContext('2d') + ctx.clearRect(0, 0, canvas.width + 1, canvas.height + 1) + ctx.beginPath() + ctx.fillStyle = 'white' + ctx.fillRect(0, 0, canvas.width + 1, canvas.height + 1) + ctx.drawImage(cacheCanvas, 0, 0, canvas.width, canvas.height) + resolve(canvas.toDataURL('image/png')) + } +} -- Gitblit v1.8.0