From 9353bc84d8c65da2130db48a2fe48dd714b0acb9 Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期日, 23 五月 2021 00:05:18 +0800 Subject: [PATCH] 2021-05-23 --- src/tabviews/zshare/imgScale/index.scss | 20 src/menu/components/tree/antd-tree/index.scss | 36 + src/menu/components/group/groupcomponents/index.jsx | 9 src/tabviews/custom/components/tree/antd-tree/index.jsx | 483 ++++++++++++++++++++ src/tabviews/zshare/normalTable/index.jsx | 42 src/menu/components/form/normal-form/groupform/index.jsx | 19 src/menu/components/tree/antd-tree/wrapsetting/settingform/index.jsx | 262 ++++++++++ src/menu/components/form/normal-form/index.jsx | 6 src/pc/menushell/index.jsx | 1 src/templates/treepageconfig/index.jsx | 3 src/menu/components/tree/antd-tree/wrapsetting/index.scss | 7 src/menu/components/tabs/tabcomponents/index.jsx | 5 src/mob/components/formdragelement/index.scss | 3 src/menu/components/tree/antd-tree/index.jsx | 188 +++++++ src/menu/menushell/card.jsx | 3 src/tabviews/custom/components/tree/antd-tree/index.scss | 93 +++ src/assets/mobimg/tree.png | 0 src/views/menudesign/index.jsx | 2 src/menu/modulesource/option.jsx | 2 src/tabviews/custom/components/card/data-card/index.jsx | 2 src/menu/components/share/normalheader/index.scss | 11 src/menu/components/tree/antd-tree/wrapsetting/settingform/index.scss | 15 src/menu/components/tree/antd-tree/wrapsetting/index.jsx | 83 +++ src/views/pcdesign/index.jsx | 2 src/menu/components/share/normalheader/index.jsx | 1 src/templates/zshare/formconfig.jsx | 19 src/tabviews/custom/index.jsx | 7 src/menu/menushell/index.jsx | 1 src/tabviews/zshare/imgScale/index.jsx | 65 ++ 29 files changed, 1,357 insertions(+), 33 deletions(-) diff --git a/src/assets/mobimg/tree.png b/src/assets/mobimg/tree.png new file mode 100644 index 0000000..b26f993 --- /dev/null +++ b/src/assets/mobimg/tree.png Binary files differ diff --git a/src/menu/components/form/normal-form/groupform/index.jsx b/src/menu/components/form/normal-form/groupform/index.jsx index 71648f4..488cd6c 100644 --- a/src/menu/components/form/normal-form/groupform/index.jsx +++ b/src/menu/components/form/normal-form/groupform/index.jsx @@ -18,13 +18,22 @@ UNSAFE_componentWillMount () { const { group } = this.props + const { appType } = this.state let fields = [] - group.fields.forEach(f => { - if (f.field && ['select', 'link', 'text', 'number'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') { - fields.push(f) - } - }) + if (appType === 'mob') { + group.fields.forEach(f => { + if (f.field && ['text', 'number'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') { + fields.push(f) + } + }) + } else { + group.fields.forEach(f => { + if (f.field && ['select', 'link', 'text', 'number'].includes(f.type) && f.hidden !== 'true' && f.readonly !== 'true') { + fields.push(f) + } + }) + } this.setState({ fields: fields diff --git a/src/menu/components/form/normal-form/index.jsx b/src/menu/components/form/normal-form/index.jsx index c8b417c..5c7f303 100644 --- a/src/menu/components/form/normal-form/index.jsx +++ b/src/menu/components/form/normal-form/index.jsx @@ -463,7 +463,11 @@ let standardform = null _inputfields = group.fields.filter(item => item.type === 'text' || item.type === 'number' || item.type === 'textarea' || item.type === 'color') - _tabfields = group.fields.filter(item => _form.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) + if (appType === 'mob') { + _tabfields = group.fields.filter(item => _form.field !== item.field && item.hidden !== 'true' && ['text', 'number'].includes(item.type)) + } else { + _tabfields = group.fields.filter(item => _form.field !== item.field && item.hidden !== 'true' && ['text', 'number', 'select', 'link'].includes(item.type)) + } _tabfields.unshift({field: '', text: '鍘熻〃鍗�'}) let uniq = new Map() diff --git a/src/menu/components/group/groupcomponents/index.jsx b/src/menu/components/group/groupcomponents/index.jsx index acffe01..b35112f 100644 --- a/src/menu/components/group/groupcomponents/index.jsx +++ b/src/menu/components/group/groupcomponents/index.jsx @@ -99,13 +99,20 @@ let name = '' let names = { - bar: '鏌辩姸鍥�', + bbar: '鏌辩姸鍥�', line: '鎶樼嚎鍥�', + tabs: '鏍囩缁�', pie: '楗煎浘', + search: '鎼滅储', table: '琛ㄦ牸', + group: '鍒嗙粍', editor: '瀵屾枃鏈�', + code: '鑷畾涔�', + carousel: '杞挱', + form: '琛ㄥ崟', dashboard: '浠〃鐩�', scatter: '鏁g偣鍥�', + tree: '鏍戝舰鍒楄〃', card: '鍗$墖' } let i = 1 diff --git a/src/menu/components/share/normalheader/index.jsx b/src/menu/components/share/normalheader/index.jsx index adac673..bfcc29b 100644 --- a/src/menu/components/share/normalheader/index.jsx +++ b/src/menu/components/share/normalheader/index.jsx @@ -73,6 +73,7 @@ } trigger="hover"> <span className="title">{title}</span> </Popover> + {config.wrap && config.wrap.searchable === 'true' ? <span className="ant-input-search ant-input-affix-wrapper"><span className="ant-input-suffix"><Icon type="search" /></span></span> : null} {hideSearch !== 'true' && config.search ? <SearchComponent config={config} updatesearch={this.props.updateComponent}/> : null} </div> ) diff --git a/src/menu/components/share/normalheader/index.scss b/src/menu/components/share/normalheader/index.scss index ceac790..ca438ed 100644 --- a/src/menu/components/share/normalheader/index.scss +++ b/src/menu/components/share/normalheader/index.scss @@ -16,6 +16,17 @@ min-height: 45px; min-width: 30px; } + .ant-input-search.ant-input-affix-wrapper { + width: calc(100% - 140px); + max-width: 130px; + margin-top: 8px; + margin-right: 25px; + float: right; + height: 28px; + border-radius: 20px; + border: 1px solid #d9d9d9; + opacity: 0.6; + } } .normal-header.hidden { display: none; diff --git a/src/menu/components/tabs/tabcomponents/index.jsx b/src/menu/components/tabs/tabcomponents/index.jsx index 816547b..f25da70 100644 --- a/src/menu/components/tabs/tabcomponents/index.jsx +++ b/src/menu/components/tabs/tabcomponents/index.jsx @@ -89,7 +89,7 @@ let name = '' let names = { - bar: '鏌辩姸鍥�', + bbar: '鏌辩姸鍥�', line: '鎶樼嚎鍥�', tabs: '鏍囩缁�', pie: '楗煎浘', @@ -97,9 +97,12 @@ table: '琛ㄦ牸', group: '鍒嗙粍', editor: '瀵屾枃鏈�', + code: '鑷畾涔�', carousel: '杞挱', + form: '琛ㄥ崟', dashboard: '浠〃鐩�', scatter: '鏁g偣鍥�', + tree: '鏍戝舰鍒楄〃', card: '鍗$墖' } let i = 1 diff --git a/src/menu/components/tree/antd-tree/index.jsx b/src/menu/components/tree/antd-tree/index.jsx new file mode 100644 index 0000000..18f83e7 --- /dev/null +++ b/src/menu/components/tree/antd-tree/index.jsx @@ -0,0 +1,188 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Icon, Popover, Tree } from 'antd' + +import asyncComponent from '@/utils/asyncComponent' +import asyncIconComponent from '@/utils/asyncIconComponent' +import { resetStyle } from '@/utils/utils-custom.js' +import MKEmitter from '@/utils/events.js' +import zhCN from '@/locales/zh-CN/model.js' +import enUS from '@/locales/en-US/model.js' + +import './index.scss' + +const SettingComponent = asyncIconComponent(() => import('@/menu/datasource')) +const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader')) +const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent')) +const UserComponent = asyncIconComponent(() => import('@/menu/components/share/usercomponent')) +const ClockComponent = asyncIconComponent(() => import('@/menu/components/share/clockcomponent')) +const WrapComponent = asyncIconComponent(() => import('./wrapsetting')) + +const { TreeNode } = Tree + +class AntdTree extends Component { + static propTpyes = { + card: PropTypes.object, + deletecomponent: PropTypes.func, + updateConfig: PropTypes.func, + } + + state = { + dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, + card: null, + back: false + } + + UNSAFE_componentWillMount () { + const { card } = this.props + + if (card.isNew) { + let _card = { + uuid: card.uuid, + type: card.type, + floor: card.floor, + tabId: card.tabId || '', + parentId: card.parentId || '', + dataName: card.dataName || '', + format: 'array', // 缁勪欢灞炴�� - 鏁版嵁鏍煎紡 + pageable: false, // 缁勪欢灞炴�� - 鏄惁鍙垎椤� + switchable: true, // 缁勪欢灞炴�� - 鏁版嵁鏄惁鍙垏鎹� + width: card.width || 12, + name: card.name, + subtype: card.subtype, + setting: { interType: 'system' }, + wrap: { name: card.name, title: '', width: card.width || 12, showIcon: 'false', showLine: 'false', searchable: 'false' }, + style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' }, + headerStyle: { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' }, + columns: [], + scripts: [], + } + + if (card.config) { + let config = fromJS(card.config).toJS() + + _card.wrap = config.wrap + _card.wrap.name = card.name + _card.style = config.style + _card.headerStyle = config.headerStyle + } + + this.setState({ + card: _card + }) + this.props.updateConfig(_card) + } else { + this.setState({ + card: fromJS(card).toJS() + }) + } + } + + componentDidMount () { + MKEmitter.addListener('submitStyle', this.getStyle) + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + /** + * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆 + */ + componentWillUnmount () { + this.setState = () => { + return + } + MKEmitter.removeListener('submitStyle', this.getStyle) + } + + /** + * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級 + */ + updateComponent = (component) => { + this.setState({ + card: component + }) + + component.width = component.wrap.width + component.name = component.wrap.name + + this.props.updateConfig(component) + } + + changeStyle = () => { + const { card } = this.state + + MKEmitter.emit('changeStyle', [card.uuid], ['height', 'background', 'border', 'padding', 'margin'], card.style) + } + + getStyle = (comIds, style) => { + const { card } = this.state + + if (comIds[0] !== card.uuid || comIds.length !== 1) return + + let _card = {...card, style} + + this.setState({ + card: _card + }) + + this.props.updateConfig(_card) + } + + /** + * @description 鏇存柊鎼滅储鏉′欢閰嶇疆淇℃伅 + */ + updateconfig = (config) => { + this.setState({ + card: config + }) + this.props.updateConfig(config) + } + + clickComponent = (e) => { + if (sessionStorage.getItem('style-control') === 'true' || sessionStorage.getItem('style-control') === 'component') { + e.stopPropagation() + MKEmitter.emit('clickComponent', this.state.card) + } + } + + render() { + const { card } = this.state + let _style = resetStyle(card.style) + + return ( + <div className="menu-editor-sand-box" style={_style} onClick={this.clickComponent} id={card.uuid}> + <NormalHeader config={card} updateComponent={this.updateComponent}/> + <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ + <div className="mk-popover-control"> + <WrapComponent config={card} updateConfig={this.updateComponent} /> + <CopyComponent type="normaltable" card={card}/> + <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" /> + <ClockComponent config={card} updateConfig={this.updateComponent}/> + <UserComponent config={card}/> + <Icon className="close" title="鍒犻櫎缁勪欢" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} /> + <SettingComponent config={card} updateConfig={this.updateComponent} /> + </div> + } trigger="hover"> + <Icon type="tool" /> + </Popover> + <div className="tree-box"> + <Tree defaultExpandAll={true} blockNode showIcon={card.wrap.showIcon === 'true'} showLine={card.wrap.showLine === 'true'} > + <TreeNode icon={<Icon type="folder-open" />} title="parent 0" key="0-0"> + <TreeNode icon={<Icon type="file" />} title="leaf 0-0" key="0-0-0" isLeaf /> + <TreeNode icon={<Icon type="file" />} title="leaf 0-1" key="0-0-1" isLeaf /> + </TreeNode> + <TreeNode icon={<Icon type="folder-open" />} title="parent 1" key="0-1"> + <TreeNode icon={<Icon type="file" />} title="leaf 1-0" key="0-1-0" isLeaf /> + <TreeNode icon={<Icon type="file" />} title="leaf 1-1" key="0-1-1" isLeaf /> + </TreeNode> + </Tree> + </div> + </div> + ) + } +} + +export default AntdTree \ No newline at end of file diff --git a/src/menu/components/tree/antd-tree/index.scss b/src/menu/components/tree/antd-tree/index.scss new file mode 100644 index 0000000..c096ca8 --- /dev/null +++ b/src/menu/components/tree/antd-tree/index.scss @@ -0,0 +1,36 @@ +.menu-editor-sand-box { + position: relative; + box-sizing: border-box; + background: #ffffff; + background-position: center center; + background-repeat: no-repeat; + background-size: cover; + min-height: 30px; + + .anticon-tool { + position: absolute; + z-index: 2; + font-size: 16px; + right: 1px; + top: 1px; + cursor: pointer; + padding: 5px; + background: rgba(255, 255, 255, 0.55); + } + .empty-content { + text-align: center; + font-size: 30px; + margin: 0; + line-height: 90px; + color: #bcbcbc; + } +} +.menu-editor-sand-box::after { + display: block; + content: ' '; + clear: both; +} +.menu-editor-sand-box:hover { + z-index: 1; + box-shadow: 0px 0px 4px #1890ff; +} diff --git a/src/menu/components/tree/antd-tree/wrapsetting/index.jsx b/src/menu/components/tree/antd-tree/wrapsetting/index.jsx new file mode 100644 index 0000000..595cb9e --- /dev/null +++ b/src/menu/components/tree/antd-tree/wrapsetting/index.jsx @@ -0,0 +1,83 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Icon, Modal } from 'antd' + +import zhCN from '@/locales/zh-CN/model.js' +import enUS from '@/locales/en-US/model.js' +import SettingForm from './settingform' +import './index.scss' + +class DataSource extends Component { + static propTpyes = { + config: PropTypes.any, + updateConfig: PropTypes.func + } + + state = { + dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, + visible: false, + wrap: null + } + + UNSAFE_componentWillMount () { + const { config } = this.props + + this.setState({wrap: fromJS(config.wrap).toJS()}) + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) + } + + editDataSource = () => { + this.setState({ + visible: true + }) + } + + verifySubmit = () => { + const { config } = this.props + + this.verifyRef.handleConfirm().then(res => { + + this.setState({ + wrap: res, + visible: false + }) + this.props.updateConfig({...config, wrap: res}) + }) + } + + render () { + const { config } = this.props + const { visible, dict, wrap } = this.state + + return ( + <div className="model-menu-setting-wrap"> + <Icon type="edit" onClick={() => this.editDataSource()} /> + <Modal + wrapClassName="popview-modal" + title="鍩烘湰璁剧疆" + visible={visible} + width={700} + maskClosable={false} + okText={dict['model.submit']} + onOk={this.verifySubmit} + onCancel={() => { this.setState({ visible: false }) }} + destroyOnClose + > + <SettingForm + dict={dict} + wrap={wrap} + config={config} + inputSubmit={this.verifySubmit} + wrappedComponentRef={(inst) => this.verifyRef = inst} + /> + </Modal> + </div> + ) + } +} + +export default DataSource \ No newline at end of file diff --git a/src/menu/components/tree/antd-tree/wrapsetting/index.scss b/src/menu/components/tree/antd-tree/wrapsetting/index.scss new file mode 100644 index 0000000..04372e6 --- /dev/null +++ b/src/menu/components/tree/antd-tree/wrapsetting/index.scss @@ -0,0 +1,7 @@ +.model-menu-setting-wrap { + display: inline-block; + + >.anticon-edit { + color: #1890ff; + } +} \ No newline at end of file diff --git a/src/menu/components/tree/antd-tree/wrapsetting/settingform/index.jsx b/src/menu/components/tree/antd-tree/wrapsetting/settingform/index.jsx new file mode 100644 index 0000000..d1a1479 --- /dev/null +++ b/src/menu/components/tree/antd-tree/wrapsetting/settingform/index.jsx @@ -0,0 +1,262 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { Form, Row, Col, Input, Radio, Tooltip, Icon, InputNumber, Select } from 'antd' + +import './index.scss' + +class SettingForm extends Component { + static propTpyes = { + dict: PropTypes.object, // 瀛楀吀椤� + config: PropTypes.object, // 鍗$墖琛屼俊鎭� + wrap: PropTypes.object, // 鏁版嵁婧愰厤缃� + inputSubmit: PropTypes.func // 鍥炶溅浜嬩欢 + } + + state = { + roleList: [], + } + + UNSAFE_componentWillMount () { + let roleList = sessionStorage.getItem('sysRoles') + if (roleList) { + try { + roleList = JSON.parse(roleList) + } catch { + roleList = [] + } + } else { + roleList = [] + } + + this.setState({roleList}) + } + + handleConfirm = () => { + // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭� + return new Promise((resolve, reject) => { + this.props.form.validateFieldsAndScroll((err, values) => { + if (!err) { + resolve(values) + } else { + reject(err) + } + }) + }) + } + + handleSubmit = (e) => { + e.preventDefault() + + if (this.props.inputSubmit) { + this.props.inputSubmit() + } + } + + render() { + const { wrap, config } = this.props + const { getFieldDecorator } = this.props.form + const { roleList } = this.state + + const formItemLayout = { + labelCol: { + xs: { span: 24 }, + sm: { span: 8 } + }, + wrapperCol: { + xs: { span: 24 }, + sm: { span: 16 } + } + } + + return ( + <div className="model-menu-setting-form"> + <Form {...formItemLayout}> + <Row gutter={24}> + <Col span={12}> + <Form.Item label="鏍囬"> + {getFieldDecorator('title', { + initialValue: wrap.title || '' + })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} + </Form.Item> + </Col> + <Col span={12}> + <Form.Item label={ + <Tooltip placement="topLeft" title="鐢ㄤ簬缁勪欢闂寸殑鍖哄垎銆�"> + <Icon type="question-circle" /> + 缁勪欢鍚嶇О + </Tooltip> + }> + {getFieldDecorator('name', { + initialValue: wrap.name, + rules: [ + { + required: true, + message: this.props.dict['form.required.input'] + '缁勪欢鍚嶇О!' + } + ] + })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} + </Form.Item> + </Col> + <Col span={12}> + <Form.Item label={ + <Tooltip placement="topLeft" title="鏁版嵁鍊煎瓧娈点��"> + <Icon type="question-circle" /> + Value + </Tooltip> + }> + {getFieldDecorator('valueField', { + initialValue: wrap.valueField || '', + rules: [ + { + required: true, + message: this.props.dict['form.required.select'] + 'Value瀛楁!' + } + ] + })( + <Select> + {config.columns.map(option => + <Select.Option key={option.uuid} value={option.field}>{option.label}</Select.Option> + )} + </Select> + )} + </Form.Item> + </Col> + <Col span={12}> + <Form.Item label={ + <Tooltip placement="topLeft" title="鏄剧ず鏂囧瓧瀛楁銆�"> + <Icon type="question-circle" /> + Label + </Tooltip> + }> + {getFieldDecorator('labelField', { + initialValue: wrap.labelField || '', + rules: [ + { + required: true, + message: this.props.dict['form.required.select'] + 'Label瀛楁!' + } + ] + })( + <Select> + {config.columns.map(option => + <Select.Option key={option.uuid} value={option.field}>{option.label}</Select.Option> + )} + </Select> + )} + </Form.Item> + </Col> + <Col span={12}> + <Form.Item label={ + <Tooltip placement="topLeft" title="鐖剁骇瀛楁銆�"> + <Icon type="question-circle" /> + Parent + </Tooltip> + }> + {getFieldDecorator('parentField', { + initialValue: wrap.parentField || '', + rules: [ + { + required: true, + message: this.props.dict['form.required.select'] + 'Parent瀛楁!' + } + ] + })( + <Select> + {config.columns.map(option => + <Select.Option key={option.uuid} value={option.field}>{option.label}</Select.Option> + )} + </Select> + )} + </Form.Item> + </Col> + <Col span={12}> + <Form.Item label={ + <Tooltip placement="topLeft" title={'鐖剁骇瀛楁鍊间笌椤剁骇鏍囪瘑鐩稿悓鏃讹紝瑙嗕负椤剁骇鑺傜偣銆�'}> + <Icon type="question-circle" /> + 椤剁骇鏍囪瘑 + </Tooltip> + }> + {getFieldDecorator('mark', { + initialValue: wrap.mark || '' + })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)} + </Form.Item> + </Col> + <Col span={12}> + <Form.Item label={ + <Tooltip placement="topLeft" title="鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��"> + <Icon type="question-circle" /> + 瀹藉害 + </Tooltip> + }> + {getFieldDecorator('width', { + initialValue: wrap.width || 24, + rules: [ + { + required: true, + message: this.props.dict['form.required.input'] + '瀹藉害!' + } + ] + })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.handleSubmit} />)} + </Form.Item> + </Col> + <Col span={12}> + <Form.Item label="鍥炬爣"> + {getFieldDecorator('showIcon', { + initialValue: wrap.showIcon || 'false' + })( + <Radio.Group> + <Radio value="true">鏄剧ず</Radio> + <Radio value="false">闅愯棌</Radio> + </Radio.Group> + )} + </Form.Item> + </Col> + <Col span={12}> + <Form.Item label="鍒嗗壊绾�"> + {getFieldDecorator('showLine', { + initialValue: wrap.showLine || 'false' + })( + <Radio.Group> + <Radio value="true">鏄剧ず</Radio> + <Radio value="false">闅愯棌</Radio> + </Radio.Group> + )} + </Form.Item> + </Col> + <Col span={12}> + <Form.Item label="杩囨护鏉′欢"> + {getFieldDecorator('searchable', { + initialValue: wrap.searchable || 'false' + })( + <Radio.Group> + <Radio value="true">鏄剧ず</Radio> + <Radio value="false">闅愯棌</Radio> + </Radio.Group> + )} + </Form.Item> + </Col> + <Col span={12}> + <Form.Item label="榛戝悕鍗�"> + {getFieldDecorator('blacklist', { + initialValue: wrap.blacklist || [] + })( + <Select + showSearch + mode="multiple" + filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} + > + {roleList.map(option => + <Select.Option key={option.uuid} value={option.value}>{option.text}</Select.Option> + )} + </Select> + )} + </Form.Item> + </Col> + </Row> + </Form> + </div> + ) + } +} + +export default Form.create()(SettingForm) \ No newline at end of file diff --git a/src/menu/components/tree/antd-tree/wrapsetting/settingform/index.scss b/src/menu/components/tree/antd-tree/wrapsetting/settingform/index.scss new file mode 100644 index 0000000..c530b18 --- /dev/null +++ b/src/menu/components/tree/antd-tree/wrapsetting/settingform/index.scss @@ -0,0 +1,15 @@ +.model-menu-setting-form { + position: relative; + + .anticon-question-circle { + color: #c49f47; + margin-right: 3px; + } + .ant-input-number { + width: 100%; + } + .color-sketch-block { + position: relative; + top: 7px; + } +} \ No newline at end of file diff --git a/src/menu/menushell/card.jsx b/src/menu/menushell/card.jsx index e086365..a482a9d 100644 --- a/src/menu/menushell/card.jsx +++ b/src/menu/menushell/card.jsx @@ -12,6 +12,7 @@ const AntvTabs = asyncComponent(() => import('@/menu/components/tabs/antv-tabs')) const DataCard = asyncComponent(() => import('@/menu/components/card/data-card')) const PropCard = asyncComponent(() => import('@/menu/components/card/prop-card')) +const NormalTree = asyncComponent(() => import('@/menu/components/tree/antd-tree')) const CarouselDataCard = asyncComponent(() => import('@/menu/components/carousel/data-card')) const CarouselPropCard = asyncComponent(() => import('@/menu/components/carousel/prop-card')) const TableCard = asyncComponent(() => import('@/menu/components/card/table-card')) @@ -63,6 +64,8 @@ return (<AntvPie card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'dashboard') { return (<AntvDashboard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'tree') { + return (<NormalTree card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'scatter') { return (<AntvScatter card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } else if (card.type === 'form') { diff --git a/src/menu/menushell/index.jsx b/src/menu/menushell/index.jsx index 8a9fcfa..b1427ac 100644 --- a/src/menu/menushell/index.jsx +++ b/src/menu/menushell/index.jsx @@ -99,6 +99,7 @@ form: '琛ㄥ崟', dashboard: '浠〃鐩�', scatter: '鏁g偣鍥�', + tree: '鏍戝舰鍒楄〃', card: '鍗$墖' } let i = 1 diff --git a/src/menu/modulesource/option.jsx b/src/menu/modulesource/option.jsx index 9bd7d81..e4d50c4 100644 --- a/src/menu/modulesource/option.jsx +++ b/src/menu/modulesource/option.jsx @@ -19,6 +19,7 @@ import form from '@/assets/mobimg/form.png' import dashboard from '@/assets/mobimg/dashboard.png' import scatter from '@/assets/mobimg/scatter.png' +import tree from '@/assets/mobimg/tree.png' // 缁勪欢閰嶇疆淇℃伅 export const menuOptions = [ @@ -31,6 +32,7 @@ { type: 'menu', url: Carousel1, component: 'carousel', subtype: 'propcard', title: '杞挱-闈欐�佹暟鎹�', width: 24, forbid: ['billPrint'] }, { type: 'menu', url: NormalTable, component: 'table', subtype: 'normaltable', title: '甯哥敤琛�', width: 24 }, { type: 'menu', url: TableCard, component: 'table', subtype: 'tablecard', title: '琛ㄦ牸', width: 12 }, + { type: 'menu', url: tree, component: 'tree', subtype: 'normaltree', title: '鏍戝舰鍒楄〃', width: 12 }, { type: 'menu', url: line, component: 'line', subtype: 'line', title: '鎶樼嚎鍥�', width: 24 }, { type: 'menu', url: line1, component: 'line', subtype: 'line1', title: '闃舵鎶樼嚎鍥�', width: 24 }, { type: 'menu', url: bar, component: 'bar', subtype: 'bar', title: '鏌辩姸鍥�', width: 24 }, diff --git a/src/mob/components/formdragelement/index.scss b/src/mob/components/formdragelement/index.scss index 188c60e..011e9e7 100644 --- a/src/mob/components/formdragelement/index.scss +++ b/src/mob/components/formdragelement/index.scss @@ -192,6 +192,9 @@ opacity: 0; z-index: 1; } + .field-name { + margin-left: 10px; + } } .ant-form-item.required { .am-input-label::before { diff --git a/src/pc/menushell/index.jsx b/src/pc/menushell/index.jsx index 024490a..acc2b18 100644 --- a/src/pc/menushell/index.jsx +++ b/src/pc/menushell/index.jsx @@ -107,6 +107,7 @@ navbar: '瀵艰埅鏍�', carousel: '杞挱', dashboard: '浠〃鐩�', + tree: '鏍戝舰鍒楄〃', card: '鍗$墖', login: '鐧诲綍' } diff --git a/src/tabviews/custom/components/card/data-card/index.jsx b/src/tabviews/custom/components/card/data-card/index.jsx index 1c56228..8269c1b 100644 --- a/src/tabviews/custom/components/card/data-card/index.jsx +++ b/src/tabviews/custom/components/card/data-card/index.jsx @@ -572,7 +572,7 @@ {switchable ? <div className={'prev-page ' + (pageIndex === 1 ? 'disabled' : '')} onClick={this.prevPage}><div><div><img src={preImg} alt=""/></div></div></div> : null} {data && data.length > 0 ? <Row className="card-row-list"> {data.map((item, index) => ( - <Col className={(activeKey === index ? 'active' : (selectKeys.indexOf(index) > -1 ? 'selected' : '')) + (card.setting.click ? ' pointer' : '')} key={index} span={card.setting.width} offset={!index ? offset : 0} onClick={() => {this.changeCard(index, item)}}> + <Col className={(activeKey === index ? ' active' : (selectKeys.indexOf(index) > -1 ? ' selected' : '')) + (card.setting.click ? ' pointer' : '')} key={index} span={card.setting.width} offset={!index ? offset : 0} onClick={() => {this.changeCard(index, item)}}> <CardItem card={card} cards={config} data={item}/> </Col> ))} diff --git a/src/tabviews/custom/components/tree/antd-tree/index.jsx b/src/tabviews/custom/components/tree/antd-tree/index.jsx new file mode 100644 index 0000000..1ab48b4 --- /dev/null +++ b/src/tabviews/custom/components/tree/antd-tree/index.jsx @@ -0,0 +1,483 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Spin, Empty, notification, Input, Tree, Icon } from 'antd' +import moment from 'moment' + +import Api from '@/api' +import Utils from '@/utils/utils.js' +import UtilsDM from '@/utils/utils-datamanage.js' +import MKEmitter from '@/utils/events.js' +import './index.scss' + +const { TreeNode } = Tree +const { Search } = Input + +class NormalTree extends Component { + static propTpyes = { + BID: PropTypes.any, // 鐖剁骇Id + data: PropTypes.array, // 缁熶竴鏌ヨ鏁版嵁 + config: PropTypes.object, // 缁勪欢閰嶇疆淇℃伅 + mainSearch: PropTypes.any, // 澶栧眰鎼滅储鏉′欢 + menuType: PropTypes.any, // 鑿滃崟绫诲瀷 + } + + state = { + BID: '', // 涓昏〃ID + config: null, // 鍥捐〃閰嶇疆淇℃伅 + loading: false, // 鏁版嵁鍔犺浇鐘舵�� + sync: false, // 鏄惁缁熶竴璇锋眰鏁版嵁 + data: null, // 鏁版嵁 + searchkey: null, // 杩囨护鏉′欢 + treedata: null, // 鍒楄〃鏁版嵁闆� + treeNodes: null, // 鍒楄〃鏁版嵁闆� + expandedKeys: [], // 灞曞紑鐨勬爲鑺傜偣 + selectedKeys: [], // 閫変腑鐨勬爲鑺傜偣 + } + + UNSAFE_componentWillMount () { + const { config, data, initdata, BID } = this.props + let _config = fromJS(config).toJS() + let _data = null + let _sync = config.setting.sync === 'true' + + if (config.setting.sync === 'true' && data) { + _data = data[config.dataName] || [] + _sync = false + } else if (config.setting.sync === 'true' && initdata) { + _data = initdata || [] + _sync = false + } + + this.setState({ + config: _config, + data: _data, + BID: BID || '', + arr_field: _config.columns.map(col => col.field).join(','), + sync: _sync + }, () => { + if (config.setting.sync !== 'true' && config.setting.onload === 'true') { + this.loadData() + } else if (config.setting.sync === 'true' && _data) { + this.handleData() + } + }) + } + + /** + * @description 鍥捐〃鏁版嵁鏇存柊锛屽埛鏂板唴瀹� + */ + UNSAFE_componentWillReceiveProps (nextProps) { + const { sync, config } = this.state + + if (sync && !is(fromJS(this.props.data), fromJS(nextProps.data))) { + let _data = [] + if (nextProps.data && nextProps.data[config.dataName]) { + _data = nextProps.data[config.dataName] || [] + } + + // _data = [ + // {ID: 'dsdsagsgfs32ed2dqd61', nvarchar1: '1', nvarchar2: '1', nvarchar3: ''}, + // {ID: 'dsdsagsgfs32ed2dqd61', nvarchar1: '1-1', nvarchar2: '1-1', nvarchar3: '1'}, + // {ID: 'dsdsagsgfs32ed2dqd61', nvarchar1: '1-2', nvarchar2: '1-2', nvarchar3: '1'}, + // {ID: 'dsdsagsgfs32ed2dqd61', nvarchar1: '2', nvarchar2: '2', nvarchar3: ''}, + // {ID: 'dsdsagsgfs32ed2dqd61', nvarchar1: '2-1', nvarchar2: '2-1', nvarchar3: '2'}, + // {ID: 'dsdsagsgfs32ed2dqd61', nvarchar1: '2-2', nvarchar2: '2-2', nvarchar3: '2'}, + // ] + + this.setState({sync: false, data: _data}, () => { + this.handleData() + }) + } else if (nextProps.mainSearch && !is(fromJS(this.props.mainSearch), fromJS(nextProps.mainSearch))) { + if (config.setting.syncRefresh === 'true') { + this.setState({}, () => { + this.loadData() + }) + } + } + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + componentDidMount () { + MKEmitter.addListener('reloadData', this.reloadData) + MKEmitter.addListener('resetSelectLine', this.resetParentParam) + this.handleTimer() + } + + /** + * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆 + */ + componentWillUnmount () { + clearTimeout(this.timer) + this.setState = () => { + return + } + MKEmitter.removeListener('reloadData', this.reloadData) + MKEmitter.removeListener('resetSelectLine', this.resetParentParam) + } + + handleTimer = () => { + const { config } = this.state + + if (!config.timer) return + + const _change = { + '15s': 15000, + '30s': 30000, + '1min': 60000, + '5min': 300000, + '10min': 600000, + '15min': 900000, + '30min': 1800000, + '1hour': 3600000 + } + + let timer = _change[config.timer] + + if (!timer) return + + let _param = { + func: 's_get_timers_role', + LText: `select '${window.GLOB.appkey || ''}','${config.uuid}'`, + timer_type: config.timer, + component_id: config.uuid + } + + _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') // 鏃堕棿鎴� + _param.LText = Utils.formatOptions(_param.LText) // 鍏抽敭瀛楃鏇挎崲锛宐ase64鍔犲瘑 + _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp) // md5瀵嗛挜 + + Api.getSystemConfig(_param).then(result => { + if (!result.status) { + notification.warning({ + top: 92, + message: result.message, + duration: 5 + }) + return + } else if (result.run_type) { + this.setState({timer}) + this.timer = setTimeout(() => { + this.timerTask() + }, timer) + } + }) + } + + timerTask = () => { + const { timer } = this.state + if (!timer) return + + this.loadData(true) + + this.timer = setTimeout(() => { + this.timerTask() + }, timer) + } + + reloadData = (menuId) => { + const { config } = this.state + + if (config.uuid !== menuId) return + + this.loadData() + } + + resetParentParam = (MenuID, id) => { + const { config } = this.state + + if (!config.setting.supModule || config.setting.supModule !== MenuID) return + if (id !== this.state.BID) { + this.setState({ BID: id }, () => { + this.loadData() + }) + } + } + + /** + * @description 鏁版嵁鍔犺浇 + */ + async loadData (hastimer) { + const { mainSearch, menuType } = this.props + const { config, arr_field, BID } = this.state + + if (config.setting.supModule && !BID) { // BID 涓嶅瓨鍦ㄦ椂锛屼笉鍋氭煡璇� + this.setState({ + data: [] + }, () => { + this.handleData() + }) + return + } + + let searches = [] + if (mainSearch && mainSearch.length > 0) { // 涓昏〃鎼滅储鏉′欢 + let keys = searches.map(item => item.key) + mainSearch.forEach(item => { + if (!keys.includes(item.key)) { + searches.push(item) + } + }) + } + + let requireFields = searches.filter(item => item.required && (!item.value || item.value.length === 0)) + if (requireFields.length > 0) { + this.setState({ + loading: false + }) + return + } + + if (!hastimer) { + this.setState({ + loading: true + }) + } + + let _orderBy = config.setting.order || '' + let param = UtilsDM.getQueryDataParams(config.setting, arr_field, searches, _orderBy, '', '', BID, menuType) + + let result = await Api.genericInterface(param) + if (result.status) { + this.setState({ + data: result.data, + loading: false + }, () => { + this.handleData() + }) + } else { + this.setState({ + loading: false, + timer: null + }) + notification.error({ + top: 92, + message: result.message, + duration: 10 + }) + } + } + + handleData = () => { + const { data, searchkey, config } = this.state + if (!data || data.length === 0) { + this.setState({ + treedata: [], + treeNodes: [], + }) + return + } + let parentNodes = [] + let _options = [] + let logMap = new Map() + + data.forEach(item => { + let pval = item[config.wrap.parentField] + let val = item[config.wrap.valueField] + + if (!val || logMap.has(val)) return + + logMap.set(val, true) + if (pval === config.wrap.mark) { + parentNodes.push({ + // ...item, + title: item[config.wrap.labelField] || '', + key: val, + parentId: '' + }) + } else if (pval) { + _options.push({ + // ...item, + title: item[config.wrap.labelField] || '', + key: val, + parentId: pval + }) + } + }) + let _treedata = this.getTree(parentNodes, _options) + + let _treeNodes = [] + + if (!searchkey) { + _treeNodes = fromJS(_treedata).toJS() + } else { + _treeNodes = this.getFilterTree(fromJS(_treedata).toJS(), searchkey.toLowerCase()) + } + + this.setState({ + treedata: _treedata, + treeNodes: _treeNodes, + }) + } + + treeFilter = (value) => { + const { treedata } = this.state + + let _treeNodes = [] + + if (!value) { + _treeNodes = fromJS(treedata).toJS() + } else { + _treeNodes = this.getFilterTree(fromJS(treedata).toJS(), value.toLowerCase()) + } + + this.setState({ + searchkey: value, + treeNodes: _treeNodes + }) + } + + /** + * @description 鑾峰彇缁撴瀯鏍戜俊鎭� + */ + getFilterTree = (parents, searchkey) => { + return parents.filter(node => { + if (!node.children) { + return (node.title.toLowerCase().indexOf(searchkey) >= 0 || node.key.toLowerCase().indexOf(searchkey) >= 0) + } else { + if (node.title.toLowerCase().indexOf(searchkey) >= 0 || node.key.toLowerCase().indexOf(searchkey) >= 0) { + return true + } + + node.children = this.getFilterTree(node.children, searchkey) + if (node.children.length === 0) { + return false + } else { + return true + } + } + }) + } + + /** + * @description 鑾峰彇缁撴瀯鏍戜俊鎭� + */ + getTree = (parents, options) => { + parents.forEach(parent => { + parent.children = [] + // 娣诲姞鑿滃崟鐨勫瓙鍏冪礌 + options = options.filter(option => { + if (option.parentId === parent.key) { + parent.children.push(option) + return false + } + return true + }) + + if (parent.children.length === 0) { + parent.children = null + } else { + parent.children = this.getTree(parent.children, options) + } + }) + return parents + } + + /** + * @description 鑾峰彇鏍戣妭鐐� + */ + renderTreeNodes = (nodes) => { + return nodes.map(item => { + if (item.children) { + return ( + <TreeNode icon={<span><Icon type="folder-open" /><Icon type="folder" /></span>} title={item.title} key={item.key} dataRef={item}> + {this.renderTreeNodes(item.children)} + </TreeNode> + ) + } + return <TreeNode icon={<Icon type="file" />} key={item.key} title={item.title} dataRef={item} isLeaf /> + }) + } + + changeExpandedKeys = (expandedKeys) => { + this.setState({ + expandedKeys: expandedKeys + }) + } + + // 鍙抽敭灞曞紑鑺傜偣涓嬬殑鍏ㄩ儴鍒嗘敮 + changeExpandedAllKeys = ({event, node}) => { + const { expandedKeys } = this.state + let _node = node.props.dataRef + event.stopPropagation() + + let keys = [] + this.getExpandKeys(_node, keys) + + this.setState({ + expandedKeys: Array.from(new Set([...keys, ...expandedKeys])), + }) + } + + getExpandKeys = (node, keys) => { + if (node.children) { + keys.push(node.key) + node.children.forEach(_node => { + this.getExpandKeys(_node, keys) + }) + } + } + + selectTreeNode = (selectedKeys, {selected, node}) => { + const { config } = this.state + let _expandedKeys = fromJS(this.state.expandedKeys).toJS() + let _data = fromJS(node.props.dataRef).toJS() + + if (_expandedKeys.indexOf(_data.key) >= 0) { + _expandedKeys = _expandedKeys.filter(key => key !== _data.key) + } else { + if (_data.children) { + _expandedKeys.push(_data.key) + _expandedKeys = Array.from(new Set(_expandedKeys)) + } + } + + if (selected) { + MKEmitter.emit('resetSelectLine', config.uuid, (_data ? _data.key : ''), _data) + } + + this.setState({ + expandedKeys: _expandedKeys, + selectedKeys: [_data.key] + }) + } + + render() { + const { config, loading, treeNodes, expandedKeys, selectedKeys } = this.state + + return ( + <div className="custom-tree-box" style={config.style}> + {loading ? + <div className="loading-mask"> + <div className="ant-spin-blur"></div> + <Spin /> + </div> : null + } + {config.wrap.title || config.wrap.searchable === 'true' ? <div className="tree-header" style={config.headerStyle}> + <span className="title">{config.wrap.title}</span> + {config.wrap.searchable === 'true' ? <Search allowClear onSearch={this.treeFilter} /> : null} + </div> : null} + {treeNodes && treeNodes.length > 0 ? <div className="tree-box"> + <Tree + blockNode + onSelect={this.selectTreeNode} + expandedKeys={expandedKeys} + selectedKeys={selectedKeys} + onRightClick={this.changeExpandedAllKeys} + onExpand={this.changeExpandedKeys} + showIcon={config.wrap.showIcon === 'true'} + showLine={config.wrap.showLine === 'true'} + > + {this.renderTreeNodes(treeNodes)} + </Tree> + </div> : null} + {treeNodes && treeNodes.length === 0 ? <Empty description={false}/> : null} + </div> + ) + } +} + +export default NormalTree \ No newline at end of file diff --git a/src/tabviews/custom/components/tree/antd-tree/index.scss b/src/tabviews/custom/components/tree/antd-tree/index.scss new file mode 100644 index 0000000..413cf1c --- /dev/null +++ b/src/tabviews/custom/components/tree/antd-tree/index.scss @@ -0,0 +1,93 @@ +.custom-tree-box { + position: relative; + background: #ffffff; + background-position: center center; + background-repeat: no-repeat; + background-size: cover; + min-height: 100px; + + .tree-header { + position: relative; + height: 45px; + padding-right: 8px; + border-bottom: 1px solid #e8e8e8; + overflow: hidden; + letter-spacing: 0px; + + .title { + text-decoration: inherit; + font-weight: inherit; + font-style: inherit; + float: left; + line-height: 45px; + margin-left: 10px; + position: relative; + z-index: 1; + } + .ant-input-search.ant-input-affix-wrapper { + width: calc(100% - 140px); + max-width: 130px; + margin-top: 6px; + float: right; + height: 30px; + border-radius: 20px; + border: 1px solid #d9d9d9; + opacity: 0.6; + input { + border: none; + border-radius: 20px; + height: 28px; + } + } + } + .tree-box { + overflow-x: auto; + padding-bottom: 10px; + + .ant-tree-node-content-wrapper-close > span > span > .anticon-folder-open { + display: none; + } + .ant-tree-node-content-wrapper-open > span > span > .anticon-folder { + display: none; + } + } + .tree-box::-webkit-scrollbar { + height: 10px; + } + .tree-box::-webkit-scrollbar-thumb { + border-radius: 5px; + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13); + background: rgba(0, 0, 0, 0.13); + } + .tree-box::-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-empty { + position: absolute; + top: calc(50% - 34px); + left: calc(50% - 92px); + + .ant-empty-image { + height: 60px; + } + } + .loading-mask { + position: absolute; + left: 0px; + top: 0; + right: 0px; + bottom: 0px; + z-index: 1; + + .ant-spin-blur { + position: absolute; + width: 100%; + height: 100%; + opacity: 0.5; + background: #ffffff; + } + } +} diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx index cbec0bc..d175a50 100644 --- a/src/tabviews/custom/index.jsx +++ b/src/tabviews/custom/index.jsx @@ -34,6 +34,7 @@ const NormalGroup = asyncComponent(() => import('./components/group/normal-group')) const BraftEditor = asyncComponent(() => import('./components/editor/braft-editor')) const SandBox = asyncComponent(() => import('./components/code/sand-box')) +const NormalTree = asyncComponent(() => import('./components/tree/antd-tree')) const SettingComponent = asyncComponent(() => import('@/tabviews/zshare/settingcomponent')) const PagemsgComponent = asyncComponent(() => import('@/tabviews/zshare/pageMessage')) @@ -1132,6 +1133,12 @@ <BraftEditor config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} /> </Col> ) + } else if (item.type === 'tree') { + return ( + <Col span={item.width} key={item.uuid}> + <NormalTree config={item} data={data} BID={_bid} mainSearch={mainSearch} menuType={menuType} /> + </Col> + ) } else if (item.type === 'code') { return ( <Col span={item.width} key={item.uuid}> diff --git a/src/tabviews/zshare/imgScale/index.jsx b/src/tabviews/zshare/imgScale/index.jsx new file mode 100644 index 0000000..dc4c542 --- /dev/null +++ b/src/tabviews/zshare/imgScale/index.jsx @@ -0,0 +1,65 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Icon } from 'antd' + +import './index.scss' + +class ImgScale extends Component { + static propTpyes = { + data: PropTypes.object + } + + state = { + list: [], + index: 0 + } + + UNSAFE_componentWillMount() { + const { data } = this.props + + this.setState({ + list: data.list || [], + index: data.index || 0 + }) + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + /** + * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊 + */ + componentWillUnmount () { + this.setState = () => { + return + } + } + + reduce = () => { + const { index } = this.state + + this.setState({index: index - 1}) + } + + plus = () => { + const { index } = this.state + + this.setState({index: index + 1}) + } + + render() { + const { list, index } = this.state + + return ( + <div className="img-scale-wrap"> + <img src={list[index]} alt="" /> + {index > 0 ? <Icon type="left" onClick={this.reduce} /> : null} + {index < list.length -1 ? <Icon type="right" onClick={this.plus} /> : null} + </div> + ) + } +} + +export default ImgScale \ No newline at end of file diff --git a/src/tabviews/zshare/imgScale/index.scss b/src/tabviews/zshare/imgScale/index.scss new file mode 100644 index 0000000..db4944e --- /dev/null +++ b/src/tabviews/zshare/imgScale/index.scss @@ -0,0 +1,20 @@ +.img-scale-wrap { + position: relative; + img { + max-width: 100%; + } + + .anticon { + position: absolute; + top: calc(50% - 25px); + font-size: 30px; + padding: 10px; + } + + .anticon-left { + left: 20px; + } + .anticon-right { + right: 20px; + } +} diff --git a/src/tabviews/zshare/normalTable/index.jsx b/src/tabviews/zshare/normalTable/index.jsx index ac7f9c5..aa989fb 100644 --- a/src/tabviews/zshare/normalTable/index.jsx +++ b/src/tabviews/zshare/normalTable/index.jsx @@ -17,6 +17,7 @@ const PopupButton = asyncComponent(() => import('@/tabviews/zshare/actionList/popupbutton')) const TabButton = asyncComponent(() => import('@/tabviews/zshare/actionList/tabbutton')) const NewPageButton = asyncComponent(() => import('@/tabviews/zshare/actionList/newpagebutton')) +const ImgScale = asyncComponent(() => import('@/tabviews/zshare/imgScale')) class NormalTable extends Component { static propTpyes = { @@ -45,7 +46,7 @@ pageSize: 10, // 姣忛〉鏁版嵁鏉℃暟 columns: null, // 鏄剧ず鍒� imgShow: false, // 鍥剧墖鏀惧ぇ妯℃�佹 - imgSrc: '', // 鍥剧墖璺緞 + imgData: {}, // 鍥剧墖闆� lineMarks: null, // 琛屾爣璁� activeIndex: null, // 鏍囪褰撳墠閫変腑琛� rowspans: null // 琛屽悎骞跺瓧娈典俊鎭� @@ -547,7 +548,7 @@ let photos = '' if (item.field && record.hasOwnProperty(item.field)) { photos = record[item.field] + '' - photos = photos.split(',') + photos = photos.split(',').filter(Boolean) } else { photos = '' } @@ -557,7 +558,7 @@ <div className="picture-col"> {photos && photos.map((url, i) => { if (item.scale === 'true') { - return <img style={{maxHeight: maxHeight}} className="image-scale" onClick={this.imgScale} key={`${i}`} src={url} alt=""/> + return <img style={{maxHeight: maxHeight}} className="image-scale" onClick={() => this.imgScale(photos, i)} key={`${i}`} src={url} alt=""/> } else { return <img style={{maxHeight: maxHeight}} key={`${i}`} src={url} alt=""/> } @@ -733,7 +734,7 @@ let photos = [] try { photos = record[col.field] + '' - photos = photos.split(',') + photos = photos.split(',').filter(Boolean) } catch { photos = [] } @@ -869,9 +870,8 @@ <div className="content-fence"> <div className="content-fence-top" style={images[0] ? {textAlign: images[0].align} : null}> {images.map((_img, index) => { - if (!_img.url) return '' if (_img.scale) { - return <img style={{maxHeight: _img.maxHeight}} className="image-scale" onClick={this.imgScale} key={`${index}`} src={_img.url} alt=""/> + return <img style={{maxHeight: _img.maxHeight}} className="image-scale" onClick={() => this.imgScale(images, index)} key={`${index}`} src={_img.url} alt=""/> } else { return (<img style={{maxHeight: _img.maxHeight}} key={`${index}`} src={_img.url} alt=""/>) } @@ -889,9 +889,8 @@ <div className="content-fence"> <div className="content-fence-left" style={images[0] ? {textAlign: images[0].align} : null}> {images.map((_img, index) => { - if (!_img.url) return '' if (_img.scale) { - return <img style={{maxHeight: _img.maxHeight}} className="image-scale" onClick={this.imgScale} key={`${index}`} src={_img.url} alt=""/> + return <img style={{maxHeight: _img.maxHeight}} className="image-scale" onClick={() => this.imgScale(images, index)} key={`${index}`} src={_img.url} alt=""/> } else { return (<img style={{maxHeight: _img.maxHeight}} key={`${index}`} src={_img.url} alt=""/>) } @@ -910,18 +909,19 @@ /** * @description 鍥剧墖缂╂斁 */ - imgScaleClose = () => { + imgScale = (images, index) => { this.setState({ - imgShow: false + imgShow: true, + imgData: { + list: images.map(item => { + if (typeof(item) === 'string') { + return item + } + return item.url + }), + index + } }) - } - imgScale = (e) => { - if (e.target.nodeName === 'IMG') { - this.setState({ - imgShow: true, - imgSrc: e.target.src - }) - } } /** @@ -1237,12 +1237,12 @@ visible={this.state.imgShow} width="70vw" maskClosable={true} - onCancel={this.imgScaleClose} + onCancel={() => {this.setState({ imgShow: false })}} title={this.props.dict['main.form.picture.check']} - footer={[<span key="close" onClick={this.imgScaleClose}>{this.props.dict['main.close']}</span>]} + footer={[<span key="close" onClick={() => {this.setState({ imgShow: false })}}>{this.props.dict['main.close']}</span>]} destroyOnClose > - <img style={{maxWidth:'100%'}} src={this.state.imgSrc} alt="" /> + <ImgScale data={this.state.imgData}/> </Modal> </div> ) diff --git a/src/templates/treepageconfig/index.jsx b/src/templates/treepageconfig/index.jsx index 8a4b4dd..d1aa9bd 100644 --- a/src/templates/treepageconfig/index.jsx +++ b/src/templates/treepageconfig/index.jsx @@ -501,6 +501,7 @@ } let submenu = menu.fstMenuList.filter(item => item.MenuID === config.fstMenuId)[0] + let _Menu = { ...menu, LongParam: config, @@ -509,7 +510,7 @@ MenuNo: config.MenuNo, ParentId: config.ParentId, fstMenuId: config.fstMenuId, - supMenuList: submenu ? submenu.options : [] + supMenuList: submenu ? submenu.children : [] } _Menu.activeKey = activeKey // 淇濆瓨褰撳墠鎵撳紑椤电 diff --git a/src/templates/zshare/formconfig.jsx b/src/templates/zshare/formconfig.jsx index 95f77fc..1a91cb1 100644 --- a/src/templates/zshare/formconfig.jsx +++ b/src/templates/zshare/formconfig.jsx @@ -2453,14 +2453,29 @@ type: 'radio', key: 'cursor', label: '鍏夋爣', - initVal: card.cursor || 'right', + initVal: card.cursor || 'left', options: [{ value: 'right', text: '鍙冲榻�' }, { value: 'left', text: '宸﹀榻�' - }] + }], + forbid: appType !== 'mob' + }, + { + type: 'radio', + key: 'scan', + label: '鎵爜', + initVal: card.scan || 'false', + options: [{ + value: 'true', + text: '鍚敤' + }, { + value: 'false', + text: '涓嶅惎鐢�' + }], + forbid: appType !== 'mob' }, { type: 'radio', diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx index b01efb6..1297c91 100644 --- a/src/views/menudesign/index.jsx +++ b/src/views/menudesign/index.jsx @@ -863,6 +863,8 @@ error = `缁勪欢銆�${item.name}銆嬫樉绀哄�煎皻鏈缃紒` } else if (item.type === 'scatter' && (!item.plot.Xaxis || !item.plot.Yaxis || !item.plot.gender)) { error = `缁勪欢銆�${item.name}銆嬪潗鏍囪酱灏氭湭璁剧疆锛乣 + } else if (item.type === 'tree' && (!item.wrap.valueField || !item.wrap.labelField || !item.wrap.parentField)) { + error = `缁勪欢銆�${item.name}銆嬪熀鏈俊鎭皻鏈缃紒` } }) } diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx index 5a249a6..a03874f 100644 --- a/src/views/pcdesign/index.jsx +++ b/src/views/pcdesign/index.jsx @@ -1350,6 +1350,8 @@ error = `缁勪欢銆�${item.name}銆嬫樉绀哄�煎皻鏈缃紒` } else if (item.type === 'scatter' && (!item.plot.Xaxis || !item.plot.Yaxis || !item.plot.gender)) { error = `缁勪欢銆�${item.name}銆嬪潗鏍囪酱灏氭湭璁剧疆锛乣 + } else if (item.type === 'tree' && (!item.wrap.valueField || !item.wrap.labelField || !item.wrap.parentField)) { + error = `缁勪欢銆�${item.name}銆嬪熀鏈俊鎭皻鏈缃紒` } }) } -- Gitblit v1.8.0