From a9ac16fecc0cf9bc66dfaefe4e9b35fa3c722812 Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期二, 10 十一月 2020 16:58:43 +0800 Subject: [PATCH] 2020-11-10 --- src/tabviews/custom/components/card/cardcellList/index.jsx | 51 +++++++ src/tabviews/custom/components/card/prop-card/index.jsx | 18 + package-lock.json | 5 public/index.html | 1 src/menu/components/card/cardcellcomponent/dragaction/index.scss | 8 + src/components/qrcode/index.scss | 5 src/menu/components/card/cardcellcomponent/index.jsx | 18 ++ src/menu/datasource/verifycard/settingform/index.jsx | 4 src/components/qrcode/index.jsx | 53 +++++++ src/menu/components/card/cardcellcomponent/elementform/index.jsx | 7 src/menu/components/card/cardcellcomponent/dragaction/card.jsx | 29 +++ src/menu/components/card/cardcellcomponent/formconfig.jsx | 113 ++++++++++++--- src/templates/zshare/createinterface/index.jsx | 3 package.json | 1 src/tabviews/custom/components/card/cardcellList/index.scss | 6 src/components/barcode/index.scss | 5 src/components/barcode/index.jsx | 53 +++++++ 17 files changed, 340 insertions(+), 40 deletions(-) diff --git a/package-lock.json b/package-lock.json index d3e14d4..89cfc2f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11395,6 +11395,11 @@ "esprima": "^4.0.0" } }, + "jsbarcode": { + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/jsbarcode/-/jsbarcode-3.11.3.tgz", + "integrity": "sha512-TsoeHL/0ASvKE3+sbLuTkT2cGvDV/MsQAQVuGf/1EWKe7SXNYlyzW/3TFeAmqJg/Fhz6pPgrci8o5hR+Ej59Jw==" + }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", diff --git a/package.json b/package.json index f119939..1ed423d 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "jest-environment-jsdom-fourteen": "0.1.0", "jest-resolve": "24.8.0", "jest-watch-typeahead": "0.3.1", + "jsbarcode": "^3.11.3", "md5": "^2.2.1", "mini-css-extract-plugin": "0.5.0", "moment": "^2.24.0", diff --git a/public/index.html b/public/index.html index a5b86ee..f21e263 100644 --- a/public/index.html +++ b/public/index.html @@ -2,6 +2,7 @@ <html lang="en"> <head> <meta charset="utf-8" /> + <meta name="renderer" content="webkit"> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> diff --git a/src/components/barcode/index.jsx b/src/components/barcode/index.jsx new file mode 100644 index 0000000..c7dd144 --- /dev/null +++ b/src/components/barcode/index.jsx @@ -0,0 +1,53 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import JsBarcode from 'jsbarcode' + +import './index.scss' + +class BarCode extends Component { + static propTpyes = { + card: PropTypes.object, // 鏉$爜璁剧疆 + value: PropTypes.any, // 鏉$爜鍊� + } + + componentDidMount () { + this.resetBarcode() + } + + UNSAFE_componentWillReceiveProps (nextProps) { + if ((nextProps.value && this.props.value !== nextProps.value) || !is(fromJS(nextProps.card), fromJS(this.props.card))) { + this.setState({}, () => { + this.resetBarcode() + }) + } + } + + resetBarcode = () => { + const { value, card } = this.props + + let style = card.style || {} + + JsBarcode(this.barcode, value, { + displayValue: card.displayValue === 'true', + width: card.interval || 1, + height: card.barHeight || 25, + margin: 0, + fontOptions: `${style.fontWeight || ''} ${style.fontStyle || ''}`, + textAlign: style.textAlign || 'left', + fontSize: (style.fontSize || 14) + 'px', + lineColor: style.color || '#000000' + }) + + } + + render() { + return ( + <div className="barcode-box"> + <svg ref={(ref) => { this.barcode = ref }}/> + </div> + ) + } +} + +export default BarCode \ No newline at end of file diff --git a/src/components/barcode/index.scss b/src/components/barcode/index.scss new file mode 100644 index 0000000..98b112a --- /dev/null +++ b/src/components/barcode/index.scss @@ -0,0 +1,5 @@ +.barcode-box { + svg { + vertical-align: top; + } +} diff --git a/src/components/qrcode/index.jsx b/src/components/qrcode/index.jsx new file mode 100644 index 0000000..da630b7 --- /dev/null +++ b/src/components/qrcode/index.jsx @@ -0,0 +1,53 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import * as QrCode from 'qrcode.react' + +import './index.scss' + +class BarCode extends Component { + static propTpyes = { + card: PropTypes.object, // 鏉$爜璁剧疆 + value: PropTypes.any, // 鏉$爜鍊� + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.props), fromJS(nextProps)) + } + + hexify = (color) => { + let values = color.replace(/rgba?\(/, '').replace(/\)/, '').replace(/[\s+]/g, '').split(',') + let a = parseFloat(values[3] || 1) + let r = Math.floor(a * parseInt(values[0]) + (1 - a) * 255) + let g = Math.floor(a * parseInt(values[1]) + (1 - a) * 255) + let b = Math.floor(a * parseInt(values[2]) + (1 - a) * 255) + + return '#' + ('0' + r.toString(16)).slice(-2) + ('0' + g.toString(16)).slice(-2) + ('0' + b.toString(16)).slice(-2) + } + + render() { + const { value, card } = this.props + let color = card.color + + if (/rgb/ig.test(color)) { + color = this.hexify(color) + } + + return ( + <div className="qrcode-box"> + <QrCode + value={value} + size={card.qrWidth || 50} + fgColor={color} + imageSettings={card.url ? { + src: card.url, + height: (card.qrWidth || 50) / 4, + width: (card.qrWidth || 50) / 4, + excavate: true + } : null}/> + </div> + ) + } +} + +export default BarCode \ No newline at end of file diff --git a/src/components/qrcode/index.scss b/src/components/qrcode/index.scss new file mode 100644 index 0000000..efe8352 --- /dev/null +++ b/src/components/qrcode/index.scss @@ -0,0 +1,5 @@ +.qrcode-box { + canvas { + vertical-align: top; + } +} \ No newline at end of file diff --git a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx index d5741ea..e71af59 100644 --- a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx +++ b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx @@ -1,13 +1,19 @@ import React from 'react' import { useDrag, useDrop } from 'react-dnd' import { Icon, Popover } from 'antd' -import './index.scss' +import moment from 'moment' import demo1 from '@/assets/img/demo1.jpg' import demo2 from '@/assets/img/demo2.jpg' import demo3 from '@/assets/img/demo3.jpg' import demo4 from '@/assets/img/demo4.jpg' import demo5 from '@/assets/img/demo5.jpg' +import asyncComponent from '@/utils/asyncComponent' + +import './index.scss' + +const BarCode = asyncComponent(() => import('@/components/barcode')) +const QrCode = asyncComponent(() => import('@/components/qrcode')) const Card = ({ id, cardIds, card, moveCard, findCard, editCard, delCard, copyCard, changeStyle }) => { const originalIndex = findCard(id).index @@ -94,9 +100,28 @@ <div className="ant-mk-picture" style={_imagestyle}></div> ) } else if (card.eleType === 'splitline') { + let _borderWidth = card.borderWidth === undefined ? 1 : card.borderWidth return ( <div style={{paddingTop: '1px'}}> - <div className="ant-mk-splitline" style={{borderColor: card.color}}></div> + <div className="ant-mk-splitline" style={{borderColor: card.color, borderWidth: _borderWidth}}></div> + </div> + ) + } else if (card.eleType === 'barcode') { + return ( + <div style={{height: card.innerHeight || 25}}> + <BarCode card={card} value={card.value || 'mksoft'}/> + </div> + ) + } else if (card.eleType === 'qrcode') { + return ( + <div style={{minHeight: card.qrWidth || 50}}> + <QrCode card={card} value={card.value || 'mksoft'}/> + </div> + ) + } else if (card.eleType === 'currentDate') { + return ( + <div className="ant-mk-date"> + {`${card.prefix || ''}${moment().format(card.dateFormat)}${card.postfix || ''}`} </div> ) } diff --git a/src/menu/components/card/cardcellcomponent/dragaction/index.scss b/src/menu/components/card/cardcellcomponent/dragaction/index.scss index 7f5a539..1d8b187 100644 --- a/src/menu/components/card/cardcellcomponent/dragaction/index.scss +++ b/src/menu/components/card/cardcellcomponent/dragaction/index.scss @@ -92,6 +92,14 @@ border-left: 0; border-right: 0; } + .ant-mk-date { + white-space: nowrap; + overflow: hidden; + word-break: break-word; + text-overflow: ellipsis; + font-weight: inherit; + font-style: inherit; + } .ant-mk-picture { background-size: cover; background-position: center center; diff --git a/src/menu/components/card/cardcellcomponent/elementform/index.jsx b/src/menu/components/card/cardcellcomponent/elementform/index.jsx index d2748f7..25490a1 100644 --- a/src/menu/components/card/cardcellcomponent/elementform/index.jsx +++ b/src/menu/components/card/cardcellcomponent/elementform/index.jsx @@ -16,7 +16,10 @@ icon: ['eleType', 'icon', 'datatype', 'width'], link: ['eleType', 'datatype', 'label', 'width', 'height', 'joint'], slider: ['eleType', 'datatype', 'width', 'color', 'maxValue'], - splitline: ['eleType', 'color', 'width'], + splitline: ['eleType', 'color', 'width', 'borderWidth'], + barcode: ['eleType', 'datatype', 'width', 'barHeight', 'displayValue', 'interval'], + qrcode: ['eleType', 'datatype', 'width', 'qrWidth', 'color', 'url'], + currentDate: ['eleType', 'width', 'dateFormat', 'prefix', 'postfix'], } class MainSearch extends Component { @@ -73,7 +76,7 @@ getOptions = (eleType, datatype) => { let _options = fromJS(cardTypeOptions[eleType]).toJS() // 閫夐」鍒楄〃 - if (['text', 'number', 'picture', 'link', 'slider'].includes(eleType)) { + if (['text', 'number', 'picture', 'link', 'slider', 'barcode', 'qrcode'].includes(eleType)) { if (datatype === 'dynamic') { _options.push('field') } else if (eleType !== 'picture') { diff --git a/src/menu/components/card/cardcellcomponent/formconfig.jsx b/src/menu/components/card/cardcellcomponent/formconfig.jsx index 5e01655..cfb5189 100644 --- a/src/menu/components/card/cardcellcomponent/formconfig.jsx +++ b/src/menu/components/card/cardcellcomponent/formconfig.jsx @@ -19,6 +19,9 @@ { value: 'link', text: '閾炬帴'}, { value: 'slider', text: '杩涘害鏉�'}, { value: 'splitline', text: '鍒嗗壊绾�'}, + { value: 'barcode', text: '鏉″舰鐮�'}, + { value: 'qrcode', text: '浜岀淮鐮�'}, + { value: 'currentDate', text: '褰撳墠鏃堕棿'}, ] if (type === 'table') { @@ -95,6 +98,14 @@ options: [] }, { + type: 'text', + key: 'value', + min: 0, + label: '鍐呭', + initVal: card.value || '', + required: true + }, + { type: 'file', key: 'url', label: '鍥剧墖', @@ -104,18 +115,38 @@ }, { type: 'text', - key: 'value', - min: 0, - label: '鍐呭', - initVal: card.value || '', - required: true - }, - { - type: 'text', key: 'label', label: '鏄剧ず淇℃伅', initVal: card.label || '', required: false + }, + { + type: 'select', + key: 'format', + label: '鏍煎紡鍖�', + initVal: card.format || '', + tooltip: '娉細鐧惧垎鏁般�佸崈鍒嗕綅瀵逛簬鏁板�肩被鍨嬫湁鏁堬紝YYYY-MM-DD瀵逛簬鏃堕棿绫诲瀷鐨勬枃鏈湁鏁堛��', + required: false, + options: [ + { value: '', text: '鏃�' }, + { value: 'percent', text: '鐧惧垎鏁�' }, + { value: 'thdSeparator', text: '鍗冨垎浣�' }, + { value: 'YYYY-MM-DD', text: 'YYYY-MM-DD' } + ] + }, + { + type: 'select', + key: 'dateFormat', + label: '鏍煎紡鍖�', + initVal: card.dateFormat || 'YYYY-MM-DD', + required: true, + options: [ + { value: 'YYYY-MM-DD', text: 'YYYY-MM-DD' }, + { value: 'YYYY', text: 'YYYY' }, + { value: 'YYYY-MM', text: 'YYYY-MM' }, + { value: 'YYYY-MM-DD HH:mm', text: 'YYYY-MM-DD HH:mm' }, + { value: 'YYYY-MM-DD HH:mm:ss', text: 'YYYY-MM-DD HH:mm:ss' }, + ] }, { type: 'text', @@ -140,24 +171,10 @@ required: false }, { - type: 'select', - key: 'format', - label: '鏍煎紡鍖�', - initVal: card.format || '', - tooltip: '娉細鐧惧垎鏁般�佸崈鍒嗕綅瀵逛簬鏁板�肩被鍨嬫湁鏁堬紝YYYY-MM-DD瀵逛簬鏃堕棿绫诲瀷鐨勬枃鏈湁鏁堛��', - required: false, - options: [ - { value: '', text: '鏃�' }, - { value: 'percent', text: '鐧惧垎鏁�' }, - { value: 'thdSeparator', text: '鍗冨垎浣�' }, - { value: 'YYYY-MM-DD', text: 'YYYY-MM-DD' } - ] - }, - { type: 'color', key: 'color', label: '棰滆壊', - initVal: card.color, + initVal: card.color || 'rgba(0, 0, 0, 0.85)', required: true }, { @@ -175,7 +192,7 @@ min: 1, max: 24, precision: 0, - label: '瀹藉害', + label: '鍏冪礌瀹藉害', initVal: card.width || 12, tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��', required: true @@ -190,6 +207,54 @@ required: true, }, { + type: 'number', + key: 'barHeight', + min: 5, + max: 50, + label: '楂樺害', + initVal: card.barHeight || 25, + required: true, + }, + { + type: 'number', + key: 'qrWidth', + min: 5, + max: 500, + label: '瀹藉害', + initVal: card.qrWidth || 50, + required: true, + }, + { + type: 'number', + key: 'interval', + min: 0.1, + max: 10, + precision: 1, + label: '绾挎潯闂撮殧', + initVal: card.interval || 1, + required: true, + }, + { + type: 'radio', + key: 'displayValue', + label: '鏄剧ず鍊�', + initVal: card.displayValue || 'false', + required: false, + options: [ + { value: 'true', text: '鏄�' }, + { value: 'false', text: '鍚�' } + ] + }, + { + type: 'number', + key: 'borderWidth', + min: 0, + max: 50, + label: '绾垮', + initVal: card.borderWidth || 1, + required: true + }, + { type: 'select', key: 'lenWidRadio', label: '闀垮姣�', diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx index e533b77..3d80bc4 100644 --- a/src/menu/components/card/cardcellcomponent/index.jsx +++ b/src/menu/components/card/cardcellcomponent/index.jsx @@ -146,6 +146,16 @@ } _card.innerHeight = fontSize * lineHeight * line + } else if (_card.eleType === 'barcode') { + _card.style = style + + let fontSize = 14 + + if (_card.style.fontSize) { + fontSize = parseInt(_card.style.fontSize) + } + + _card.innerHeight = _card.barHeight + (_card.displayValue === 'true' ? fontSize + 2 : 0) } else if (_card.eleType === 'button') { // 鎷嗗垎style let _style = fromJS(style).toJS() _card.style = {} @@ -415,6 +425,14 @@ if (res.eleType === 'link' && !res.style.color) { res.style.color = 'rgba(24, 144, 255, 1)' } + } else if (res.eleType === 'barcode') { + let fontSize = 14 + + if (res.style && res.style.fontSize) { + fontSize = parseInt(res.style.fontSize) + } + + res.innerHeight = res.barHeight + (res.displayValue === 'true' ? fontSize + 2 : 0) } return res diff --git a/src/menu/datasource/verifycard/settingform/index.jsx b/src/menu/datasource/verifycard/settingform/index.jsx index 30f8ce9..ac736b0 100644 --- a/src/menu/datasource/verifycard/settingform/index.jsx +++ b/src/menu/datasource/verifycard/settingform/index.jsx @@ -249,10 +249,6 @@ initialValue: setting.varMark || '', rules: [ { - required: true, - message: this.props.dict['form.required.input'] + '鍙橀噺鏍囪瘑!' - }, - { pattern: /^[a-zA-Z_]*$/ig, message: '璇蜂娇鐢ㄥ瓧姣嶆垨_' }, diff --git a/src/tabviews/custom/components/card/cardcellList/index.jsx b/src/tabviews/custom/components/card/cardcellList/index.jsx index ab52d69..05728a2 100644 --- a/src/tabviews/custom/components/card/cardcellList/index.jsx +++ b/src/tabviews/custom/components/card/cardcellList/index.jsx @@ -2,10 +2,12 @@ import PropTypes from 'prop-types' import { is, fromJS } from 'immutable' import { Icon, Col, Tooltip, notification } from 'antd' +import moment from 'moment' import zhCN from '@/locales/zh-CN/model.js' import enUS from '@/locales/en-US/model.js' import asyncComponent from './asyncButtonComponent' +import asyncElementComponent from '@/utils/asyncComponent' import './index.scss' @@ -17,6 +19,8 @@ const NewPageButton = asyncComponent(() => import('@/tabviews/zshare/actionList/newpagebutton')) const ChangeUserButton = asyncComponent(() => import('@/tabviews/zshare/actionList/changeuserbutton')) const PrintButton = asyncComponent(() => import('@/tabviews/zshare/actionList/printbutton')) +const BarCode = asyncElementComponent(() => import('@/components/barcode')) +const QrCode = asyncElementComponent(() => import('@/components/qrcode')) class CardCellComponent extends Component { static propTpyes = { @@ -266,10 +270,55 @@ </Col> ) } else if (card.eleType === 'splitline') { + let _borderWidth = card.borderWidth === undefined ? 1 : card.borderWidth return ( <Col key={card.uuid} span={card.width}> <div style={card.style}> - <div className="ant-mk-splitline" style={{borderColor: card.color}}></div> + <div className="ant-mk-splitline" style={{borderColor: card.color, borderWidth: _borderWidth}}></div> + </div> + </Col> + ) + } else if (card.eleType === 'barcode') { + let val = '' + + if (card.datatype === 'static') { + val = card.value + } else if (data.hasOwnProperty(card.field)) { + val = data[card.field] + } + + return ( + <Col key={card.uuid} span={card.width}> + <div style={card.style}> + <div style={{height: card.innerHeight || 25}}> + {val ? <BarCode card={card} value={val}/> : null} + </div> + </div> + </Col> + ) + } else if (card.eleType === 'qrcode') { + let val = '' + + if (card.datatype === 'static') { + val = card.value + } else if (data.hasOwnProperty(card.field)) { + val = data[card.field] + } + + return ( + <Col key={card.uuid} span={card.width}> + <div style={card.style}> + <div style={{minHeight: card.qrWidth || 50}}> + {val ? <QrCode card={card} value={val}/> : null} + </div> + </div> + </Col> + ) + } else if (card.eleType === 'currentDate') { + return ( + <Col key={card.uuid} span={card.width}> + <div className="ant-mk-date" style={card.style}> + {card.dateFormat ? `${card.prefix || ''}${moment().format(card.dateFormat)}${card.postfix || ''}` : null} </div> </Col> ) diff --git a/src/tabviews/custom/components/card/cardcellList/index.scss b/src/tabviews/custom/components/card/cardcellList/index.scss index c55fce9..79a952f 100644 --- a/src/tabviews/custom/components/card/cardcellList/index.scss +++ b/src/tabviews/custom/components/card/cardcellList/index.scss @@ -97,6 +97,12 @@ border-left: 0; border-right: 0; } + .ant-mk-date { + white-space: nowrap; + overflow: hidden; + word-break: break-word; + text-overflow: ellipsis; + } .ant-slider { margin: 0px; } diff --git a/src/tabviews/custom/components/card/prop-card/index.jsx b/src/tabviews/custom/components/card/prop-card/index.jsx index 765774e..7073848 100644 --- a/src/tabviews/custom/components/card/prop-card/index.jsx +++ b/src/tabviews/custom/components/card/prop-card/index.jsx @@ -40,7 +40,10 @@ _sync = _config.setting.sync === 'true' if (_config.setting.sync === 'true' && data) { - _data = data[_config.dataName] || [] + _data = data[_config.dataName] + if (_data && Array.isArray(_data)) { + _data = _data[0] + } _sync = false } } else { @@ -104,9 +107,12 @@ const { sync, config } = this.state if (sync && !is(fromJS(this.props.data), fromJS(nextProps.data))) { - let _data = [] + let _data = {} if (nextProps.data && nextProps.data[config.dataName]) { - _data = nextProps.data[config.dataName] || [] + _data = nextProps.data[config.dataName] + if (_data && Array.isArray(_data)) { + _data = _data[0] + } } this.setState({sync: false, loading: false, data: _data}) @@ -144,7 +150,7 @@ if (config.wrap.datatype === 'static') { this.setState({ loading: false, - data: [] + data: {} }) return } else { @@ -160,7 +166,7 @@ if (result.status) { this.setState({ activeKey: '', - data: result.data, + data: result.data && result.data[0] ? result.data[0] : {}, loading: false }) } else { @@ -214,7 +220,7 @@ {data ? <div className="card-row-list"> {config.subcards.map((item, index) => ( <Col className={activeKey === index ? 'active' : ''} key={index} span={item.setting.width || 6} onClick={() => {this.changeCard(index, item)}}> - <CardItem BID={BID} card={item} cards={config} data={data[0] || {}} updateStatus={this.updateStatus}/> + <CardItem BID={BID} card={item} cards={config} data={data} updateStatus={this.updateStatus}/> </Col> ))} </div> : null} diff --git a/src/templates/zshare/createinterface/index.jsx b/src/templates/zshare/createinterface/index.jsx index 0100d2f..9efec6b 100644 --- a/src/templates/zshare/createinterface/index.jsx +++ b/src/templates/zshare/createinterface/index.jsx @@ -709,7 +709,8 @@ } _sql = `/* 绯荤粺鐢熸垚 */ Declare @tbid nvarchar(50),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@BillCode nvarchar(50),@BVoucher nvarchar(50),@FIBVoucherDate nvarchar(50), @FiYear nvarchar(50), @UserName nvarchar(50),@FullName nvarchar(50),@ModularDetailCode nvarchar(50)${_declarefields} - + + select @UserName='',@FullName='' select @UserName=UserName,@FullName=FullName from SUsers where UID=@UserID@ ` -- Gitblit v1.8.0