From ecbe0dc46ce2b8f607b9afd063104adeb7f10fe8 Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期二, 30 三月 2021 15:19:31 +0800 Subject: [PATCH] 2021-03-30 --- src/views/pcdesign/index.jsx | 4 src/views/mobdesign/menuform/index.jsx | 138 +++ src/mob/modulesource/dragsource/index.jsx | 15 src/mob/mobshell/index.jsx | 136 ++ src/mob/modulesource/index.jsx | 93 ++ src/mob/modulesource/option.jsx | 42 src/pc/menushell/index.jsx | 15 /dev/null | 16 src/tabviews/zshare/mutilform/index.jsx | 282 ++++-- src/templates/sharecomponent/columncomponent/index.jsx | 2 src/mob/modulesource/index.scss | 2 src/views/mobdesign/index.scss | 282 +++-- src/views/mobdesign/menuform/index.scss | 10 src/views/mobdesign/index.jsx | 1548 +++++++++++++++++++++++++++++--- src/assets/mobimg/navbar-mob.png | 0 src/menu/menushell/index.jsx | 15 src/mob/mobshell/card.jsx | 74 + src/mob/modulesource/dragsource/index.scss | 46 + 18 files changed, 2,242 insertions(+), 478 deletions(-) diff --git a/src/assets/mobimg/mobile.png b/src/assets/mobimg/mobile.png deleted file mode 100644 index c17bc0b..0000000 --- a/src/assets/mobimg/mobile.png +++ /dev/null Binary files differ diff --git a/src/assets/mobimg/navbar-mob.png b/src/assets/mobimg/navbar-mob.png new file mode 100644 index 0000000..d6be81a --- /dev/null +++ b/src/assets/mobimg/navbar-mob.png Binary files differ diff --git a/src/menu/menushell/index.jsx b/src/menu/menushell/index.jsx index 05c87c4..6ac5ace 100644 --- a/src/menu/menushell/index.jsx +++ b/src/menu/menushell/index.jsx @@ -1,6 +1,5 @@ import React, { useState } from 'react' import { useDrop } from 'react-dnd' -import { is, fromJS } from 'immutable' import update from 'immutability-helper' import { Empty, notification, Modal } from 'antd' @@ -18,10 +17,7 @@ const { card, index } = findCard(id) const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] }) handleList({...menu, components: _cards}) - } - - if (!is(fromJS(cards), fromJS(menu.components))) { - setCards(menu.components) + setCards(_cards) } const findCard = id => { @@ -33,7 +29,9 @@ } const updateConfig = (element) => { - handleList({...menu, components: cards.map(item => item.uuid === element.uuid ? element : item)}) + const _cards = cards.map(item => item.uuid === element.uuid ? element : item) + handleList({...menu, components: _cards}) + setCards(_cards) } const deleteCard = (id) => { @@ -54,8 +52,10 @@ title: `纭畾鍒犻櫎銆�${card.name}銆嬪悧锛焋, content: hasComponent ? '褰撳墠缁勪欢涓惈鏈夊瓙缁勪欢锛�' : '', onOk() { + const _cards = cards.filter(item => item.uuid !== card.uuid) MKEmitter.emit('delButtons', uuids) - handleList({...menu, components: cards.filter(item => item.uuid !== card.uuid)}) + handleList({...menu, components: _cards}) + setCards(_cards) }, onCancel() {} }) @@ -130,6 +130,7 @@ const _cards = update(cards, { $splice: [[overIndex + 1, 0, newcard]] }) handleList({...menu, components: _cards}) + setCards(_cards) } }) diff --git a/src/mob/contdelete/index.jsx b/src/mob/contdelete/index.jsx deleted file mode 100644 index d96e1b6..0000000 --- a/src/mob/contdelete/index.jsx +++ /dev/null @@ -1,57 +0,0 @@ -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/mob.js' -import enUS from '@/locales/en-US/mob.js' -import './index.scss' - -const { confirm } = Modal - -class ContentDelete extends Component { - static propTpyes = { - element: PropTypes.object, - list: PropTypes.array, - updateContent: PropTypes.func - } - - state = { - dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, - images: [], - visible: false - } - - UNSAFE_componentWillMount () { - - } - - // shouldComponentUpdate (nextProps, nextState) { - // return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) - // } - - deleteElement = () => { - const { list, element } = this.props - const _this = this - - confirm({ - title: '纭畾鍒犻櫎鍏冪礌鍚楋紵', - onOk() { - _this.props.updateContent({...list, subItems: list.subItems.filter(item => item.uuid !== element.uuid)}) - }, - onCancel() {} - }) - } - - - - render () { - return ( - <div className="mob-content-list-delete"> - <Icon type="close" onClick={this.deleteElement} /> - </div> - ) - } -} - -export default ContentDelete \ No newline at end of file diff --git a/src/mob/contdelete/index.scss b/src/mob/contdelete/index.scss deleted file mode 100644 index a36b973..0000000 --- a/src/mob/contdelete/index.scss +++ /dev/null @@ -1,25 +0,0 @@ -.mob-content-list-delete { - position: absolute; - top: -10px; - left: -10px; - border-radius: 2px; - font-size: 14px; - display: none; - line-height: 1.5; - z-index: 1; - - i { - padding: 2px 5px; - cursor: pointer; - } - .anticon-close { - color: #ff4d4f; - } -} -.deletable-item { - position: relative; -} -.deletable-item:hover .mob-content-list-delete { - display: inline-block; -} - diff --git a/src/mob/controller/index.jsx b/src/mob/controller/index.jsx deleted file mode 100644 index 21878d7..0000000 --- a/src/mob/controller/index.jsx +++ /dev/null @@ -1,480 +0,0 @@ -import React, {Component} from 'react' -import PropTypes from 'prop-types' -import { is, fromJS } from 'immutable' -import { Collapse, Form, Input, Col, Icon, InputNumber, Select, Radio, Popover, Menu } from 'antd' - -import zhCN from '@/locales/zh-CN/mob.js' -import enUS from '@/locales/en-US/mob.js' -import ColorSketch from '@/mob/colorsketch' -import FileUpload from '@/tabviews/zshare/fileupload' -import './index.scss' - -const { Panel } = Collapse -const { Option } = Select - -class MobController extends Component { - static propTpyes = { - editElem: PropTypes.any, - updateStyle: PropTypes.func, - } - - state = { - dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, - card: null, - fontColor: '#000000', - backgroundColor: '#ffffff', - bgimages: [], - marginTop: '', - marginTopVal: '', - marginBottom: '', - marginBottomVal: '', - } - - UNSAFE_componentWillReceiveProps (nextProps) { - if (!is(fromJS(this.props.editElem), fromJS(nextProps.editElem))) { - this.setState({ - card: null - }, () => { - if (!nextProps.editElem) return - let _card = fromJS(nextProps.editElem).toJS() - let bgImg = _card.backgroundImage || '' - - if (bgImg && /^linear-gradient/.test(bgImg)) { - bgImg = bgImg.replace('linear-gradient(', '') - bgImg = bgImg.replace(')', '') - } else if (bgImg && /^url/.test(bgImg)) { - bgImg = bgImg.replace('url(', '') - bgImg = bgImg.replace(')', '') - } - - this.setState({ - card: _card, - fontColor: _card.color || '#000000', - backgroundColor: _card.backgroundColor || '#ffffff', - backgroundImage: bgImg, - marginTop: _card.marginTop ? _card.marginTop : '', - marginTopVal: _card.marginTop ? parseInt(_card.marginTop) : '', - marginBottom: _card.marginBottom ? _card.marginBottom : '', - marginBottomVal: _card.marginBottomVal ? parseInt(_card.marginBottomVal) : '' - }) - }) - } - } - - shouldComponentUpdate (nextProps, nextState) { - return !is(fromJS(this.state), fromJS(nextState)) - } - - updateStyle = (style) => { - const { card } = this.state - - this.props.updateStyle({componentId: card.componentId, classId: card.classId, uuid: card.uuid, style}) - } - - /** - * @description 瀛椾綋澶у皬鍒囨崲锛岃秴鍑鸿寖鍥村拷鐣� - */ - changeFontSize = (val) => { - let value = parseInt(val) - - if (isNaN(value) || value < 12 || value > 100) return - - this.updateStyle({fontSize: `${value}px`}) - } - - /** - * @description 淇敼琛岄棿璺濓紝瓒呭嚭鑼冨洿蹇界暐 - */ - changeLineHeight = (val) => { - let value = parseFloat(val) - - if (isNaN(value) || value < 1 || value > 10) return - - this.updateStyle({lineHeight: value}) - } - - /** - * @description 瀛椾綋闂磋窛淇敼锛岃秴鍑鸿寖鍥村拷鐣� - */ - changeLetterSpacing = (val) => { - let value = parseFloat(val) - - if (isNaN(value) || value < 0 || value > 100) return - - this.updateStyle({letterSpacing: `${value}px`}) - } - - /** - * @description 淇敼瀛椾綋绮楃粏 - */ - boldChange = (val) => { - this.updateStyle({fontWeight: val}) - } - - /** - * @description 淇敼瀛椾綋棰滆壊 锛岄鑹叉帶浠� - */ - changeFontColor = (val) => { - this.setState({ - fontColor: val - }) - this.updateStyle({color: val}) - } - - /** - * @description 淇敼瀛椾綋棰滆壊 锛屾墜鍔ㄨ緭鍏� - */ - changeFontColorInput = (e) => { - this.setState({ - fontColor: e.target.value - }) - } - - /** - * @description 瀛椾綋瀵归綈 - */ - changeTextAlign = (e) => { - this.updateStyle({textAlign: e.target.value}) - } - - /** - * @description 瀛椾綋鏍峰紡锛屽�炬枩 - */ - changeFontStyle = (e) => { - this.updateStyle({fontStyle: e.target.value}) - } - - /** - * @description 瀛椾綋瑁呴グ锛屼笅鍒掔嚎銆佽疮绌跨嚎銆佷笂鍒掔嚎 - */ - changeTextDecoration = (e) => { - this.updateStyle({textDecoration: e.target.value}) - } - - /** - * @description 淇敼鑳屾櫙棰滆壊 锛岄鑹叉帶浠� - */ - changeBackgroundColor = (val) => { - this.setState({ - backgroundColor: val - }) - this.updateStyle({backgroundColor: val}) - } - - /** - * @description 淇敼瀛椾綋棰滆壊 锛屾墜鍔ㄨ緭鍏� - */ - changeBackgroundColorInput = (e) => { - this.setState({ - backgroundColor: e.target.value - }) - } - - imgChange = (list) => { - if (list[0] && list[0].response) { - this.setState({ - bgimages: [], - backgroundImage: list[0].response - }) - this.updateStyle({backgroundImage: `url(${list[0].response})`}) - } else { - this.setState({bgimages: list}) - } - } - - changeBackgroundImageInput = (e) => { - this.setState({ - backgroundImage: e.target.value - }) - } - - submitBackgroundImage = (e) => { - let val = e.target.value - val = val.replace(/^\s*|\s*$/ig, '') - - if (/^http|^\/\//.test(val)) { - val = `url(${val})` - } else if (/^#|,/ig.test(val)) { - val = `linear-gradient(${val})` - } - - this.updateStyle({backgroundImage: val}) - } - - submitBorder = (val, type) => { - this.updateStyle({[type]: val}) - } - - changeBorderRadius = (val) => { - let value = parseFloat(val) - - if (isNaN(value) || value < 0 || value > 500) return - - this.updateStyle({borderRadius: `${value}px`}) - } - - changeMarginTop = (e) => { - let val = e.target.value - let _val = parseInt(val) - - this.setState({ - marginTop: val - }) - - if (isNaN(_val)) return - - this.setState({ - marginTopVal: _val - }) - } - - submitMarginTop = (val) => { - this.setState({ - marginTop: val - }) - this.updateStyle({marginTop: val}) - } - - changeMarginBottom = (e) => { - let val = e.target.value - let _val = parseInt(val) - - this.setState({ - marginBottom: val - }) - - if (isNaN(_val)) return - - this.setState({ - marginBottomVal: _val - }) - } - - submitMarginBottom = (val) => { - this.setState({ - marginBottom: val - }) - this.updateStyle({marginBottom: val}) - } - - render () { - const { card, backgroundImage, bgimages, marginTop, marginTopVal, marginBottom, marginBottomVal } = this.state - const formItemLayout = { - labelCol: { - xs: { span: 24 }, - sm: { span: 8 } - }, - wrapperCol: { - xs: { span: 24 }, - sm: { span: 16 } - } - } - - return ( - <div className="mob-controller"> - <Form {...formItemLayout}> - {card ? <Collapse expandIconPosition="right" defaultActiveKey={card.items[0]} accordion={true}> - {card.items.includes('font') ? <Panel header="瀛椾綋" key="font"> - <Col span={12}> - <Form.Item colon={false} label={<Icon title="瀛椾綋澶у皬" type="font-size" />}> - <InputNumber defaultValue={card.fontSize || 14} min={12} max={100} precision={0} onChange={this.changeFontSize} /> - </Form.Item> - </Col> - <Col span={12}> - <Form.Item colon={false} label={<Icon title="瀛椾綋绮楃粏" type="bold" />}> - <Select defaultValue={card.fontWeight || 'normal'} onChange={this.boldChange}> - <Option value="normal">normal</Option> - <Option value="bold">bold</Option> - <Option value="bolder">bolder</Option> - <Option value="lighter">lighter</Option> - <Option value="100">100</Option> - <Option value="200">200</Option> - <Option value="300">300</Option> - <Option value="400">400</Option> - <Option value="500">500</Option> - <Option value="600">600</Option> - <Option value="700">700</Option> - <Option value="800">800</Option> - <Option value="900">900</Option> - </Select> - </Form.Item> - </Col> - <Col span={12}> - <Form.Item colon={false} label={<Icon title="琛岄棿璺�" type="line-height" />}> - <InputNumber defaultValue={card.lineHeight || 1.5} min={1} max={10} precision={1} onChange={this.changeLineHeight} /> - </Form.Item> - </Col> - <Col span={12}> - <Form.Item colon={false} label={<Icon title="瀛楅棿璺�" type="column-width" />}> - <InputNumber defaultValue={card.letterSpacing || 0} min={0} max={100} precision={0} onChange={this.changeLetterSpacing}/> - </Form.Item> - </Col> - <Col span={24}> - <Form.Item - colon={false} - label={<Icon title="瀛椾綋棰滆壊" type="font-colors" />} - labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } - > - <ColorSketch value={card.color || '#000000'} onChange={this.changeFontColor} /> - </Form.Item> - </Col> - <Col span={24}> - <Form.Item - colon={false} - label={' '} - labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } - > - <Radio.Group defaultValue={card.fontStyle || 'normal'} onChange={this.changeFontStyle}> - <Radio.Button value="normal"><span title="鏍囧噯">N</span></Radio.Button> - <Radio.Button value="italic"><Icon title="鏂滀綋" type="italic" /></Radio.Button> - <Radio.Button value="oblique" style={{fontStyle: 'oblique'}}><span title="鍊炬枩">B</span></Radio.Button> - </Radio.Group> - </Form.Item> - </Col> - <Col span={24}> - <Form.Item - colon={false} - label={' '} - labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } - > - <Radio.Group className="text-align" defaultValue={card.textAlign || 'left'} onChange={this.changeTextAlign}> - <Radio.Button value="left"><Icon title="宸﹀榻�" type="align-left" /></Radio.Button> - <Radio.Button value="center"><Icon title="灞呬腑瀵归綈" type="align-center" /></Radio.Button> - <Radio.Button value="right"><Icon title="鍙冲榻�" type="align-right" /></Radio.Button> - </Radio.Group> - </Form.Item> - </Col> - <Col span={24}> - <Form.Item - colon={false} - label={' '} - labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } - > - <Radio.Group className="text-decoration" defaultValue={card.textDecoration || 'none'} onChange={this.changeTextDecoration}> - <Radio.Button value="none"><span title="鏍囧噯">N</span></Radio.Button> - <Radio.Button value="underline"><Icon title="涓嬪垝绾�" type="underline" /></Radio.Button> - <Radio.Button value="line-through"><Icon title="涓垝绾�" type="strikethrough" /></Radio.Button> - <Radio.Button value="overline" style={{textDecoration: 'overline'}}><span title="涓婂垝绾�">O</span></Radio.Button> - </Radio.Group> - </Form.Item> - </Col> - </Panel> : null} - {card.items.includes('background') ? <Panel header="鑳屾櫙" key="background"> - <Col span={24}> - <Form.Item - colon={false} - label={<Icon title="鑳屾櫙棰滆壊" type="bg-colors" />} - labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } - > - <ColorSketch value={card.backgroundColor || '#ffffff'} onChange={this.changeBackgroundColor} /> - </Form.Item> - </Col> - <Col span={24}> - <Form.Item - colon={false} - label={<Icon title="鑳屾櫙鍥剧墖" type="picture" />} - labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } - > - <FileUpload accept=".jpg,.png,.gif,.svg" value={bgimages} maxFile={2} fileType="text" onChange={this.imgChange}/> - <Input placeholder="" value={backgroundImage} autoComplete="off" onBlur={this.submitBackgroundImage} onPressEnter={this.submitBackgroundImage} onChange={this.changeBackgroundImageInput} /> - </Form.Item> - </Col> - </Panel> : null} - {card.items.includes('border') ? <Panel header="杈规" key="border"> - <Col span={24}> - <Form.Item - colon={false} - label={<Icon title="澶栬竟妗�" type="border-outer" />} - labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } - > - <Input placeholder="" defaultValue={card.border || ''} autoComplete="off" onBlur={(e) => this.submitBorder(e.target.value, 'border')} onPressEnter={(e) => this.submitBorder(e.target.value, 'border')}/> - </Form.Item> - </Col> - <Col span={24}> - <Form.Item - colon={false} - label={<Icon title="宸﹁竟妗�" type="border-left" />} - labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } - > - <Input placeholder="" defaultValue={card.borderLeft || ''} autoComplete="off" onBlur={(e) => this.submitBorder(e.target.value, 'borderLeft')} onPressEnter={(e) => this.submitBorder(e.target.value, 'borderLeft')}/> - </Form.Item> - </Col> - <Col span={24}> - <Form.Item - colon={false} - label={<Icon title="鍙宠竟妗�" type="border-right" />} - labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } - > - <Input placeholder="" defaultValue={card.borderRight || ''} autoComplete="off" onBlur={(e) => this.submitBorder(e.target.value, 'borderRight')} onPressEnter={(e) => this.submitBorder(e.target.value, 'borderRight')}/> - </Form.Item> - </Col> - <Col span={24}> - <Form.Item - colon={false} - label={<Icon title="涓婅竟妗�" type="border-top" />} - labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } - > - <Input placeholder="" defaultValue={card.borderTop || ''} autoComplete="off" onBlur={(e) => this.submitBorder(e.target.value, 'borderTop')} onPressEnter={(e) => this.submitBorder(e.target.value, 'borderTop')}/> - </Form.Item> - </Col> - <Col span={24}> - <Form.Item - colon={false} - label={<Icon title="涓嬭竟妗�" type="border-bottom" />} - labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } - > - <Input placeholder="" defaultValue={card.borderBottom || ''} autoComplete="off" onBlur={(e) => this.submitBorder(e.target.value, 'borderBottom')} onPressEnter={(e) => this.submitBorder(e.target.value, 'borderBottom')}/> - </Form.Item> - </Col> - <Col span={24}> - <Form.Item - colon={false} - label={<Icon title="鍦嗚" type="radius-setting" />} - labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } - > - <InputNumber defaultValue={card.borderRadius || 0} min={0} max={500} precision={0} onChange={this.changeBorderRadius}/> - </Form.Item> - </Col> - </Panel> : null} - {card.items.includes('margin') ? <Panel header="澶栬竟璺�" key="margin"> - <Col span={12}> - <Form.Item - colon={false} - label={<Icon title="涓婅竟璺�" type="vertical-align-top"/>} - > - <Popover placement="bottom" overlayClassName="margin-popover" content={ - marginTopVal !== '' ? - <Menu> - <Menu.Item onClick={() => this.submitMarginTop(`${marginTopVal}px`)}>{marginTopVal} px</Menu.Item> - <Menu.Item onClick={() => this.submitMarginTop(`${marginTopVal}vh`)}>{marginTopVal} vh</Menu.Item> - </Menu> : null - } trigger="hover"> - <Input value={marginTop} onChange={this.changeMarginTop}/> - </Popover> - </Form.Item> - </Col> - <Col span={12}> - <Form.Item - colon={false} - label={<Icon title="涓嬭竟璺�" type="vertical-align-bottom"/>} - > - <Popover placement="bottom" overlayClassName="margin-popover" content={ - marginBottomVal !== '' ? - <Menu> - <Menu.Item onClick={() => this.submitMarginBottom(`${marginBottomVal}px`)}>{marginBottomVal} px</Menu.Item> - <Menu.Item onClick={() => this.submitMarginBottom(`${marginBottomVal}vh`)}>{marginBottomVal} vh</Menu.Item> - </Menu> : null - } trigger="hover"> - <Input value={marginBottom} onChange={this.changeMarginBottom}/> - </Popover> - </Form.Item> - </Col> - </Panel> : null} - </Collapse> : null} - </Form> - </div> - ) - } -} - -export default MobController \ No newline at end of file diff --git a/src/mob/controller/index.scss b/src/mob/controller/index.scss deleted file mode 100644 index 6acbf69..0000000 --- a/src/mob/controller/index.scss +++ /dev/null @@ -1,147 +0,0 @@ -.mob-controller { - width: 100%; - height: 100%; - overflow: hidden; - >.ant-form >.ant-collapse { - border: 0; - background: #262E3F; - - > .ant-collapse-item { - border-color: #202735; - > .ant-collapse-header { - padding: 10px 40px 10px 16px; - background: #262E3F; - color: rgba(255, 255, 255, 0.85); - } - >.ant-collapse-content { - color: rgba(255, 255, 255, 0.85); - background-color: #202735; - border-top: 1px solid #202735; - .ant-input-number { - width: 100%; - } - .ant-form-item { - margin-bottom: 5px; - - .ant-form-item-label > label { - color: rgba(255, 255, 255, 0.85); - .anticon { - vertical-align: middle; - font-size: 18px; - } - } - .ant-form-item-control-wrapper { - .ant-form-item-control { - input { - background: transparent; - color: rgba(255, 255, 255, 0.65); - } - .ant-input { - height: 28px; - } - .ant-input-number { - height: 28px; - background: transparent; - .ant-input-number-input { - height: 28px; - } - } - .ant-select-selection { - background: transparent; - color: rgba(255, 255, 255, 0.65); - } - .color-sketch-block { - position: relative; - top: 10px; - } - .color-sketch-block + .ant-input { - float: right; - width: 70%; - margin-top: 9px; - padding-right: 5px; - padding-left: 5px; - } - .ant-select-arrow { - color: inherit; - } - .ant-input-number-handler-wrap { - background: transparent; - .ant-input-number-handler { - color: rgba(255, 255, 255, 0.65); - .ant-input-number-handler-up-inner, .ant-input-number-handler-down-inner { - color: rgba(255, 255, 255, 0.65); - } - } - .ant-input-number-handler:active { - background: transparent; - } - } - .ant-radio-group { - .ant-radio-button-wrapper { - background: transparent; - color: rgba(255, 255, 255, 0.65); - height: 27px; - line-height: 25px; - span { - font-style: inherit; - } - } - } - .fileupload-form-container { - .ant-btn { - height: 28px; - } - .ant-upload-list-item { - .ant-upload-list-item-info { - background: transparent; - color: rgba(255, 255, 255, 0.85); - i { - color: rgba(255, 255, 255, 0.85); - } - } - .anticon-close { - color: rgba(255, 255, 255, 0.85); - } - .anticon-close:hover { - color: rgba(255, 255, 255, 0.85); - } - } - .ant-upload-list-item:hover .ant-upload-list-item-info { - background: transparent; - } - } - } - } - } - } - } - } -} - -.margin-popover { - padding-top: 0px; - .ant-popover-inner-content { - width: 90px; - padding: 0px 5px; - .ant-menu-root.ant-menu-vertical { - border: 0; - .ant-menu-item { - height: 30px; - cursor: pointer; - line-height: 30px; - } - .ant-menu-item:not(:last-child) { - margin-bottom: 0px; - } - .ant-menu-item:first-child { - margin-top: 10px; - } - .ant-menu-item:last-child { - margin-bottom: 10px; - } - } - } - .ant-popover-arrow { - display: none; - } -} \ No newline at end of file diff --git a/src/mob/contupdate/index.jsx b/src/mob/contupdate/index.jsx deleted file mode 100644 index 95734cf..0000000 --- a/src/mob/contupdate/index.jsx +++ /dev/null @@ -1,137 +0,0 @@ -import React, {Component} from 'react' -import PropTypes from 'prop-types' -// import { is, fromJS } from 'immutable' -import { Form, Icon, Popover, Input, Modal } from 'antd' - -import zhCN from '@/locales/zh-CN/mob.js' -import enUS from '@/locales/en-US/mob.js' -import FileUpload from '@/tabviews/zshare/fileupload' -import './index.scss' - -const { TextArea } = Input -const { confirm } = Modal - -class ContentUpdate extends Component { - static propTpyes = { - deletable: PropTypes.any, - element: PropTypes.object, - updateContent: PropTypes.func - } - - state = { - dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, - images: [], - visible: false - } - - UNSAFE_componentWillMount () { - - } - - // shouldComponentUpdate (nextProps, nextState) { - // return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) - // } - - onVisibleChange = (visible) => { - const { element } = this.props - let val = this.props.form.getFieldValue('content') - let _url = this.props.form.getFieldValue('url') - - this.setState({ - visible: visible - }) - - if (element.eleType === 'link') { - if ((val && element.content !== val) || (_url && element.url !== _url)) { - this.props.updateContent({...element, content: val, url: _url}) - } else { - this.props.form.setFieldsValue({content: element.content, url: element.url}) - } - } else { - if (val && element.content !== val) { - this.props.updateContent({...element, content: val}) - } else { - this.props.form.setFieldsValue({content: element.content}) - } - } - } - - handleSubmit = () => { - const { element } = this.props - let val = this.props.form.getFieldValue('content') - - this.setState({ - visible: false - }) - - if (val && element.content !== val) { - this.props.updateContent({...element, content: val}) - } else { - this.props.form.setFieldsValue({content: element.content}) - } - } - - deleteElement = () => { - const _this = this - - confirm({ - title: '纭畾鍒犻櫎鍏冪礌鍚楋紵', - onOk() { - _this.props.updateContent(null) - }, - onCancel() {} - }) - } - - imgChange = (list) => { - const { element } = this.props - - this.setState({images: list}) - if (list && list.length && list[0].response) { - this.setState({ - visible: false, - images: [] - }) - let val = list[0].response - if (val && element.content !== val) { - this.props.updateContent({...element, content: val}) - } - this.props.form.setFieldsValue({content: val}) - } - } - - render () { - const { element, deletable } = this.props - const { getFieldDecorator } = this.props.form - const { visible, images } = this.state - - return ( - <div className="mob-content-update"> - {deletable !== false ? <Icon type="delete" onClick={this.deleteElement} /> : null} - <Popover content={ - <div> - {element.eleType === 'img' ? <FileUpload accept=".jpg,.png,.gif,.svg" value={images} maxFile={1} fileType="text" onChange={this.imgChange}/> : null} - {getFieldDecorator('content', { - initialValue: element.content - })(element.eleType !== 'textarea' ? - <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} /> : - <TextArea autoSize={{ minRows: 2, maxRows: 3 }} onPressEnter={this.handleSubmit} /> - )} - {element.eleType === 'link' ? <div className="link-url"> - <p>閾炬帴鍦板潃:</p> - {getFieldDecorator('url', { - initialValue: element.url - })( - <Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} /> - )} - </div> : null} - </div> - } overlayClassName="mob-content-update-popover" placement="bottomRight" title="" visible={visible} trigger="click" onVisibleChange={this.onVisibleChange}> - <Icon type="edit" /> - </Popover> - </div> - ) - } -} - -export default Form.create()(ContentUpdate) \ No newline at end of file diff --git a/src/mob/contupdate/index.scss b/src/mob/contupdate/index.scss deleted file mode 100644 index 34a4615..0000000 --- a/src/mob/contupdate/index.scss +++ /dev/null @@ -1,53 +0,0 @@ -.mob-content-update { - position: absolute; - top: -22px; - right: -1px; - border-radius: 2px; - color: #ffffff; - font-size: 14px; - display: none; - line-height: 1.5; - z-index: 1; - white-space: nowrap; - - i { - padding: 2px 5px; - cursor: pointer; - background: #2f54eb; - } - .anticon-delete { - background: #ff4d4f; - } -} -.editing .mob-content-update { - display: inline-block; -} -.mob-content-update-popover { - .ant-popover-content { - margin-top: -5px; - .ant-popover-arrow { - top: 1px; - } - - .fileupload-form-container { - display: block; - margin-bottom: 10px; - .ant-upload-list { - width: 250px; - } - } - } - input { - width: 250px; - } - textarea { - width: 270px; - } - .link-url { - p { - margin: 10px 0px 5px 5px; - font-size: 14px; - color: #959595; - } - } -} diff --git a/src/mob/datasource/index.jsx b/src/mob/datasource/index.jsx deleted file mode 100644 index 06abe17..0000000 --- a/src/mob/datasource/index.jsx +++ /dev/null @@ -1,161 +0,0 @@ -import React, {Component} from 'react' -import PropTypes from 'prop-types' -import { is, fromJS } from 'immutable' -import { Icon, Modal } from 'antd' - -import Utils from '@/utils/utils.js' -import zhCN from '@/locales/zh-CN/mob.js' -import enUS from '@/locales/en-US/mob.js' -import VerifyCard from './verifycard' -import './index.scss' - -const { confirm } = Modal - -class DataSource extends Component { - static propTpyes = { - config: PropTypes.any, - updateConfig: PropTypes.func - } - - state = { - dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, - sourcelist: [], - searches: [], - visible: false, - loading: false, - source: null - } - - UNSAFE_componentWillMount () { - const { config } = this.props - - this.setState({sourcelist: config.sourcelist || []}) - } - - UNSAFE_componentWillReceiveProps(nextProps) { - - } - - shouldComponentUpdate (nextProps, nextState) { - return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) - } - - editDataSource = (item) => { - // const { config } = this.props - - if (!item) { - item = { - uuid: Utils.getuuid(), - setting: {}, - columns: [], - scripts: [] - } - } - - this.setState({ - visible: true, - source: item, - searches: [] - }) - } - - closeDataSource = (item) => { - const { config } = this.props - let sourcelist = fromJS(this.state.sourcelist).toJS() - const _this = this - - sourcelist = sourcelist.filter(cell => cell.uuid !== item.uuid) - - confirm({ - title: '纭畾鍒犻櫎鏁版嵁婧愬悧锛�', - content: '', - onOk() { - _this.setState({sourcelist}) - _this.props.updateConfig({...config, sourcelist: fromJS(sourcelist).toJS()}) - }, - onCancel() {} - }) - } - - verifySubmit = () => { - const { config } = this.props - let sourcelist = fromJS(this.state.sourcelist).toJS() - - this.setState({loading: true}) - this.verifyRef.submitDataSource().then((res) => { - let isadd = true - sourcelist = sourcelist.map(item => { - if (item.uuid === res.uuid) { - isadd = false - return res - } else { - return item - } - }) - - if (isadd) { - sourcelist.push(res) - } - - this.setState({loading: false, visible: false, sourcelist}) - this.props.updateConfig({...config, sourcelist: fromJS(sourcelist).toJS()}) - }, () => { - this.setState({loading: false}) - }) - } - - render () { - const { config } = this.props - const { sourcelist, visible, source, dict, searches, loading } = this.state - - let addable = true - if (config.components && config.components.length === 1 && config.components[0].type === 'login') { - addable = false - } - - return ( - <div className="mob-datasource"> - {sourcelist.map(item => ( - <span className="mob-input-group-wrapper" key={item.uuid}> - <span className="mob-input-wrapper"> - <span className="mob-input-value">{item.setting.name}</span> - <span className="mob-input-group-addon"> - <Icon type="setting" onClick={() => this.editDataSource(item)} /> - <Icon type="close" onClick={() => this.closeDataSource(item)} /> - </span> - </span> - </span> - ))} - {addable ? <span className="mob-input-group-wrapper"> - <span className="mob-input-wrapper"> - <span className="mob-input-insert" onClick={() => this.editDataSource()}> - <Icon type="plus" /> - </span> - </span> - </span> : null} - <Modal - wrapClassName="mob-datasource-verify-modal popview-modal" - title={'鏁版嵁婧愰厤缃�'} - visible={visible} - width={'75vw'} - maskClosable={false} - okText={dict['mob.submit']} - onOk={this.verifySubmit} - confirmLoading={loading} - onCancel={() => { this.setState({ visible: false }) }} - destroyOnClose - > - <VerifyCard - dict={dict} - card={source} - menuId={this.props.config.uuid} - searches={searches} - wrappedComponentRef={(inst) => this.verifyRef = inst} - /> - </Modal> - </div> - ) - } -} - -export default DataSource \ No newline at end of file diff --git a/src/mob/datasource/index.scss b/src/mob/datasource/index.scss deleted file mode 100644 index ea28922..0000000 --- a/src/mob/datasource/index.scss +++ /dev/null @@ -1,89 +0,0 @@ -.mob-datasource { - width: 100%; - height: 100%; - overflow: hidden; - padding-top: 15px; - - .mob-input-group-wrapper { - padding: 0 20px; - display: inline-block; - width: 100%; - text-align: start; - vertical-align: top; - margin-bottom: 15px; - - .mob-input-wrapper { - position: relative; - display: table; - width: 100%; - border-collapse: separate; - border-spacing: 0; - - .mob-input-value { - display: table-cell; - width: 100%; - border: 1px solid #d9d9d9; - border-radius: 4px 0px 0px 4px; - overflow: hidden; - text-overflow:ellipsis; - white-space: nowrap; - padding: 2px 10px; - color: #ffffff; - } - - .mob-input-group-addon { - display: table-cell; - width: 1px; - position: relative; - padding: 0 11px; - color: rgba(0, 0, 0, 0.65); - font-weight: normal; - font-size: 14px; - line-height: 1; - text-align: center; - background-color: #fafafa; - border: 1px solid #d9d9d9; - border-radius: 0px 4px 4px 0px; - white-space: nowrap; - } - - .mob-input-insert { - display: table-cell; - width: 100%; - border: 1px dotted #d9d9d9; - border-radius: 4px; - text-align: center; - cursor: pointer; - - .anticon-plus { - padding: 6px; - font-size: 16px; - color: rgb(38, 194, 129); - } - } - } - .anticon-setting { - margin-right: 5px; - padding: 6px; - cursor: pointer; - } - .anticon-setting:hover { - color: #1890ff; - } - .anticon-close { - padding: 6px; - cursor: pointer; - } - .anticon-close:hover { - color: #ff4d4f; - } - } -} -.mob-datasource-verify-modal { - .ant-modal { - top: 50px; - .ant-modal-body { - max-height: calc(100vh - 190px); - } - } -} \ No newline at end of file diff --git a/src/mob/datasource/verifycard/columnform/index.jsx b/src/mob/datasource/verifycard/columnform/index.jsx deleted file mode 100644 index 31fbe81..0000000 --- a/src/mob/datasource/verifycard/columnform/index.jsx +++ /dev/null @@ -1,137 +0,0 @@ -import React, {Component} from 'react' -import PropTypes from 'prop-types' -import { Form, Row, Col, Select, Button, Input } from 'antd' -import './index.scss' - - -class UniqueForm extends Component { - static propTpyes = { - dict: PropTypes.object, // 瀛楀吀椤� - columnChange: PropTypes.func // 淇敼鍑芥暟 - } - - state = { - editItem: null // 缂栬緫鍏冪礌 - } - - edit = (record) => { - this.setState({ - editItem: record - }) - - this.props.form.setFieldsValue({ - label: record.label, - field: record.field, - datatype: record.datatype - }) - } - - - handleConfirm = () => { - // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭� - this.props.form.validateFieldsAndScroll((err, values) => { - if (!err) { - values.uuid = this.state.editItem ? this.state.editItem.uuid : '' - - this.setState({ - editItem: null - }, () => { - this.props.columnChange(values) - }) - this.props.form.setFieldsValue({ - label: '', - field: '' - }) - } - }) - } - - render() { - const { getFieldDecorator } = this.props.form - const formItemLayout = { - labelCol: { - xs: { span: 24 }, - sm: { span: 8 } - }, - wrapperCol: { - xs: { span: 24 }, - sm: { span: 16 } - } - } - - return ( - <Form {...formItemLayout} className="verify-form" id="verifycard1"> - <Row gutter={24}> - <Col span={7}> - <Form.Item label={'鍚嶇О'}> - {getFieldDecorator('label', { - initialValue: '', - rules: [ - { - required: true, - message: this.props.dict['form.required.input'] + '鍚嶇О!' - } - ] - })(<Input placeholder="" autoComplete="off" />)} - </Form.Item> - </Col> - <Col span={7}> - <Form.Item label={'瀛楁'}> - {getFieldDecorator('field', { - initialValue: '', - rules: [ - { - required: true, - message: this.props.dict['form.required.input'] + '瀛楁!' - } - ] - })(<Input placeholder="" autoComplete="off" />)} - </Form.Item> - </Col> - <Col span={7}> - <Form.Item label={'鏁版嵁绫诲瀷'}> - {getFieldDecorator('datatype', { - initialValue: '', - rules: [ - { - required: true, - message: this.props.dict['form.required.select'] + '鏁版嵁绫诲瀷!' - } - ] - })( - <Select> - <Select.Option value="Nvarchar(10)"> Nvarchar(10) </Select.Option> - <Select.Option value="Nvarchar(20)"> Nvarchar(20) </Select.Option> - <Select.Option value="Nvarchar(50)"> Nvarchar(50) </Select.Option> - <Select.Option value="Nvarchar(100)"> Nvarchar(100) </Select.Option> - <Select.Option value="Nvarchar(512)"> Nvarchar(512) </Select.Option> - <Select.Option value="Nvarchar(1024)"> Nvarchar(1024) </Select.Option> - <Select.Option value="Nvarchar(2048)"> Nvarchar(2048) </Select.Option> - <Select.Option value="Nvarchar(max)"> Nvarchar(max) </Select.Option> - <Select.Option value="Int"> Int </Select.Option> - <Select.Option value="Decimal(18,0)"> Decimal(18,0) </Select.Option> - <Select.Option value="Decimal(18,1)"> Decimal(18,1) </Select.Option> - <Select.Option value="Decimal(18,2)"> Decimal(18,2) </Select.Option> - <Select.Option value="Decimal(18,3)"> Decimal(18,3) </Select.Option> - <Select.Option value="Decimal(18,4)"> Decimal(18,4) </Select.Option> - <Select.Option value="Decimal(18,5)"> Decimal(18,5) </Select.Option> - <Select.Option value="Decimal(18,6)"> Decimal(18,6) </Select.Option> - <Select.Option value="Decimal(18,7)"> Decimal(18,7) </Select.Option> - <Select.Option value="Decimal(18,8)"> Decimal(18,8) </Select.Option> - <Select.Option value="date"> date </Select.Option> - </Select> - )} - </Form.Item> - </Col> - <Col span={3} className="add"> - <Button onClick={this.handleConfirm} type="primary" className="mk-green"> - 淇濆瓨 - </Button> - </Col> - </Row> - </Form> - ) - } -} - -export default Form.create()(UniqueForm) \ No newline at end of file diff --git a/src/mob/datasource/verifycard/columnform/index.scss b/src/mob/datasource/verifycard/columnform/index.scss deleted file mode 100644 index e69de29..0000000 --- a/src/mob/datasource/verifycard/columnform/index.scss +++ /dev/null diff --git a/src/mob/datasource/verifycard/customscript/index.jsx b/src/mob/datasource/verifycard/customscript/index.jsx deleted file mode 100644 index 5267ea7..0000000 --- a/src/mob/datasource/verifycard/customscript/index.jsx +++ /dev/null @@ -1,229 +0,0 @@ -import React, {Component} from 'react' -import PropTypes from 'prop-types' -import { Form, Row, Col, Button, notification, Select } from 'antd' - -import Utils from '@/utils/utils.js' -import CodeMirror from '@/templates/zshare/codemirror' -import './index.scss' - -class CustomForm extends Component { - static propTpyes = { - type: PropTypes.string, // 鑿滃崟绫诲瀷 - dict: PropTypes.object, // 瀛楀吀椤� - setting: PropTypes.object, // 璁剧疆 - searches: PropTypes.array, // 鎼滅储鏉′欢 - swhere: PropTypes.string, // where鏉′欢 - arr_field: PropTypes.string, // 鍒楀瓧娈� - regoptions: PropTypes.array, // 姝e垯鏇挎崲 - systemScripts: PropTypes.array, // 绯荤粺鑴氭湰 - scriptSubmit: PropTypes.func, // 鑴氭湰楠岃瘉鍚庢彁浜� - scriptsChange: PropTypes.func // 鑴氭湰楠岃瘉 - } - - state = { - editItem: null, - loading: false, - usefulFields: '' - } - - UNSAFE_componentWillMount() { - const { searches } = this.props - - let _usefulFields = [] - searches.forEach(item => { - if (item.type === 'group') { - if (item.transfer === 'true') { - _usefulFields.push(item.field) - } - _usefulFields.push(item.datefield) - _usefulFields.push(item.datefield + '1') - } else if (['dateweek', 'datemonth', 'daterange'].includes(item.type)) { - _usefulFields.push(item.field) - _usefulFields.push(item.field + '1') - } else if (_usefulFields.includes(item.field)) { - _usefulFields.push(item.field + '1') - } else { - _usefulFields.push(item.field) - } - }) - - this.setState({ - usefulFields: _usefulFields.join(', ') - }) - } - - edit = (record) => { - this.setState({ - editItem: record - }) - - this.props.form.setFieldsValue({ - sql: record.sql - }) - } - - handleCancel = () => { - this.setState({ - editItem: null - }) - this.props.form.setFieldsValue({ - sql: '' - }) - } - - handleConfirm = () => { - // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭� - this.props.form.validateFieldsAndScroll((err, values) => { - if (!err) { - values.uuid = this.state.editItem ? this.state.editItem.uuid : '' - - let _quot = values.sql.match(/'{1}/g) - let _lparen = values.sql.match(/\({1}/g) - let _rparen = values.sql.match(/\){1}/g) - - _quot = _quot ? _quot.length : 0 - _lparen = _lparen ? _lparen.length : 0 - _rparen = _rparen ? _rparen.length : 0 - - if (_quot % 2 !== 0) { - notification.warning({ - top: 92, - message: 'sql涓璡'蹇呴』鎴愬鍑虹幇', - duration: 5 - }) - return - } else if (_lparen !== _rparen) { - notification.warning({ - top: 92, - message: 'sql涓�()蹇呴』鎴愬鍑虹幇', - duration: 5 - }) - return - } else if (/--/ig.test(values.sql)) { - notification.warning({ - top: 92, - message: '鑷畾涔塻ql璇彞涓紝涓嶅彲鍑虹幇瀛楃 -- 锛屾敞閲婅鐢� /*鍐呭*/', - duration: 5 - }) - return - } - - let error = Utils.verifySql(values.sql, 'customscript') - - if (error) { - notification.warning({ - top: 92, - message: 'sql涓笉鍙娇鐢�' + error, - duration: 5 - }) - return - } - - this.setState({loading: true}) - this.props.scriptsChange(values).then(() => { - this.setState({ - editItem: null, - loading: false - }) - this.props.form.setFieldsValue({ - sql: '' - }) - this.props.scriptSubmit(values) - }) - } - }) - } - - selectScript = (value, option) => { - let _sql = this.props.form.getFieldValue('sql') - if (_sql) { - _sql = _sql + ` - - ` - } - - _sql = _sql.replace(/\s{6}$/, '') - _sql = _sql + `/*${option.props.children}*/ - ` - _sql = _sql.replace(/\s{4}$/, '') - _sql = _sql + value - - this.props.form.setFieldsValue({ - sql: _sql - }) - } - - render() { - const { systemScripts, setting } = this.props - const { getFieldDecorator } = this.props.form - const { usefulFields } = this.state - const formItemLayout = { - labelCol: { - xs: { span: 24 }, - sm: { span: 8 } - }, - wrapperCol: { - xs: { span: 24 }, - sm: { span: 16 } - } - } - - return ( - <Form {...formItemLayout} className="modal-menu-setting-script"> - <Row gutter={24}> - {setting.tableName ? <Col span={8}> - <Form.Item label={'琛ㄥ悕'} style={{whiteSpace: 'nowrap', margin: 0}}> - {setting.tableName} - </Form.Item> - </Col> : null} - <Col span={16}> - <Form.Item label={'鎶ラ敊瀛楁'} style={{margin: 0}}> - ErrorCode, retmsg - </Form.Item> - </Col> - <Col span={24} className="sqlfield"> - <Form.Item label={'鍙敤瀛楁'}> - id, bid, loginuid, sessionuid, userid, appkey, time_id, orderBy{setting.laypage !== 'false' ? ', pageSize, pageIndex': ''}{usefulFields ? ', ' + usefulFields : ''} - </Form.Item> - </Col> - <Col span={10}> - <Form.Item label={'蹇嵎娣诲姞'} style={{marginBottom: 0}}> - <Select - showSearch - filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} - onChange={this.selectScript} - > - {systemScripts.map((option, i) => - <Select.Option style={{whiteSpace: 'normal'}} key={i} value={option.value}>{option.name}</Select.Option> - )} - </Select> - </Form.Item> - </Col> - <Col span={6} className="add"> - <Button onClick={this.handleConfirm} loading={this.state.loading} className="mk-green" style={{marginTop: 5, marginBottom: 15, marginLeft: 30}}> - 淇濆瓨 - </Button> - <Button onClick={this.handleCancel} style={{marginTop: 5, marginBottom: 15, marginLeft: 10}}> - 鍙栨秷 - </Button> - </Col> - <Col span={24} className="sql"> - <Form.Item label={'sql'}> - {getFieldDecorator('sql', { - initialValue: '', - rules: [ - { - required: true, - message: this.props.dict['mob.required.input'] + 'sql!' - } - ] - })(<CodeMirror />)} - </Form.Item> - </Col> - </Row> - </Form> - ) - } -} - -export default Form.create()(CustomForm) \ No newline at end of file diff --git a/src/mob/datasource/verifycard/customscript/index.scss b/src/mob/datasource/verifycard/customscript/index.scss deleted file mode 100644 index 2a1d2d8..0000000 --- a/src/mob/datasource/verifycard/customscript/index.scss +++ /dev/null @@ -1,34 +0,0 @@ -.modal-menu-setting-script { - .sqlfield { - .ant-form-item { - margin-bottom: 5px; - } - .ant-form-item-control { - line-height: 24px; - } - .ant-form-item-label { - line-height: 25px; - } - .ant-form-item-children { - line-height: 22px; - } - .ant-col-sm-8 { - width: 10.5%; - } - .ant-col-sm-16 { - width: 89.5%; - } - } - .sql { - .ant-col-sm-8 { - width: 10.5%; - } - .ant-col-sm-16 { - width: 89.5%; - padding-top: 4px; - } - .CodeMirror { - height: 350px; - } - } -} \ No newline at end of file diff --git a/src/mob/datasource/verifycard/index.jsx b/src/mob/datasource/verifycard/index.jsx deleted file mode 100644 index 2d619ec..0000000 --- a/src/mob/datasource/verifycard/index.jsx +++ /dev/null @@ -1,519 +0,0 @@ -import React, {Component} from 'react' -import PropTypes from 'prop-types' -import { fromJS } from 'immutable' -import { Form, Tabs, Table, Popconfirm, Icon, notification, Modal, Typography, Spin } from 'antd' -import moment from 'moment' - -import Api from '@/api' -import Utils from '@/utils/utils.js' - -import ColForm from './columnform' -import CustomScriptsForm from './customscript' -import SettingForm from './settingform' -import SettingUtils from './utils' -import './index.scss' - -const { TabPane } = Tabs -const { Paragraph } = Typography - -class VerifyCard extends Component { - static propTpyes = { - dict: PropTypes.object, // 瀛楀吀椤� - card: PropTypes.object, // 鏁版嵁婧愪俊鎭� - menuId: PropTypes.string, // 鑿滃崟Id - searches: PropTypes.array, // 鎼滅储鏉′欢 - } - - state = { - columns: [], - activeKey: 'setting', - loading: false, - initsql: '', // sql楠岃瘉鏃跺彉閲忓0鏄庡強璧嬪�� - usefulfields: '', - defaultsql: '', // 榛樿Sql - systemScripts: [], - colColumns: [ - { - title: '鍚嶇О', - dataIndex: 'label', - width: '25%' - }, - { - title: '瀛楁', - dataIndex: 'field', - width: '25%' - }, - { - title: '鏁版嵁绫诲瀷', - dataIndex: 'datatype', - width: '25%', - }, - { - title: '鎿嶄綔', - align: 'center', - width: '25%', - dataIndex: 'operation', - render: (text, record) => - (<div> - <span className="operation-btn" title={this.props.dict['mob.edit']} onClick={() => this.handleEdit(record, 'columns')} style={{color: '#1890ff'}}><Icon type="edit" /></span> - <Popconfirm - overlayClassName="popover-confirm" - title={this.props.dict['mob.query.delete']} - onConfirm={() => this.deleteColumn(record) - }> - <span className="operation-btn" style={{color: '#ff4d4f'}}><Icon type="delete" /></span> - </Popconfirm> - </div>) - } - ], - scriptsColumns: [ - { - title: 'SQL', - dataIndex: 'sql', - width: '60%', - render: (text) => ( - <Paragraph copyable ellipsis={{ rows: 5, expandable: true }}>{text}</Paragraph> - ) - }, - { - title: '鐘舵��', - dataIndex: 'status', - width: '20%', - render: (text, record) => record.status === 'false' ? - ( - <div> - {this.props.dict['mob.status.forbidden']} - <Icon style={{marginLeft: '5px'}} type="stop" theme="twoTone" twoToneColor="#ff4d4f" /> - </div> - ) : - ( - <div> - {this.props.dict['mob.status.open']} - <Icon style={{marginLeft: '5px'}} type="check-circle" theme="twoTone" twoToneColor="#52c41a" /> - </div> - ) - }, - { - title: '鎿嶄綔', - align: 'center', - width: '20%', - dataIndex: 'operation', - render: (text, record) => - (<div> - <span className="operation-btn" title={this.props.dict['model.edit']} onClick={() => this.handleEdit(record, 'scripts')} style={{color: '#1890ff'}}><Icon type="edit" /></span> - <span className="operation-btn" onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span> - <span className="operation-btn" onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span> - <span className="operation-btn" title={this.props.dict['mob.status.change']} onClick={() => this.handleStatus(record)} style={{color: '#8E44AD'}}><Icon type="swap" /></span> - <Popconfirm - overlayClassName="popover-confirm" - title={this.props.dict['mob.query.delete']} - onConfirm={() => this.deleteScript(record) - }> - <span className="operation-btn" style={{color: '#ff4d4f'}}><Icon type="delete" /></span> - </Popconfirm> - </div>) - } - ] - } - - UNSAFE_componentWillMount() { - const { card } = this.props - - this.setState({ - columns: fromJS(card.columns).toJS(), - setting: fromJS(card.setting).toJS(), - scripts: fromJS(card.scripts).toJS() - }) - } - - getsysScript = () => { - let _scriptSql = `Select distinct func+Remark as funcname,longparam, s.Sort from聽 s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid = case when s.appkey='' then s.openid else p.OpenID end order by s.Sort` - - _scriptSql = Utils.formatOptions(_scriptSql) - - let _sParam = { - func: 'sPC_Get_SelectedList', - LText: _scriptSql, - obj_name: 'data', - arr_field: 'funcname,longparam' - } - - _sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') - _sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp) - - _sParam.open_key = Utils.encryptOpenKey(_sParam.secretkey, _sParam.timestamp) // 浜戠鏁版嵁楠岃瘉 - - Api.getSystemConfig(_sParam).then(res => { - if (res.status) { - let _scripts = [] - - res.data.forEach(item => { - let _item = { - name: item.funcname, - value: window.decodeURIComponent(window.atob(item.longparam)) - } - - _scripts.push(_item) - }) - - this.setState({ - systemScripts: _scripts - }) - } else { - notification.warning({ - top: 92, - message: res.message, - duration: 5 - }) - } - }) - } - - columnChange = (values) => { - let columns = fromJS(this.state.columns).toJS() - - if (values.uuid) { - columns = columns.map(item => { - if (item.uuid === values.uuid) { - return values - } else { - return item - } - }) - } else { - values.uuid = Utils.getuuid() - columns.push(values) - } - - this.setState({ columns }) - } - - deleteColumn = (record) => { - this.setState({ columns: this.state.columns.filter(item => item.uuid !== record.uuid) }) - } - - deleteScript = (record) => { - this.setState({ scripts: this.state.scripts.filter(item => item.uuid !== record.uuid) }) - } - - handleEdit = (record, type) => { - if (type === 'scripts') { - this.scriptsForm.edit(record) - } else if (type === 'columns') { - this.contrastForm.edit(record) - } - - let node = document.getElementById('mob-verify-card-box-tab').parentNode - - if (node && node.scrollTop) { - let inter = Math.ceil(node.scrollTop / 10) - - let timer = setInterval(() => { - if (node.scrollTop - inter > 0) { - node.scrollTop = node.scrollTop - inter - } else { - node.scrollTop = 0 - clearInterval(timer) - } - }, 10) - } - } - - handleStatus = (record) => { - let scripts = fromJS(this.state.scripts).toJS() - record.status = record.status === 'false' ? 'true' : 'false' - - scripts = scripts.map(item => { - if (item.uuid === record.uuid) { - return record - } else { - return item - } - }) - - this.setState({ scripts }) - } - - handleUpDown = (record, direction) => { - let scripts = fromJS(this.state.scripts).toJS() - let index = 0 - - scripts = scripts.filter((item, i) => { - if (item.uuid === record.uuid) { - index = i - } - - return item.uuid !== record.uuid - }) - if ((index === 0 && direction === 'up') || (index === scripts.length && direction === 'down')) { - return - } - - if (direction === 'up') { - scripts.splice(index - 1, 0, record) - } else { - scripts.splice(index + 1, 0, record) - } - - this.setState({ scripts }) - } - - scriptsChange = (values) => { - let scripts = fromJS(this.state.scripts).toJS() - - if (values.uuid) { - scripts = scripts.map(item => { - if (item.uuid === values.uuid) { - return values - } else { - return item - } - }) - } else { - scripts.push(values) - } - - return new Promise((resolve, reject) => { - this.sqlverify(resolve, reject, false, scripts) - }) - } - - scriptSubmit = (values) => { - let scripts = fromJS(this.state.scripts).toJS() - - if (values.uuid) { - scripts = scripts.map(item => { - if (item.uuid === values.uuid) { - return values - } else { - return item - } - }) - } else { - values.uuid = Utils.getuuid() - scripts.push(values) - } - - this.setState({ scripts }) - } - - changeTab = (val) => { - const { activeKey } = this.state - - this.setState({loading: true}) - if (activeKey === 'setting') { - this.settingForm.handleConfirm().then(res => { - this.setState({ - setting: res - }, () => { - this.sqlverify(() => { // 楠岃瘉鎴愬姛 - this.setState({ - activeKey: val, - loading: false - }) - }, () => { // 楠岃瘉澶辫触 - this.setState({ - loading: false - }) - }, true) - }) - }, () => { - this.setState({loading: false}) - }) - } else if (activeKey === 'columns') { - this.sqlverify(() => { // 楠岃瘉鎴愬姛 - this.setState({ - activeKey: val, - loading: false - }) - }, () => { // 楠岃瘉澶辫触 - this.setState({ - loading: false - }) - }, true) - } else if (activeKey === 'scripts') { - let _loading = false - if (this.scriptsForm && this.scriptsForm.state.editItem) { - _loading = true - } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) { - _loading = true - } - - if (_loading) { - notification.warning({ - top: 92, - message: '瀛樺湪鏈繚瀛樿剼鏈紝璇风偣鍑荤‘瀹氫繚瀛橈紝鎴栫偣鍑诲彇娑堟斁寮冧慨鏀癸紒', - duration: 5 - }) - this.setState({ - loading: false - }) - return - } - - this.sqlverify(() => { // 楠岃瘉鎴愬姛 - this.setState({ - activeKey: val, - loading: false - }) - }, () => { // 楠岃瘉澶辫触 - this.setState({ - loading: false - }) - }, true) - } - } - - submitDataSource = () => { - const { card } = this.props - const { activeKey, setting, columns, scripts } = this.state - - return new Promise((resolve, reject) => { - if (activeKey === 'setting') { - this.settingForm.handleConfirm().then(res => { - this.setState({ - setting: res - }, () => { - this.sqlverify(() => { resolve({uuid: card.uuid, setting: res, columns, scripts }) }, reject, false) - }) - }, () => { - reject() - }) - } else if (activeKey === 'columns') { - this.sqlverify(() => { resolve({uuid: card.uuid, setting, columns, scripts }) }, reject, false) - } else if (activeKey === 'scripts') { - let _loading = false - if (this.scriptsForm && this.scriptsForm.state.editItem) { - _loading = true - } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) { - _loading = true - } - - if (_loading) { - notification.warning({ - top: 92, - message: '瀛樺湪鏈繚瀛樿剼鏈紝璇风偣鍑荤‘瀹氫繚瀛橈紝鎴栫偣鍑诲彇娑堟斁寮冧慨鏀癸紒', - duration: 5 - }) - reject() - return - } - - this.sqlverify(() => { resolve({uuid: card.uuid, setting, columns, scripts }) }, reject, false) - } - }) - } - - sqlverify = (resolve, reject, change = false, testScripts) => { - const { searches } = this.props - const { columns, setting, scripts } = this.state - - let _scripts = scripts.filter(item => item.status !== 'false') - - if (testScripts) { - _scripts = testScripts.filter(item => item.status !== 'false') - } - if (!change && setting.interType === 'system' && setting.execute === 'false' && _scripts.length === 0) { - notification.warning({ - top: 92, - message: '涓嶆墽琛岄粯璁ql鏃讹紝璇锋坊鍔犺嚜瀹氫箟鑴氭湰锛�', - duration: 5 - }) - reject() - return - } - - if ((setting.interType === 'system' && setting.execute !== 'false') || _scripts.length > 0) { - let param = { - func: 's_debug_sql', - exec_type: 'y', - LText: SettingUtils.getDebugSql(setting, _scripts, columns, searches) - } - param.LText = Utils.formatOptions(param.LText) - param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') - param.secretkey = Utils.encrypt('', param.timestamp) - - Api.getLocalConfig(param).then(result => { - if (result.status) { - resolve() - } else { - reject() - Modal.error({ - title: result.message - }) - } - }) - } else { - resolve() - } - } - - /** - * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊 - */ - componentWillUnmount () { - this.setState = () => { - return - } - } - - render() { - const { columns, setting, scripts, colColumns, scriptsColumns, activeKey, loading } = this.state - - return ( - <div id="mob-verify-card-box-tab"> - {loading && <Spin size="large" />} - <Tabs activeKey={activeKey} className="verify-card-box" onChange={this.changeTab}> - <TabPane tab="鏁版嵁婧�" key="setting"> - <SettingForm - menuId={this.props.menuId} - dict={this.props.dict} - columns={columns} - setting={setting} - scripts={scripts} - wrappedComponentRef={(inst) => this.settingForm = inst} - /> - </TabPane> - <TabPane tab="瀛楁闆�" key="columns"> - <ColForm - dict={this.props.dict} - columnChange={this.columnChange} - wrappedComponentRef={(inst) => this.contrastForm = inst} - /> - <Table - bordered - rowKey="uuid" - className="custom-table" - dataSource={columns} - columns={colColumns} - pagination={false} - /> - </TabPane> - <TabPane tab="鑷畾涔夎剼鏈�" key="scripts"> - <CustomScriptsForm - setting={setting} - searches={this.props.searches} - initsql={this.state.initsql} - dict={this.props.dict} - customScripts={scripts} - systemScripts={this.state.systemScripts} - scriptsChange={this.scriptsChange} - scriptSubmit={this.scriptSubmit} - wrappedComponentRef={(inst) => this.scriptsForm = inst} - /> - <Table - bordered - rowKey="uuid" - className="custom-table" - dataSource={scripts} - columns={scriptsColumns} - pagination={false} - /> - </TabPane> - </Tabs> - </div> - ) - } -} - -export default Form.create()(VerifyCard) \ No newline at end of file diff --git a/src/mob/datasource/verifycard/index.scss b/src/mob/datasource/verifycard/index.scss deleted file mode 100644 index 6a7c5e3..0000000 --- a/src/mob/datasource/verifycard/index.scss +++ /dev/null @@ -1,74 +0,0 @@ -#mob-verify-card-box-tab { - .ant-spin { - position: absolute; - left: calc(50% - 16px); - top: 220px; - z-index: 1; - } - .verify-card-box { - .ant-tabs-nav-scroll { - text-align: center; - } - .ant-tabs-content { - min-height: 40vh; - } - table tr td { - word-wrap: break-word; - word-break: break-word; - } - .verify-form { - .ant-input-number { - width: 100%; - } - .sql { - .ant-col-sm-8 { - width: 10.5%; - } - .ant-col-sm-16 { - width: 89.5%; - padding-top: 4px; - } - } - .sqlfield { - .ant-form-item { - margin-bottom: 5px; - } - .ant-form-item-control { - line-height: 24px; - } - .ant-form-item-label { - line-height: 25px; - } - .ant-form-item-children { - line-height: 22px; - } - .ant-col-sm-8 { - width: 10.5%; - } - .ant-col-sm-16 { - width: 89.5%; - } - } - .add { - padding-top: 4px; - } - .anticon-question-circle { - color: #c49f47; - margin-right: 3px; - } - } - .custom-table .ant-empty { - margin: 20px 8px!important; - } - .errorval { - display: inline-block; - width: 30px; - } - .operation-btn { - display: inline-block; - font-size: 16px; - padding: 0 5px; - cursor: pointer; - } - } -} \ No newline at end of file diff --git a/src/mob/datasource/verifycard/settingform/index.jsx b/src/mob/datasource/verifycard/settingform/index.jsx deleted file mode 100644 index 41c3e3f..0000000 --- a/src/mob/datasource/verifycard/settingform/index.jsx +++ /dev/null @@ -1,334 +0,0 @@ -import React, {Component} from 'react' -import PropTypes from 'prop-types' -// import { fromJS } from 'immutable' -import { Form, Row, Col, Input, Radio, Select, Tooltip, Icon, notification } from 'antd' -import moment from 'moment' - -import Api from '@/api' -import Utils from '@/utils/utils.js' -// import SettingUtils from './utils.jsx' -import CodeMirror from '@/templates/zshare/codemirror' -import './index.scss' - -class SettingForm extends Component { - static propTpyes = { - dict: PropTypes.object, // 瀛楀吀椤� - menuId: PropTypes.string, // 鑿滃崟Id - setting: PropTypes.object, // 鏁版嵁婧愰厤缃� - columns: PropTypes.array, // 鍒楄缃� - scripts: PropTypes.array, // 鑷畾涔夎剼鏈� - } - - state = { - interType: this.props.setting.interType || 'system', - structure: this.props.setting.structure || 'array' - } - - handleConfirm = (otype) => { - const { setting } = this.props - // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭� - return new Promise((resolve, reject) => { - this.props.form.validateFieldsAndScroll((err, values) => { - if (!err) { - // 鏁版嵁婧愬墠绔獙璇� - if (values.interType === 'inner' && !values.innerFunc && values.execute !== 'false' && !values.dataresource) { - notification.warning({ - top: 92, - message: '璇峰~鍐欏唴閮ㄥ嚱鏁版垨鏁版嵁婧愶紒', - duration: 5 - }) - reject() - return - } else if (values.interType === 'inner' && !values.innerFunc && values.execute !== 'false' && values.dataresource) { - let _quot = values.dataresource.match(/'{1}/g) - let _lparen = values.dataresource.match(/\({1}/g) - let _rparen = values.dataresource.match(/\){1}/g) - - _quot = _quot ? _quot.length : 0 - _lparen = _lparen ? _lparen.length : 0 - _rparen = _rparen ? _rparen.length : 0 - - if (_quot % 2 !== 0) { - notification.warning({ - top: 92, - message: '鏁版嵁婧愪腑\'蹇呴』鎴愬鍑虹幇', - duration: 5 - }) - reject() - return - } else if (_lparen !== _rparen) { - notification.warning({ - top: 92, - message: '鏁版嵁婧愪腑()蹇呴』鎴愬鍑虹幇', - duration: 5 - }) - reject() - return - } else if (/--/ig.test(values.dataresource)) { - notification.warning({ - top: 92, - message: '鏁版嵁婧愪腑锛屼笉鍙嚭鐜板瓧绗� -- 锛屾敞閲婅鐢� /*鍐呭*/', - duration: 5 - }) - reject() - return - } - - let error = Utils.verifySql(values.dataresource) - - if (error) { - notification.warning({ - top: 92, - message: '鏁版嵁婧愪腑涓嶅彲浣跨敤' + error, - duration: 5 - }) - reject() - return - } - } - - // 鏁版嵁婧愪繚瀛� - if ( - values.interType === 'inner' && !values.innerFunc && values.execute !== 'false' && - /[^\s]+\s+[^\s]+/ig.test(values.dataresource) && setting.dataresource !== values.dataresource - ) { - let param = { - func: 's_DataSrc_Save', - LText: values.dataresource, - MenuID: this.props.menuId - } - - param.LText = Utils.formatOptions(param.LText) - param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') - param.secretkey = Utils.encrypt(param.LText, param.timestamp) - - Api.getLocalConfig(param) - } - - resolve(values) - } else { - reject(err) - } - }) - }) - } - - onRadioChange = (e, key) => { - let value = e.target.value - - if (key === 'interType') { - this.setState({ - interType: value - }) - } else if (key === 'structure') { - this.setState({ - structure: value - }) - } - } - - render() { - const { columns, setting } = this.props - const { getFieldDecorator } = this.props.form - const { interType, structure } = this.state - - const formItemLayout = { - labelCol: { - xs: { span: 24 }, - sm: { span: 8 } - }, - wrapperCol: { - xs: { span: 24 }, - sm: { span: 16 } - } - } - - return ( - <div className="mob-datasource-setting-form-box"> - <Form {...formItemLayout} className="mob-setting-form"> - <Row gutter={24}> - <Col span={8}> - <Form.Item label="鍚嶇О"> - {getFieldDecorator('name', { - initialValue: setting.name, - rules: [ - { - required: true, - message: this.props.dict['mob.required.input'] + '鍚嶇О!' - }, - ] - })(<Input placeholder={''} autoComplete="off" />)} - </Form.Item> - </Col> - <Col span={8}> - <Form.Item label="琛ㄥ悕"> - {getFieldDecorator('tableName', { - initialValue: setting.tableName, - rules: [ - { - required: true, - message: this.props.dict['mob.required.input'] + '琛ㄥ悕!' - }, - ] - })(<Input placeholder={''} autoComplete="off" />)} - </Form.Item> - </Col> - <Col span={8}> - <Form.Item label="鏁版嵁缁撴瀯"> - {getFieldDecorator('structure', { - initialValue: structure, - rules: [ - { - required: true, - message: this.props.dict['mob.required.select'] + '琛ㄥ悕!' - }, - ] - })( - <Radio.Group onChange={(e) => {this.onRadioChange(e, 'structure')}}> - <Radio value="array">鏁扮粍</Radio> - <Radio value="field">瀛楁</Radio> - </Radio.Group>)} - </Form.Item> - </Col> - <Col span={8}> - <Form.Item label="鎺ュ彛绫诲瀷"> - {getFieldDecorator('interType', { - initialValue: interType, - rules: [ - { - required: true, - message: this.props.dict['mob.required.select'] + '鎺ュ彛绫诲瀷!' - }, - ] - })( - <Radio.Group onChange={(e) => {this.onRadioChange(e, 'interType')}}> - <Radio value="inner">鍐呴儴</Radio> - <Radio value="outer">澶栭儴</Radio> - </Radio.Group>)} - </Form.Item> - </Col> - {interType === 'inner' ? <Col span={8}> - <Form.Item label="鍐呴儴鍑芥暟"> - {getFieldDecorator('innerFunc', { - initialValue: setting.innerFunc || '', - rules: [ - - ] - })(<Input placeholder={''} autoComplete="off" />)} - </Form.Item> - </Col> : null} - {interType === 'outer' ? <Col span={8}> - <Form.Item label="鎺ュ彛鍦板潃"> - {getFieldDecorator('interface', { - initialValue: setting.interface || '', - rules: [ - { - required: true, - message: this.props.dict['mob.required.input'] + '鎺ュ彛鍦板潃!' - }, - ] - })(<Input placeholder={''} autoComplete="off" />)} - </Form.Item> - </Col> : null} - {interType === 'outer' ? <Col span={8}> - <Form.Item label="澶栭儴鍑芥暟"> - {getFieldDecorator('outerFunc', { - initialValue: setting.outerFunc || '', - rules: [ - - ] - })(<Input placeholder={''} autoComplete="off" />)} - </Form.Item> - </Col> : null} - {interType === 'inner' ? <Col span={24} className="data-source" style={{paddingLeft: '7px'}}> - <Form.Item labelCol={{xs: { span: 24 }, sm: { span: 2 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 22 }} } label={ - <Tooltip placement="topLeft" title={'浣跨敤绯荤粺鍑芥暟鏃讹紝闇�濉啓鏁版嵁婧愩�傛敞锛氭暟鎹潈闄愭浛鎹㈢ $@ -> /* 鎴� \'\'銆� @$ -> */ 鎴� \'\''}> - <Icon type="question-circle" /> - 鏁版嵁婧� - </Tooltip> - }> - {getFieldDecorator('dataresource', { - initialValue: setting.dataresource || '' - })(<CodeMirror />)} - </Form.Item> - </Col> : null} - {interType === 'inner' ? <Col span={8}> - <Form.Item label={ - <Tooltip placement="topLeft" title={'鏌ヨ鏃讹紝鎼滅储鏉′欢浠here鏉′欢鎷兼帴杩涘叆sql锛岀粺璁℃椂锛屽皢鏁版嵁婧愪腑浠モ�淍+鎼滅储瀛楁+@鈥濈殑鍐呭锛屼互鎼滅储鏉′欢涓殑鍊艰繘琛屾浛鎹㈠悗锛屾彁浜ゆ煡璇紝娉細鏌ヨ绫诲瀷浠呭湪浣跨敤绯荤粺鍑芥暟鏃舵湁鏁堛��'}> - <Icon type="question-circle" /> - 鏌ヨ绫诲瀷 - </Tooltip> - }> - {getFieldDecorator('queryType', { - initialValue: setting.queryType || 'query' - })( - <Radio.Group> - <Radio value="query">鏌ヨ</Radio> - <Radio value="statistics">缁熻</Radio> - </Radio.Group>)} - </Form.Item> - </Col> : null} - {structure === 'array' ? <Col span={8}> - <Form.Item label="涓婚敭"> - {getFieldDecorator('primaryKey', { - initialValue: setting.primaryKey || '' - })( - <Select onChange={(value) => {this.selectChange('primaryKey', value)}}> - {columns.map((option, i) => - <Select.Option key={i} value={option.value}> - {option.text} - </Select.Option> - )} - </Select> - )} - </Form.Item> - </Col> : null} - {structure === 'array' ? <Col span={8}> - <Form.Item label="榛樿鎺掑簭"> - {getFieldDecorator('order', { - initialValue: setting.order || 'ID asc' - })(<Input placeholder={'ID asc, UID desc'} autoComplete="off" />)} - </Form.Item> - </Col> : null} - {structure === 'array' ? <Col span={8}> - <Form.Item label="鍒嗛〉"> - {getFieldDecorator('laypage', { - initialValue: setting.laypage || 'true' - })( - <Radio.Group> - <Radio value="true">鏄�</Radio> - <Radio value="false">鍚�</Radio> - </Radio.Group>)} - </Form.Item> - </Col> : null} - - {interType === 'inner' ? <Col span={8}> - <Form.Item label="榛樿sql"> - {getFieldDecorator('execute', { - initialValue: setting.execute || 'true' - })( - <Radio.Group> - <Radio value="true">鎵ц</Radio> - <Radio value="false">涓嶆墽琛�</Radio> - </Radio.Group>)} - </Form.Item> - </Col> : null} - <Col span={8}> - <Form.Item label="鎼滅储鏉′欢"> - {getFieldDecorator('search', { - initialValue: setting.search || 'true' - })( - <Radio.Group> - <Radio value="true">鎺ユ敹</Radio> - <Radio value="false">涓嶆帴鏀�</Radio> - </Radio.Group>)} - </Form.Item> - </Col> - </Row> - </Form> - </div> - ) - } -} - -export default Form.create()(SettingForm) \ No newline at end of file diff --git a/src/mob/datasource/verifycard/settingform/index.scss b/src/mob/datasource/verifycard/settingform/index.scss deleted file mode 100644 index f9bc3f3..0000000 --- a/src/mob/datasource/verifycard/settingform/index.scss +++ /dev/null @@ -1,22 +0,0 @@ -.mob-datasource-setting-form-box { - position: relative; - - .mob-setting-form { - .data-source { - .ant-form-item-label { - width: 11%; - } - .ant-form-item-control-wrapper { - width: 89%; - } - .CodeMirror { - height: 150px; - } - } - .anticon-question-circle { - color: #c49f47; - margin-right: 3px; - } - } - -} \ No newline at end of file diff --git a/src/mob/datasource/verifycard/settingform/utils.jsx b/src/mob/datasource/verifycard/settingform/utils.jsx deleted file mode 100644 index a1e29d0..0000000 --- a/src/mob/datasource/verifycard/settingform/utils.jsx +++ /dev/null @@ -1,84 +0,0 @@ - -export default class SettingUtils { - /** - * @description 鐢熸垚椤甸潰鏌ヨ璇彞 - * @return {String} arr_field 鏄剧ず鍒楀瓧娈� - * @return {String} search 鎼滅储鏉′欢 - * @return {Object} setting 椤甸潰璁剧疆 - * @return {Array} regoptions 鎼滅储鏉′欢姝e垯鏇挎崲 - */ - static getDebugSql (setting, arr_field, regoptions, search) { - let sql = '' - let _dataresource = setting.dataresource - let _customScript = setting.customScript - - if (setting.interType === 'system' && setting.default === 'false') { - _dataresource = '' - } - - if (_dataresource) { - _dataresource = _dataresource.replace(/@\$|\$@/ig, '') - } - if (_customScript) { - _customScript = _customScript.replace(/@\$|\$@/ig, '') - } - - // 姝e垯鏇挎崲 - let _regoptions = regoptions.map(item => { - return { - reg: new RegExp('@' + item.key + '@', 'ig'), - value: `'${item.value}'` - } - }) - let _search = search - - if (setting.queryType === 'statistics' && _dataresource) { - _regoptions.forEach(item => { - _dataresource = _dataresource.replace(item.reg, item.value) - }) - - _search = '' - } - - if (_customScript) { - _regoptions.push({ - reg: new RegExp('@orderBy@', 'ig'), - value: setting.order - }) - if (setting.laypage !== 'false') { - _regoptions.push({ - reg: new RegExp('@pageSize@', 'ig'), - value: 10 - }, { - reg: new RegExp('@pageIndex@', 'ig'), - value: 1 - }) - } - _regoptions.forEach(item => { - _customScript = _customScript.replace(item.reg, item.value) - }) - } - - // 鏁版嵁婧愬鐞�, 瀛樺湪鏄剧ず鍒楁椂 - if (arr_field && _dataresource) { - if (/\s/.test(_dataresource)) { - _dataresource = '(' + _dataresource + ') tb' - } - - _dataresource = `select ${setting.laypage !== 'false' ? 'top 10' : ''} ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${setting.order}) as rows from ${_dataresource} ${_search}) tmptable ${setting.laypage !== 'false' ? 'where rows > 0' : ''} order by tmptable.rows` - } - - if (_customScript) { - sql = `${_customScript} - ${_dataresource} - aaa: - if @ErrorCode!='' - insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg,@UserID@ - ` - } else { - sql = _dataresource - } - - return sql - } -} \ No newline at end of file diff --git a/src/mob/datasource/verifycard/utils.jsx b/src/mob/datasource/verifycard/utils.jsx deleted file mode 100644 index 8a3cf2e..0000000 --- a/src/mob/datasource/verifycard/utils.jsx +++ /dev/null @@ -1,99 +0,0 @@ - -export default class SettingUtils { - /** - * @description 鐢熸垚椤甸潰鏌ヨ璇彞 - * @return {String} scripts 鑷畾涔夎剼鏈� - * @return {String} searches 鎼滅储鏉′欢 - * @return {Object} setting 椤甸潰璁剧疆 - * @return {Array} columns 鏄剧ず瀛楁 - */ - static getDebugSql (setting, scripts, columns, searches) { - let sql = '' - let _dataresource = '' - let _customScript = '' - let arr_field = columns.map(item => item.field).join(',') - - if (scripts.length > 0) { - scripts.forEach(item => { - _customScript += ` - ${item.sql} - ` - }) - } - - if (_customScript) { - _customScript = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg ='' - ${_customScript} - ` - } - - if (setting.interType === 'system' && setting.execute !== 'false') { - _dataresource = setting.dataresource - } - - if (_dataresource) { - _dataresource = _dataresource.replace(/@\$|\$@/ig, '') - } - if (_customScript) { - _customScript = _customScript.replace(/@\$|\$@/ig, '') - } - - // 姝e垯鏇挎崲 - let _regoptions = searches.map(item => { - return { - reg: new RegExp('@' + item.key + '@', 'ig'), - value: `'${item.value}'` - } - }) - let _search = '' - - if (setting.queryType === 'statistics' && _dataresource) { - _regoptions.forEach(item => { - _dataresource = _dataresource.replace(item.reg, item.value) - }) - - _search = '' - } - - if (_customScript) { - _regoptions.push({ - reg: new RegExp('@orderBy@', 'ig'), - value: setting.order - }) - if (setting.laypage !== 'false') { - _regoptions.push({ - reg: new RegExp('@pageSize@', 'ig'), - value: 10 - }, { - reg: new RegExp('@pageIndex@', 'ig'), - value: 1 - }) - } - _regoptions.forEach(item => { - _customScript = _customScript.replace(item.reg, item.value) - }) - } - - // 鏁版嵁婧愬鐞�, 瀛樺湪鏄剧ず鍒楁椂 - if (arr_field && _dataresource) { - if (/\s/.test(_dataresource)) { - _dataresource = '(' + _dataresource + ') tb' - } - - _dataresource = `select ${setting.laypage !== 'false' ? 'top 10' : ''} ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${setting.order}) as rows from ${_dataresource} ${_search}) tmptable ${setting.laypage !== 'false' ? 'where rows > 0' : ''} order by tmptable.rows` - } - - if (_customScript) { - sql = `${_customScript} - ${_dataresource} - aaa: - if @ErrorCode!='' - insert into tmp_err_retmsg (ID, ErrorCode, retmsg, CreateUserID) select @time_id@,@ErrorCode, @retmsg,@UserID@ - ` - } else { - sql = _dataresource - } - - return sql - } -} \ No newline at end of file diff --git a/src/mob/mobcard/index.jsx b/src/mob/mobcard/index.jsx deleted file mode 100644 index 6b732c9..0000000 --- a/src/mob/mobcard/index.jsx +++ /dev/null @@ -1,222 +0,0 @@ -import React, {Component} from 'react' -import { is, fromJS } from 'immutable' -import PropTypes from 'prop-types' -import { Card, Spin, Icon, Row, Col, Modal, notification } from 'antd' - -import Api from '@/api' -import Utils from '@/utils/utils.js' -import zhCN from '@/locales/zh-CN/mob.js' -import enUS from '@/locales/en-US/mob.js' -import asyncComponent from '@/utils/asyncSpinComponent' -import './index.scss' - -const { confirm } = Modal -const MutilForm = asyncComponent(() => import('./mutilform')) - -class CardChart extends Component { - static propTpyes = { - jumpMenu: PropTypes.func // 椤甸潰璺宠浆 - } - - state = { - dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, - loading: true, - visible: false, - confirmloading: false, - data: [], - card: null - } - - shouldComponentUpdate (nextProps, nextState) { - return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) - } - - UNSAFE_componentWillMount() { - this.getMobCards() - } - - getMobCards = () => { - let param = { - func: 's_get_kei' - } - - Api.getCloudConfig(param).then(result => { - if (result.status) { - this.setState({ - loading: false, - data: result.data.map(item => { - return { - uuid: item.ID, - keiNo: item.kei_no, - name: item.remark, - type: item.typename - } - }) - }) - - } else { - this.setState({ - loading: false - }) - notification.warning({ - top: 92, - message: result.message, - duration: 5 - }) - } - }) - } - - editCard = (card) => { - this.setState({ - card: card || null, - visible: true - }) - } - - deleteCard = (card) => { - let _this = this - - confirm({ - title: '纭畾鍒犻櫎銆�' + card.name + '銆嬪悧锛�', - content: '', - onOk() { - return new Promise(resolve => { - let param = { - func: 's_kei_del', - ID: card.uuid, - kei_no: card.keiNo - } - - Api.getCloudConfig(param).then(result => { - if (result.status) { - notification.success({ - top: 92, - message: '鍒犻櫎鎴愬姛锛�', - duration: 5 - }) - - _this.getMobCards() - } else { - notification.warning({ - top: 92, - message: result.message, - duration: 5 - }) - } - resolve() - }) - }) - }, - onCancel() {} - }) - } - - submitCard = () => { - const { card } = this.state - - this.mobcardRef.handleConfirm().then(res => { - this.setState({ - confirmloading: true - }) - - let param = { - func: 's_kei_addupt', - ID: card ? card.uuid : Utils.getuuid(), - TypeName: res.type, - remark: res.name, - kei_no: res.keiNo - } - - Api.getCloudConfig(param).then(result => { - if (result.status) { - notification.success({ - top: 92, - message: card ? '淇敼鎴愬姛锛�' : '娣诲姞鎴愬姛锛�', - duration: 5 - }) - - this.setState({ - confirmloading: false, - visible: false, - loading: true - }) - this.getMobCards() - } else { - this.setState({ - confirmloading: false - }) - notification.warning({ - top: 92, - message: result.message, - duration: 5 - }) - } - }, () => { - this.setState({ - confirmloading: false - }) - }) - }) - } - - render() { - const { data, loading, card, dict } = this.state - - return ( - <div className="mob-card-row-box"> - {loading ? - <div className="loading-mask"> - <div className="ant-spin-blur"></div> - <Spin /> - </div> : null - } - <Row gutter={24}> - {data && data.length > 0 && - data.map(item => ( - <Col key={item.uuid} span={6}> - <Card - size="small" - className="chart-card" - actions={[ - <Icon title="edit" onClick={() => this.editCard(item)} type="edit" />, - <Icon title="delete" onClick={() => this.deleteCard(item)} type="close" />, - <Icon title="detail" onClick={() => this.props.jumpMenu(item)} type="arrow-right" /> - ]} - > - <div className="mk-mob-card-title"> - {item.name} - </div> - <div className="mk-mob-card-type"> - {item.type === 'mob' ? '绉诲姩绔�' : 'PC绔�'} - </div> - </Card> - </Col> - )) - } - - <Col span={6} key="insert"> - <div className="chart-card insert" onClick={() => this.editCard()}> - <Icon type="plus" /> - </div> - </Col> - </Row> - <Modal - className="mob-card-modal" - title={card ? '缂栬緫搴旂敤' : '鏂板缓搴旂敤'} - width={'600px'} - maskClosable={false} - visible={this.state.visible} - onCancel={() => this.setState({visible: false})} - confirmLoading={this.state.confirmloading} - onOk={this.submitCard} - destroyOnClose - > - <MutilForm card={card} dict={dict} wrappedComponentRef={(inst) => this.mobcardRef = inst} inputSubmit={this.submitCard} /> - </Modal> - </div> - ) - } -} - -export default CardChart \ No newline at end of file diff --git a/src/mob/mobcard/index.scss b/src/mob/mobcard/index.scss deleted file mode 100644 index 54c55cc..0000000 --- a/src/mob/mobcard/index.scss +++ /dev/null @@ -1,64 +0,0 @@ -.mob-card-row-box { - padding: 40px 20px; - position: relative; - - .chart-card { - height: 250px; - border: 1px solid #e8e8e8; - .ant-card-body { - height: 201px; - .mk-mob-card-title { - margin-top: 40px; - font-size: 24px; - font-weight: 600; - text-align: center; - } - .mk-mob-card-type { - font-size: 14px; - color: rgba(0, 0 , 0, 0.55); - text-align: center; - } - } - - .ant-card-actions > li > span { - > .anticon-close:hover { - color: #ff4d4f; - } - > .anticon-arrow-right:hover { - color: rgb(38, 194, 129); - } - } - } - - .chart-card.insert { - text-align: center; - cursor: pointer; - - .anticon-plus { - color: rgb(38, 194, 129); - font-size: 100px; - line-height: 250px; - } - } - - .loading-mask { - position: absolute; - left: 20px; - top: 0; - right: 20px; - bottom: 0; - display: flex; - align-items: center; - justify-content: center; - text-align: justify; - z-index: 1; - - .ant-spin-blur { - position: absolute; - width: 100%; - height: 100%; - opacity: 0.5; - background: #ffffff; - } - } -} diff --git a/src/mob/mobcard/mutilform/index.jsx b/src/mob/mobcard/mutilform/index.jsx deleted file mode 100644 index 0ba42e2..0000000 --- a/src/mob/mobcard/mutilform/index.jsx +++ /dev/null @@ -1,123 +0,0 @@ -import React, {Component} from 'react' -import PropTypes from 'prop-types' -import { Form, Row, Col, Input, Select, Radio } from 'antd' -import './index.scss' - -class MainSearch extends Component { - static propTpyes = { - dict: PropTypes.object, // 瀛楀吀椤� - card: PropTypes.any, // 缂栬緫搴旂敤 - inputSubmit: PropTypes.func // input鍥炶溅鎻愪氦 - } - - state = {} - - /** - * @description 鑾峰彇琛ㄥ崟鍊� - */ - handleConfirm = () => { - return new Promise(resolve => { - this.props.form.validateFieldsAndScroll((err, values) => { - if (!err) { - resolve(values) - } - }) - }) - } - - /** - * @description 鍥炶溅鎻愪氦 - */ - handleSubmit = (e) => { - e.preventDefault() - this.props.inputSubmit() - } - - render() { - const { card } = this.props - const { getFieldDecorator } = this.props.form - const formItemLayout = { - labelCol: { - xs: { span: 24 }, - sm: { span: 8 } - }, - wrapperCol: { - xs: { span: 24 }, - sm: { span: 16 } - } - } - return ( - <Form {...formItemLayout} className="mob-card-edit-form"> - <Row gutter={24}> - <Col span={24}> - <Form.Item label="搴旂敤鍚�"> - {getFieldDecorator('name', { - initialValue: card ? card.name : '', - rules: [{ - required: true, - message: this.props.dict['mob.required.input'] + '搴旂敤鍚�!' - }, { - max: 20, - message: '搴旂敤鍚嶄笉鍙秴杩�20涓瓧绗�!' - }] - })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />)} - </Form.Item> - </Col> - <Col span={24}> - <Form.Item label="搴旂敤绫诲瀷"> - {getFieldDecorator('type', { - initialValue: card ? card.type : 'mob', - rules: [ - { - required: true, - message: this.props.dict['mob.required.select'] + '搴旂敤绫诲瀷!' - } - ] - })( - <Select> - <Select.Option value="mob">绉诲姩绔�</Select.Option> - <Select.Option value="pc">PC绔�</Select.Option> - </Select> - )} - </Form.Item> - </Col> - <Col span={24}> - <Form.Item label="搴旂敤缂栫爜"> - {getFieldDecorator('keiNo', { - initialValue: card ? card.keiNo : '', - rules: [{ - required: true, - message: this.props.dict['mob.required.input'] + '搴旂敤缂栫爜!' - }, { - pattern: /^[a-zA-Z_]*$/ig, - message: '搴旂敤缂栫爜鍙厑璁稿寘鍚ぇ灏忓啓瀛楁瘝鍙奯!' - }, { - max: 20, - message: '搴旂敤缂栫爜涓嶅彲瓒呰繃20涓瓧绗�!' - }] - })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit} />)} - </Form.Item> - </Col> - <Col span={24}> - <Form.Item label="鏉冮檺绠$悊"> - {getFieldDecorator('role_manage', { - initialValue: card ? card.role_manage || 'false' : 'false', - rules: [{ - required: true, - message: this.props.dict['mob.required.select'] + '鏄惁鍚敤鏉冮檺绠$悊!' - }] - })( - <Radio.Group> - <Radio value="true">鍚敤</Radio> - <Radio value="false">涓嶅惎鐢�</Radio> - </Radio.Group> - )} - </Form.Item> - </Col> - </Row> - </Form> - ) - } -} - -export default Form.create()(MainSearch) \ No newline at end of file diff --git a/src/mob/mobcard/mutilform/index.scss b/src/mob/mobcard/mutilform/index.scss deleted file mode 100644 index 28344fe..0000000 --- a/src/mob/mobcard/mutilform/index.scss +++ /dev/null @@ -1,4 +0,0 @@ -.mob-card-edit-form { - padding: 0px 24px 20px; - -} \ No newline at end of file diff --git a/src/mob/mobshell/card.jsx b/src/mob/mobshell/card.jsx index 5b7a510..30225a7 100644 --- a/src/mob/mobshell/card.jsx +++ b/src/mob/mobshell/card.jsx @@ -2,56 +2,86 @@ import { useDrag, useDrop } from 'react-dnd' import asyncComponent from '@/utils/asyncComponent' - import './index.scss' -// const Home = asyncComponent(() => import('@/mob/home')) -const MobLogin1 = asyncComponent(() => import('@/mob/components/login/mob-login-1')) -const MobLogin2 = asyncComponent(() => import('@/mob/components/login/mob-login-2')) +const AntvBar = asyncComponent(() => import('@/menu/components/chart/antv-bar')) +const MainSearch = asyncComponent(() => import('@/menu/components/search/main-search')) +const AntvPie = asyncComponent(() => import('@/menu/components/chart/antv-pie')) +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 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')) +const NormalTable = asyncComponent(() => import('@/menu/components/table/normal-table')) +const NormalForm = asyncComponent(() => import('@/menu/components/form/normal-form')) +const NormalGroup = asyncComponent(() => import('@/menu/components/group/normal-group')) +const CodeSandbox = asyncComponent(() => import('@/menu/components/code/sandbox')) -const Card = ({ id, card, moveCard, findCard, editId, editCard, delCard, doubleClickCard, updateConfig }) => { +const Card = ({ id, card, moveCard, findCard, delCard, updateConfig }) => { const originalIndex = findCard(id).index const [{ isDragging }, drag] = useDrag({ - item: { type: 'mob', id, originalIndex }, + item: { type: 'menu', id, originalIndex, floor: card.floor }, collect: monitor => ({ isDragging: monitor.isDragging(), }), }) const [, drop] = useDrop({ - accept: 'mob', + accept: 'menu', canDrop: () => true, drop: (item) => { - const { id: draggedId, originalIndex } = item - + const { id: draggedId, originalIndex, floor } = item if (originalIndex === undefined) { item.dropTargetId = id - } else if (draggedId && draggedId !== id) { + } else if (draggedId && floor === card.floor) { + if (draggedId === id) return + const { index: originIndex } = findCard(draggedId) + + if (originIndex === -1) return + const { index: overIndex } = findCard(id) + moveCard(draggedId, overIndex) } } }) let style = { opacity: 1} - if (isDragging && card.type !== 'login') { + if (isDragging) { style = { opacity: 0.3} - } - if (card.type === 'login') { - style.height = '100%' } const getCardComponent = () => { - if (card.type === 'login') { - if (card.subtype === 'mob-login-1') { - return (<MobLogin1 card={card} triggerEdit={editCard} editId={editId} onDoubleClick={doubleClickCard} updateConfig={updateConfig} />) - } else if (card.subtype === 'mob-login-2') { - return (<MobLogin2 card={card} triggerEdit={editCard} editId={editId} onDoubleClick={doubleClickCard} updateConfig={updateConfig} />) - } + if (card.type === 'bar' || card.type === 'line') { + return (<AntvBar card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'search') { + return (<MainSearch card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'pie') { + return (<AntvPie card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'form') { + return (<NormalForm card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'tabs') { + return (<AntvTabs tabs={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'card' && card.subtype === 'datacard') { + return (<DataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'card' && card.subtype === 'propcard') { + return (<PropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'carousel' && card.subtype === 'datacard') { + return (<CarouselDataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'carousel' && card.subtype === 'propcard') { + return (<CarouselPropCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'table' && card.subtype === 'tablecard') { + return (<TableCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'table' && card.subtype === 'normaltable') { + return (<NormalTable card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'group' && card.subtype === 'normalgroup') { + return (<NormalGroup group={card} updateConfig={updateConfig} deletecomponent={delCard}/>) + } else if (card.type === 'code') { + return (<CodeSandbox card={card} updateConfig={updateConfig} deletecomponent={delCard}/>) } } - return ( - <div className="mk-component-card" ref={node => drag(drop(node))} style={style}> + <div className={'ant-col mk-component-card ant-col-' + (card.width || 24)} ref={node => drag(drop(node))} style={style}> {getCardComponent()} </div> ) diff --git a/src/mob/mobshell/index.jsx b/src/mob/mobshell/index.jsx index 2dd4b00..ee23621 100644 --- a/src/mob/mobshell/index.jsx +++ b/src/mob/mobshell/index.jsx @@ -1,23 +1,23 @@ import React, { useState } from 'react' import { useDrop } from 'react-dnd' -import { is, fromJS } from 'immutable' import update from 'immutability-helper' -import { message, Empty } from 'antd' +import { Empty, notification, Modal } from 'antd' import Utils from '@/utils/utils.js' +import MKEmitter from '@/utils/events.js' +import MenuUtils from '@/utils/utils-custom.js' import Card from './card' import './index.scss' -const Container = ({config, editId, handleList, editCard, deleteCard, doubleClickCard }) => { - const [cards, setCards] = useState(config.components) +const { confirm } = Modal + +const Container = ({menu, handleList }) => { + const [cards, setCards] = useState(menu.components) const moveCard = (id, atIndex) => { const { card, index } = findCard(id) const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] }) - handleList({...config, components: _cards}) - } - - if (!is(fromJS(cards), fromJS(config.components))) { - setCards(config.components) + handleList({...menu, components: _cards}) + setCards(_cards) } const findCard = id => { @@ -29,27 +29,94 @@ } const updateConfig = (element) => { - handleList({...config, components: cards.map(item => item.uuid === element.uuid ? element : item)}) + const _cards = cards.map(item => item.uuid === element.uuid ? element : item) + handleList({...menu, components: _cards}) + setCards(_cards) + } + + const deleteCard = (id) => { + const { card } = findCard(id) + + let hasComponent = false + if (card.type === 'tabs') { + card.subtabs.forEach(tab => { + if (tab.components.length > 0) { + hasComponent = true + } + }) + } + + let uuids = MenuUtils.getDelButtonIds(card) + + confirm({ + title: `纭畾鍒犻櫎銆�${card.name}銆嬪悧锛焋, + content: hasComponent ? '褰撳墠缁勪欢涓惈鏈夊瓙缁勪欢锛�' : '', + onOk() { + MKEmitter.emit('delButtons', uuids) + const _cards = cards.filter(item => item.uuid !== card.uuid) + handleList({...menu, components: _cards}) + setCards(_cards) + }, + onCancel() {} + }) } const [, drop] = useDrop({ - accept: 'mob', + accept: 'menu', drop(item) { - if (item.hasOwnProperty('originalIndex')) { + if (item.hasOwnProperty('originalIndex') || item.added) { + delete item.added // 鍒犻櫎缁勪欢娣诲姞鏍囪 return } - if (cards.length > 0 && cards[0].type === 'login') { - message.warning('鐧诲綍椤典笉鍙坊鍔犲叾浠栧厓绱狅紒') - return + if (item.component === 'search') { // 鎼滅储缁勪欢涓嶅彲閲嶅娣诲姞 + if (cards.filter(card => card.type === 'search').length > 0) { + notification.warning({ + top: 92, + message: '鎼滅储鏉′欢涓嶅彲閲嶅娣诲姞锛�', + duration: 5 + }) + return + } + } + + let name = '' + let names = { + bar: '鏌辩姸鍥�', + line: '鎶樼嚎鍥�', + tabs: '鏍囩缁�', + pie: '楗煎浘', + search: '鎼滅储', + table: '琛ㄦ牸', + group: '鍒嗙粍', + editor: '瀵屾枃鏈�', + code: '鑷畾涔�', + carousel: '杞挱', + form: '琛ㄥ崟', + card: '鍗$墖' + } + let i = 1 + + while (!name && names[item.component]) { + let _name = names[item.component] + i + if (menu.components.filter(com => com.name === _name).length === 0) { + name = _name + } + i++ } let newcard = { uuid: Utils.getuuid(), - type: item.componentType, + type: item.component, subtype: item.subtype, + config: item.config, + width: item.width || 24, + dataName: Utils.getdataName(), + name: name, + floor: 1, // 缁勪欢鐨勫眰绾� + isNew: true // 鏂版坊鍔犳爣蹇楋紝鐢ㄤ簬鍒濆鍖� } - + let targetId = '' if (item.dropTargetId) { @@ -59,29 +126,29 @@ targetId = cards.slice(-1)[0].uuid } - const { index: overIndex } = findCard(`${targetId}`) // cards涓虹┖鏃� overIndex 涓� -1 + const { index: overIndex } = findCard(`${targetId}`) const _cards = update(cards, { $splice: [[overIndex + 1, 0, newcard]] }) - handleList({...config, components: _cards}) + handleList({...menu, components: _cards}) + setCards(_cards) } }) return ( - <div ref={drop} className="mob-shell-inner"> - {cards.map(card => ( - <Card - id={card.uuid} - key={card.uuid} - card={card} - editId={editId} - moveCard={moveCard} - editCard={editCard} - delCard={deleteCard} - findCard={findCard} - updateConfig={updateConfig} - doubleClickCard={doubleClickCard} - /> - ))} + <div ref={drop} className="mob-shell-inner" id="menu-shell-inner" style={menu.style}> + <div className="ant-row"> + {cards.map(card => ( + <Card + id={card.uuid} + key={card.uuid} + card={card} + moveCard={moveCard} + delCard={deleteCard} + findCard={findCard} + updateConfig={updateConfig} + /> + ))} + </div> {cards.length === 0 ? <Empty description="璇锋坊鍔犵粍浠�" /> : null } @@ -89,3 +156,4 @@ ) } export default Container + diff --git a/src/mob/modelsource/dragsource/index.jsx b/src/mob/modelsource/dragsource/index.jsx deleted file mode 100644 index 6ae90a6..0000000 --- a/src/mob/modelsource/dragsource/index.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react' -import { useDrag } from 'react-dnd' -import { Tooltip } from 'antd' -import './index.scss' - -const MobSourceElement = ({content}) => { - const [, drag] = useDrag({ item: content }) - return ( - <div ref={drag} className="mob-source-item" style={{backgroundImage: 'url(' + content.url + ')', ...content.style}}> - <Tooltip placement="right" overlayClassName="mob-source-tooltip-box" mouseEnterDelay={0.3} mouseLeaveDelay={0} title={ - <div><img style={{width: '100%'}} src={content.url} alt=""/></div> - }> - <div className="tooltip-block"></div> - </Tooltip> - </div> - ) -} -export default MobSourceElement \ No newline at end of file diff --git a/src/mob/modelsource/dragsource/index.scss b/src/mob/modelsource/dragsource/index.scss deleted file mode 100644 index 9884d46..0000000 --- a/src/mob/modelsource/dragsource/index.scss +++ /dev/null @@ -1,25 +0,0 @@ -.mob-source-item { - display: inline-block; - width: 130px; - margin-right: 15px; - cursor: move; - height: 130px; - box-shadow: 0px 0px 3px #cdcdcd; - - background-size: cover; - background-position: top center; - background-repeat: no-repeat; - - .tooltip-block { - width: 100%; - height: 100%; - background: transparent; - } -} - -.mob-source-tooltip-box { - margin-left: 20px; - .ant-tooltip-content { - width: 250px; - } -} \ No newline at end of file diff --git a/src/mob/modelsource/index.jsx b/src/mob/modelsource/index.jsx deleted file mode 100644 index 9adfe9c..0000000 --- a/src/mob/modelsource/index.jsx +++ /dev/null @@ -1,36 +0,0 @@ -import React, {Component} from 'react' -import { is, fromJS } from 'immutable' -import PropTypes from 'prop-types' - -import { mobOptions } from './option' -import SourceWrap from './dragsource' -import './index.scss' - -class CardChart extends Component { - static propTpyes = { - appType: PropTypes.string // 搴旂敤绫诲瀷 - } - - state = {} - - shouldComponentUpdate (nextProps, nextState) { - return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState)) - } - - render() { - const { appType } = this.props - - return ( - <div className="mob-card-source-box"> - {appType === 'mob' && mobOptions.map((item, index) => ( - <div key={index}> - <p>{item.title}</p> - {item.options.map((cell, i) => (<SourceWrap key={i} content={cell} />))} - </div> - ))} - </div> - ) - } -} - -export default CardChart \ No newline at end of file diff --git a/src/mob/modelsource/option.jsx b/src/mob/modelsource/option.jsx deleted file mode 100644 index 0123971..0000000 --- a/src/mob/modelsource/option.jsx +++ /dev/null @@ -1,16 +0,0 @@ -import zhCN from '@/locales/zh-CN/mob.js' -import enUS from '@/locales/en-US/mob.js' -import mobLogin1 from '@/assets/mobimg/mob-login1.png' -import mobLogin2 from '@/assets/mobimg/mob-login2.png' - -const _dict = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS - -// 缁勪欢閰嶇疆淇℃伅 -export const mobOptions = [{ - title: _dict['mob.login'], - sourceType: 'login', - options: [ - { subtype: 'mob-login-1', componentType: 'login', type: 'mob', url: mobLogin1, style: {} }, - { subtype: 'mob-login-2', componentType: 'login', type: 'mob', url: mobLogin2, style: {} }, - ] -}] diff --git a/src/mob/modulesource/dragsource/index.jsx b/src/mob/modulesource/dragsource/index.jsx new file mode 100644 index 0000000..0f13372 --- /dev/null +++ b/src/mob/modulesource/dragsource/index.jsx @@ -0,0 +1,15 @@ +import React from 'react' +import { useDrag } from 'react-dnd' +import { Icon } from 'antd' +import './index.scss' + +const MobSourceElement = ({item, triggerDel}) => { + const [, drag] = useDrag({ item }) + return ( + <div className="menu-source-item"> + <div className="property"><span>{item.title}</span>{item.config ? <Icon onClick={() => triggerDel(item)} type="close-circle" /> : null}</div> + <img ref={drag} src={item.url} alt=""/> + </div> + ) +} +export default MobSourceElement \ No newline at end of file diff --git a/src/mob/modulesource/dragsource/index.scss b/src/mob/modulesource/dragsource/index.scss new file mode 100644 index 0000000..ac891ba --- /dev/null +++ b/src/mob/modulesource/dragsource/index.scss @@ -0,0 +1,46 @@ +.menu-source-item { + display: inline-block; + width: 100%; + margin-bottom: 15px; + height: auto; + min-height: 70px; + + .property { + font-size: 14px; + color: rgba(0, 0, 0, 0.65); + margin-bottom: 2px; + + .anticon-close-circle { + opacity: 0; + cursor: pointer; + padding: 0 3px; + color: #ff4d4f; + transition: all 0.3s; + } + } + + img { + width: 100%; + cursor: move; + box-shadow: 0px 0px 1px #1890ff; + } + + .tooltip-block { + width: 100%; + height: 100%; + background: transparent; + } +} + +.menu-source-item:hover .property { + .anticon-close-circle { + opacity: 1; + } +} + +.menu-source-tooltip-box { + margin-left: 20px; + .ant-tooltip-content { + width: 250px; + } +} \ No newline at end of file diff --git a/src/mob/modulesource/index.jsx b/src/mob/modulesource/index.jsx new file mode 100644 index 0000000..f4705bf --- /dev/null +++ b/src/mob/modulesource/index.jsx @@ -0,0 +1,93 @@ +import React, {Component} from 'react' +import { is, fromJS } from 'immutable' +import { Modal, notification } from 'antd' + +import Api from '@/api' +import { menuOptions } from './option' +import SourceWrap from './dragsource' +import MKEmitter from '@/utils/events.js' +import './index.scss' + +const { confirm } = Modal + +class ModelSource extends Component { + state = { + menuOptions: null, + } + + UNSAFE_componentWillMount () { + const { components } = this.props + let options = [] + + if (components) { + options = fromJS(components).toJS() + } else { + options = fromJS(menuOptions).toJS() + } + + this.setState({ + menuOptions: options + }) + } + + UNSAFE_componentWillReceiveProps (nextProps) { + if (nextProps.components && !is(fromJS(this.props.components), fromJS(nextProps.components))) { + this.setState({ + menuOptions: fromJS(nextProps.components).toJS() + }) + } + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + triggerDel = (item) => { + confirm({ + title: `纭畾鍒犻櫎<${item.title}>鍚楋紵`, + content: '', + onOk() { + return new Promise(resolve => { + Api.getSystemConfig({ + func: 's_custom_components_adduptdel', + c_id: item.uuid, + images: '', + c_name: item.title, + long_param: '', + del_type: 'Y' + }).then(result => { + if (result.status) { + notification.success({ + top: 92, + message: '鍒犻櫎鎴愬姛锛�', + duration: 5 + }) + + MKEmitter.emit('updateCustomComponent') + } else { + notification.warning({ + top: 92, + message: result.message, + duration: 5 + }) + } + resolve() + }) + }) + }, + onCancel() {} + }) + } + + render() { + const { menuOptions } = this.state + + return ( + <div className="mob-card-source-box"> + {menuOptions.map((item, index) => (<SourceWrap key={index} item={item} triggerDel={this.triggerDel} />))} + </div> + ) + } +} + +export default ModelSource \ No newline at end of file diff --git a/src/mob/modelsource/index.scss b/src/mob/modulesource/index.scss similarity index 78% rename from src/mob/modelsource/index.scss rename to src/mob/modulesource/index.scss index db58054..cd91c8f 100644 --- a/src/mob/modelsource/index.scss +++ b/src/mob/modulesource/index.scss @@ -1,5 +1,5 @@ .mob-card-source-box { - padding: 20px 0px 20px 15px; + padding: 20px 0px; position: relative; p { diff --git a/src/mob/modulesource/option.jsx b/src/mob/modulesource/option.jsx new file mode 100644 index 0000000..7fa85b7 --- /dev/null +++ b/src/mob/modulesource/option.jsx @@ -0,0 +1,42 @@ +import bar from '@/assets/mobimg/bar.png' +import bar1 from '@/assets/mobimg/bar1.png' +import line from '@/assets/mobimg/line.png' +import line1 from '@/assets/mobimg/line1.png' +import tabs from '@/assets/mobimg/tabs.png' +import group from '@/assets/mobimg/group.png' +import card1 from '@/assets/mobimg/card1.png' +import card2 from '@/assets/mobimg/card2.png' +import TableCard from '@/assets/mobimg/table-card.png' +import NormalTable from '@/assets/mobimg/normal-table.png' +import Pie from '@/assets/mobimg/pie.png' +import SandBox from '@/assets/mobimg/sandbox.png' +import Pie1 from '@/assets/mobimg/ring.png' +import Pie2 from '@/assets/mobimg/nightingale.png' +import Mainsearch from '@/assets/mobimg/mainsearch.png' +import Navbar from '@/assets/mobimg/navbar-mob.png' +import Carousel from '@/assets/mobimg/carousel.png' +import Carousel1 from '@/assets/mobimg/carousel1.png' +import form from '@/assets/mobimg/form.png' + +// 缁勪欢閰嶇疆淇℃伅 +export const menuOptions = [ + { type: 'menu', url: Navbar, component: 'navbar', subtype: 'mobnavbar', title: '瀵艰埅鏍�', width: 1200 }, + { type: 'menu', url: tabs, component: 'tabs', subtype: 'tabs', title: '鏍囩椤�', width: 24 }, + { type: 'menu', url: Mainsearch, component: 'search', subtype: 'mainsearch', title: '鎼滅储鏉′欢', width: 24 }, + { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '鏁版嵁鍗�', width: 24 }, + { type: 'menu', url: card2, component: 'card', subtype: 'propcard', title: '灞炴�у崱', width: 24 }, + { type: 'menu', url: form, component: 'form', subtype: 'stepform', title: '琛ㄥ崟', width: 24 }, + { type: 'menu', url: Carousel, component: 'carousel', subtype: 'datacard', title: '杞挱-鍔ㄦ�佹暟鎹�', width: 24 }, + { type: 'menu', url: Carousel1, component: 'carousel', subtype: 'propcard', title: '杞挱-闈欐�佹暟鎹�', width: 24 }, + { 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: 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 }, + { type: 'menu', url: bar1, component: 'bar', subtype: 'bar1', title: '鏉″舰鍥�', width: 24 }, + { type: 'menu', url: Pie, component: 'pie', subtype: 'pie', title: '楗煎浘', width: 12 }, + { type: 'menu', url: Pie1, component: 'pie', subtype: 'ring', title: '鐜浘', width: 12 }, + { type: 'menu', url: SandBox, component: 'code', subtype: 'sandbox', title: '鑷畾涔�', width: 24 }, + { type: 'menu', url: Pie2, component: 'pie', subtype: 'nightingale', title: '鍗椾竵鏍煎皵鍥�', width: 12 }, + { type: 'menu', url: group, component: 'group', subtype: 'normalgroup', title: '鍒嗙粍', width: 24 }, +] diff --git a/src/pc/menushell/index.jsx b/src/pc/menushell/index.jsx index 7dac00b..29be748 100644 --- a/src/pc/menushell/index.jsx +++ b/src/pc/menushell/index.jsx @@ -1,6 +1,5 @@ import React, { useState } from 'react' import { useDrop } from 'react-dnd' -import { is, fromJS } from 'immutable' import update from 'immutability-helper' import { Empty, notification, Modal } from 'antd' @@ -18,10 +17,7 @@ const { card, index } = findCard(id) const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] }) handleList({...menu, components: _cards}) - } - - if (!is(fromJS(cards), fromJS(menu.components))) { - setCards(menu.components) + setCards(_cards) } const findCard = id => { @@ -33,7 +29,9 @@ } const updateConfig = (element) => { - handleList({...menu, components: cards.map(item => item.uuid === element.uuid ? element : item)}) + const _cards = cards.map(item => item.uuid === element.uuid ? element : item) + handleList({...menu, components: _cards}) + setCards(_cards) } const deleteCard = (id) => { @@ -55,7 +53,9 @@ content: hasComponent ? '褰撳墠缁勪欢涓惈鏈夊瓙缁勪欢锛�' : '', onOk() { MKEmitter.emit('delButtons', uuids) - handleList({...menu, components: cards.filter(item => item.uuid !== card.uuid)}) + const _cards = cards.filter(item => item.uuid !== card.uuid) + handleList({...menu, components: _cards}) + setCards(_cards) }, onCancel() {} }) @@ -139,6 +139,7 @@ const _cards = update(cards, { $splice: [[overIndex + 1, 0, newcard]] }) handleList({...menu, components: _cards}) + setCards(_cards) } }) diff --git a/src/tabviews/zshare/mutilform/index.jsx b/src/tabviews/zshare/mutilform/index.jsx index f25ea69..bd8f48f 100644 --- a/src/tabviews/zshare/mutilform/index.jsx +++ b/src/tabviews/zshare/mutilform/index.jsx @@ -76,6 +76,7 @@ formlist = formlist.map(item => { if (item.labelwidth) { item.labelCol = {style: {width: item.labelwidth + '%'}} + item.wrapperCol = {style: {width: (100 - item.labelwidth) + '%'}} } if (item.type === 'split' || item.type === 'hint') return item @@ -716,7 +717,13 @@ } else if (item.type === 'hint') { fields.push( <Col span={item.span || 24} key={index}> - <Form.Item colon={!!item.label} label={item.label || ' '} labelCol={item.labelCol} className="hint"> + <Form.Item + colon={!!item.label} + label={item.label || ' '} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + className="hint" + > <div className="message">{item.message}</div> </Form.Item> </Col> @@ -754,12 +761,17 @@ fields.push( <Col span={item.span || 24} key={index}> - <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ? - <Tooltip placement="topLeft" title={item.tooltip}> - <Icon type="question-circle" /> - {item.label} - </Tooltip> : item.label - }> + <Form.Item + extra={item.extra || null} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + label={item.tooltip ? + <Tooltip placement="topLeft" title={item.tooltip}> + <Icon type="question-circle" /> + {item.label} + </Tooltip> : item.label + } + > {getFieldDecorator(item.field, { initialValue: item.initval + '', rules: [ @@ -782,12 +794,17 @@ fields.push( <Col span={item.span || 24} key={index}> - <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ? - <Tooltip placement="topLeft" title={item.tooltip}> - <Icon type="question-circle" /> - {item.label} - </Tooltip> : item.label - }> + <Form.Item + extra={item.extra || null} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + label={item.tooltip ? + <Tooltip placement="topLeft" title={item.tooltip}> + <Icon type="question-circle" /> + {item.label} + </Tooltip> : item.label + } + > {getFieldDecorator(item.field, { initialValue: item.initval, rules: [ @@ -810,12 +827,17 @@ } else if (item.type === 'color') { // 棰滆壊閫夋嫨 fields.push( <Col span={item.span || 24} key={index}> - <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ? - <Tooltip placement="topLeft" title={item.tooltip}> - <Icon type="question-circle" /> - {item.label} - </Tooltip> : item.label - }> + <Form.Item + extra={item.extra || null} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + label={item.tooltip ? + <Tooltip placement="topLeft" title={item.tooltip}> + <Icon type="question-circle" /> + {item.label} + </Tooltip> : item.label + } + > {getFieldDecorator(item.field, { initialValue: item.initval || 'transparent', rules: [ @@ -833,12 +855,18 @@ } else if (item.type === 'checkcard') { // 澶氶�夋 fields.push( <Col span={item.span || 24} key={index}> - <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ? - <Tooltip placement="topLeft" title={item.tooltip}> - <Icon type="question-circle" /> - {item.label} - </Tooltip> : item.label - } className="checkcard"> + <Form.Item + className="checkcard" + extra={item.extra || null} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + label={item.tooltip ? + <Tooltip placement="topLeft" title={item.tooltip}> + <Icon type="question-circle" /> + {item.label} + </Tooltip> : item.label + } + > {getFieldDecorator(item.field, { initialValue: item.initval, rules: [ @@ -854,12 +882,17 @@ } else if (item.type === 'switch') { // 澶氶�夋 fields.push( <Col span={item.span || 24} key={index}> - <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ? - <Tooltip placement="topLeft" title={item.tooltip}> - <Icon type="question-circle" /> - {item.label} - </Tooltip> : item.label - }> + <Form.Item + extra={item.extra || null} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + label={item.tooltip ? + <Tooltip placement="topLeft" title={item.tooltip}> + <Icon type="question-circle" /> + {item.label} + </Tooltip> : item.label + } + > {getFieldDecorator(item.field, { initialValue: item.initval, rules: [ @@ -877,12 +910,17 @@ fields.push( <Col span={item.span || 24} key={index}> - <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ? - <Tooltip placement="topLeft" title={item.tooltip}> - <Icon type="question-circle" /> - {item.label} - </Tooltip> : item.label - }> + <Form.Item + extra={item.extra || null} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + label={item.tooltip ? + <Tooltip placement="topLeft" title={item.tooltip}> + <Icon type="question-circle" /> + {item.label} + </Tooltip> : item.label + } + > {getFieldDecorator(item.field, { initialValue: _initval, rules: [ @@ -902,12 +940,17 @@ } else if (item.type === 'radio') { // 鍗曢�夋 fields.push( <Col span={item.span || 24} key={index}> - <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ? - <Tooltip placement="topLeft" title={item.tooltip}> - <Icon type="question-circle" /> - {item.label} - </Tooltip> : item.label - }> + <Form.Item + extra={item.extra || null} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + label={item.tooltip ? + <Tooltip placement="topLeft" title={item.tooltip}> + <Icon type="question-circle" /> + {item.label} + </Tooltip> : item.label + } + > {getFieldDecorator(item.field, { initialValue: item.initval, rules: [ @@ -927,12 +970,17 @@ } else if (item.type === 'select' || item.type === 'link') { // 涓嬫媺鎼滅储 fields.push( <Col span={item.span || 24} key={index}> - <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ? - <Tooltip placement="topLeft" title={item.tooltip}> - <Icon type="question-circle" /> - {item.label} - </Tooltip> : item.label - }> + <Form.Item + extra={item.extra || null} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + label={item.tooltip ? + <Tooltip placement="topLeft" title={item.tooltip}> + <Icon type="question-circle" /> + {item.label} + </Tooltip> : item.label + } + > {getFieldDecorator(item.field, { initialValue: item.initval, rules: [ @@ -961,12 +1009,17 @@ let _initval = item.initval ? item.initval.split(',').filter(Boolean) : [] fields.push( <Col span={item.span || 24} key={index}> - <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ? - <Tooltip placement="topLeft" title={item.tooltip}> - <Icon type="question-circle" /> - {item.label} - </Tooltip> : item.label - }> + <Form.Item + extra={item.extra || null} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + label={item.tooltip ? + <Tooltip placement="topLeft" title={item.tooltip}> + <Icon type="question-circle" /> + {item.label} + </Tooltip> : item.label + } + > {getFieldDecorator(item.field, { initialValue: _initval, rules: [ @@ -993,12 +1046,17 @@ } else if (item.type === 'date') { // 鏃堕棿鎼滅储 fields.push( <Col span={item.span || 24} key={index}> - <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ? - <Tooltip placement="topLeft" title={item.tooltip}> - <Icon type="question-circle" /> - {item.label} - </Tooltip> : item.label - }> + <Form.Item + extra={item.extra || null} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + label={item.tooltip ? + <Tooltip placement="topLeft" title={item.tooltip}> + <Icon type="question-circle" /> + {item.label} + </Tooltip> : item.label + } + > {getFieldDecorator(item.field, { initialValue: item.initval, rules: [ @@ -1016,12 +1074,17 @@ } else if (item.type === 'datemonth') { fields.push( <Col span={item.span || 24} key={index}> - <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ? - <Tooltip placement="topLeft" title={item.tooltip}> - <Icon type="question-circle" /> - {item.label} - </Tooltip> : item.label - }> + <Form.Item + extra={item.extra || null} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + label={item.tooltip ? + <Tooltip placement="topLeft" title={item.tooltip}> + <Icon type="question-circle" /> + {item.label} + </Tooltip> : item.label + } + > {getFieldDecorator(item.field, { initialValue: item.initval, rules: [ @@ -1039,12 +1102,17 @@ } else if (item.type === 'datetime') { fields.push( <Col span={item.span || 24} key={index}> - <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ? - <Tooltip placement="topLeft" title={item.tooltip}> - <Icon type="question-circle" /> - {item.label} - </Tooltip> : item.label - }> + <Form.Item + extra={item.extra || null} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + label={item.tooltip ? + <Tooltip placement="topLeft" title={item.tooltip}> + <Icon type="question-circle" /> + {item.label} + </Tooltip> : item.label + } + > {getFieldDecorator(item.field, { initialValue: item.initval, rules: [ @@ -1081,12 +1149,17 @@ fields.push( <Col span={item.span || 24} key={index}> - <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ? - <Tooltip placement="topLeft" title={item.tooltip}> - <Icon type="question-circle" /> - {item.label} - </Tooltip> : item.label - }> + <Form.Item + extra={item.extra || null} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + label={item.tooltip ? + <Tooltip placement="topLeft" title={item.tooltip}> + <Icon type="question-circle" /> + {item.label} + </Tooltip> : item.label + } + > {getFieldDecorator(item.field, { initialValue: filelist, rules: [ @@ -1104,12 +1177,17 @@ } else if (item.type === 'linkMain') { fields.push( <Col span={item.span || 24} key={index}> - <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ? - <Tooltip placement="topLeft" title={item.tooltip}> - <Icon type="question-circle" /> - {item.label} - </Tooltip> : item.label - }> + <Form.Item + extra={item.extra || null} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + label={item.tooltip ? + <Tooltip placement="topLeft" title={item.tooltip}> + <Icon type="question-circle" /> + {item.label} + </Tooltip> : item.label + } + > {getFieldDecorator(item.field, { initialValue: item.initval, rules: [ @@ -1135,12 +1213,17 @@ } fields.push( <Col span={item.span || 24} key={index}> - <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.tooltip ? - <Tooltip placement="topLeft" title={item.tooltip}> - <Icon type="question-circle" /> - {item.label} - </Tooltip> : item.label - }> + <Form.Item + extra={item.extra || null} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + label={item.tooltip ? + <Tooltip placement="topLeft" title={item.tooltip}> + <Icon type="question-circle" /> + {item.label} + </Tooltip> : item.label + } + > {getFieldDecorator(item.field, { initialValue: item.initval, rules: [ @@ -1163,12 +1246,17 @@ fields.push( <Col span={item.span || 24} key={index}> - <Form.Item extra={item.extra || null} labelCol={item.labelCol} label={item.hidelabel !== 'true' && item.tooltip ? - <Tooltip placement="topLeft" title={item.tooltip}> - <Icon type="question-circle" /> - {item.label} - </Tooltip> : (item.hidelabel !== 'true' ? item.label : '') - }> + <Form.Item + extra={item.extra || null} + labelCol={item.labelCol} + wrapperCol={item.wrapperCol} + label={item.hidelabel !== 'true' && item.tooltip ? + <Tooltip placement="topLeft" title={item.tooltip}> + <Icon type="question-circle" /> + {item.label} + </Tooltip> : (item.hidelabel !== 'true' ? item.label : '') + } + > {getFieldDecorator(item.field, { initialValue: item.initval || '', rules: [ diff --git a/src/templates/sharecomponent/columncomponent/index.jsx b/src/templates/sharecomponent/columncomponent/index.jsx index c8061d3..a37af66 100644 --- a/src/templates/sharecomponent/columncomponent/index.jsx +++ b/src/templates/sharecomponent/columncomponent/index.jsx @@ -186,7 +186,7 @@ _columnlist = _columnlist.filter(item => !item.origin || item.uuid === res.uuid) // 鍘婚櫎鍒濆鍒� _columnlist = _columnlist.map(item => { if (item.uuid !== res.uuid && res.field && item.field) { - if (item.field === res.field) { + if (item.field.toLowerCase() === res.field.toLowerCase()) { fieldrepet = true } } diff --git a/src/views/mobdesign/index.jsx b/src/views/mobdesign/index.jsx index a126428..bd6570b 100644 --- a/src/views/mobdesign/index.jsx +++ b/src/views/mobdesign/index.jsx @@ -1,46 +1,130 @@ import React, { Component } from 'react' import { connect } from 'react-redux' import { DndProvider } from 'react-dnd' -import { fromJS } from 'immutable' +import { withRouter } from 'react-router' +import { is, fromJS } from 'immutable' import moment from 'moment' import HTML5Backend from 'react-dnd-html5-backend' -import { Icon, Tabs, notification, Modal } from 'antd' -// import html2canvas from 'html2canvas' +import { ConfigProvider, notification, Modal, Collapse, Switch, Button, message, Spin } from 'antd' import Api from '@/api' import Utils from '@/utils/utils.js' import zhCN from '@/locales/zh-CN/mob.js' import enUS from '@/locales/en-US/mob.js' +import antdEnUS from 'antd/es/locale/en_US' +import antdZhCN from 'antd/es/locale/zh_CN' +import MKEmitter from '@/utils/events.js' +import MenuUtils from '@/utils/utils-custom.js' import asyncComponent from '@/utils/asyncComponent' +import { modifyCustomMenu } from '@/store/action' import './index.scss' -const { TabPane } = Tabs +const { Panel } = Collapse const { confirm } = Modal const Header = asyncComponent(() => import('@/mob/header')) -const Controller = asyncComponent(() => import('@/mob/controller')) +const MenuForm = asyncComponent(() => import('./menuform')) const MobShell = asyncComponent(() => import('@/mob/mobshell')) -const SourceWrap = asyncComponent(() => import('@/mob/modelsource')) -const DataSource = asyncComponent(() => import('@/mob/datasource')) +const SourceWrap = asyncComponent(() => import('@/mob/modulesource')) +const BgController = asyncComponent(() => import('@/pc/bgcontroller')) +const SysInterface = asyncComponent(() => import('@/menu/sysinterface')) +const Quotecomponent = asyncComponent(() => import('@/pc/quotecomponent')) +const PasteController = asyncComponent(() => import('@/menu/pastecontroller')) +const StyleController = asyncComponent(() => import('@/menu/stylecontroller')) +const UrlFieldComponent = asyncComponent(() => import('@/menu/urlfieldcomponent')) +const PictureController = asyncComponent(() => import('@/menu/picturecontroller')) +const ModalController = asyncComponent(() => import('@/menu/modalconfig/controller')) +const StyleCombController = asyncComponent(() => import('@/menu/stylecombcontroller')) +const StyleCombControlButton = asyncComponent(() => import('@/menu/stylecombcontrolbutton')) +const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent')) -class Mobile extends Component { +sessionStorage.setItem('isEditState', 'true') +sessionStorage.setItem('editMenuType', 'menu') // 缂栬緫鑿滃崟绫诲瀷 +sessionStorage.setItem('appType', 'mob') // 搴旂敤绫诲瀷 +document.body.className = '' +window.GLOB.UserComponentMap = new Map() // 缂撳瓨鐢ㄦ埛鑷畾涔夌粍浠� +window.GLOB.CacheIndependent = new Map() +window.GLOB.urlFields = [] // url鍙橀噺 + +class MobDesign extends Component { state = { + localedict: sessionStorage.getItem('lang') !== 'en-US' ? antdZhCN : antdEnUS, dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, - appId: this.props.match.params.appId, - appType: this.props.match.params.appType, - appCode: this.props.match.params.appCode, - appName: this.props.match.params.appName, + loading: true, + MenuId: '', + MenuName: '', + MenuNo: '', + delButtons: [], + copyButtons: [], + thawButtons: [], + activeKey: 'basedata', + menuloading: false, oriConfig: null, - parentId: '', - openEdition: '', config: null, - pageIndex: 0, - editElem: null + visible: false, + customComponents: [], } UNSAFE_componentWillMount() { - this.getAppParam(this.props.match.params.appId) + if (this.props.memberLevel < 30) return + try { + let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param))) + + if (param.type === 'app') { + sessionStorage.setItem('appId', param.ID || '') + sessionStorage.setItem('lang', param.lang || 'zh-CN') + sessionStorage.setItem('kei_no', param.kei_no || '') + sessionStorage.setItem('link_type', param.link_type || 'true') + sessionStorage.setItem('role_type', param.role_type || 'true') + sessionStorage.setItem('login_types', param.login_types || 'true') + + this.setState({ + localedict: sessionStorage.getItem('lang') !== 'en-US' ? antdZhCN : antdEnUS, + dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS + }) + this.getAppMessage() + } else if (param.type === 'view') { + this.setState({ + MenuId: param.MenuID + }, () => { + this.getMenuParam(param) + }) + } + } catch { + notification.warning({ + top: 92, + message: '鑿滃崟淇℃伅瑙f瀽閿欒锛�', + duration: 5 + }) + } + } + + UNSAFE_componentWillReceiveProps(nextProps) { + if (this.props.match.params.param !== nextProps.match.params.param) { + window.location.reload() + } + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + componentDidMount () { + if (this.props.memberLevel < 30) { + document.getElementById('mk-mob-design-view').innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh; height: 100vh; background: #fff;">鏈簲鐢ㄦ病鏈塒C绔〉闈㈢殑缂栬緫鏉冮檺锛岃鑱旂郴绠$悊鍛橈紒</div>' + return + } + MKEmitter.addListener('delButtons', this.delButtons) + MKEmitter.addListener('thawButtons', this.thawButtons) + MKEmitter.addListener('copyButtons', this.copyButtons) + MKEmitter.addListener('changeEditMenu', this.changeEditMenu) + MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle) + MKEmitter.addListener('updateCustomComponent', this.updateCustomComponent) + setTimeout(() => { + this.updateCustomComponent() + this.getAppPictures() + }, 1000) } /** @@ -50,214 +134,1324 @@ this.setState = () => { return } + MKEmitter.removeListener('delButtons', this.delButtons) + MKEmitter.removeListener('thawButtons', this.thawButtons) + MKEmitter.removeListener('copyButtons', this.copyButtons) + MKEmitter.removeListener('changeEditMenu', this.changeEditMenu) + MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle) + MKEmitter.removeListener('updateCustomComponent', this.updateCustomComponent) } - triggerSave = () => { - const { config, openEdition, parentId } = this.state + changeEditMenu = (menu) => { + const { oriConfig, config } = this.state + + if (!oriConfig || !is(fromJS(oriConfig), fromJS(config))) { + notification.warning({ + top: 92, + message: '閰嶇疆淇℃伅鏈繚瀛橈紒', + duration: 5 + }) + return + } let param = { - func: 'sPC_TrdMenu_AddUpt', - ParentID: config.entrance ? '' : parentId, - MenuID: config.uuid, - MenuNo: config.MenuNo, - EasyCode: '', - Template: '', - MenuName: '', - PageParam: '', - LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(config))), - // LText: _vals.func.map(item => `select '${menu.MenuID}' as MenuID,'${item.func}' as ProcName,'${item.label}' as MenuName`), - // LTexttb: _tables.map(item => `select '${menu.MenuID}' as MenuID,'${item}' as tbName`), - TypeCharOne: 'mob' + MenuID: menu.MenuID, + copyMenuId: menu.copyMenuId || '', + type: 'view' } - let _LText = '' - // _LText = _LText.join(' union all ') - let _LTexttb = '' - // _LTexttb = _LTexttb.join(' union all ') - - param.LText = Utils.formatOptions(_LText) - param.LTexttb = Utils.formatOptions(_LTexttb) - param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') - param.secretkey = Utils.encrypt(param.LText, param.timestamp) - - if (openEdition) { // 鐗堟湰绠$悊 - param.open_edition = openEdition + if (menu.fixed && menu.MenuNo && menu.MenuName) { + param.fixed = true + param.MenuNo = menu.MenuNo + param.MenuName = menu.MenuName } - Api.getSystemConfig(param).then(response => { - if (response.status) { - this.setState({ - oriConfig: fromJS(config).toJS(), - openEdition: response.open_edition || '', - }) - } else { - notification.warning({ - top: 92, - message: response.message, - duration: 5 - }) - } - }) - + param = window.btoa(window.encodeURIComponent(JSON.stringify(param))) + + if (param === this.props.match.params.param) return + + this.props.history.push('/mobdesign/' + param) } - getAppParam = (id) => { + getAppMessage = () => { Api.getSystemConfig({ - func: 'sPC_Get_LongParam', - MenuID: id, - TypeCharOne: 'mob' - }).then(result => { - if (result.status) { - let config = null + func: 's_get_keyids', + bid: sessionStorage.getItem('appId') + }).then(res => { + if (!res.status) { + notification.warning({ + top: 92, + message: res.message, + duration: 5 + }) + return + } - if (result.LongParam) { - try { - config = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) - } catch (e) { - console.warn('Parse Failure') - config = null + let homeId = '' + let appViewList = [] + if (res.data && res.data.length > 0) { + appViewList = res.data + appViewList.forEach(item => { + if (item.keys_type === 'index') { + homeId = item.keys_id } + }) + } + + if (!homeId) { + homeId = Utils.getuuid() + + let param = { + func: 's_kei_link_keyids_addupt', + BID: sessionStorage.getItem('appId'), + exec_type: 'y', + LText: '' } - if (!config) { - config = { - version: 1.0, - entrance: true, - label: '', - uuid: this.props.match.params.appId, - pageIndex: 0, - MenuNo: this.props.match.params.appCode, - sourcelist: [], - components: [] + appViewList.unshift({ + appkey: window.GLOB.appkey || '', + bid: sessionStorage.getItem('appId') || '', + kei_no: sessionStorage.getItem('kei_no') || '', + keys_id: homeId, + keys_type: 'index', + remark: '棣栭〉' + }) + + param.LText = appViewList.map(item => `select '${item.keys_id}','${item.keys_type}','${item.kei_no}','${item.appkey}','${item.bid}','${sessionStorage.getItem('CloudUserID')}','${item.remark}'`) + param.LText = param.LText.join(' union all ') + param.LText = Utils.formatOptions(param.LText) + + param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + param.secretkey = Utils.encrypt('', param.timestamp) + + Api.getSystemConfig(param).then(result => { + if (!result.status) { + notification.warning({ + top: 92, + message: result.message, + duration: 5 + }) + } else { + sessionStorage.setItem('appViewList', JSON.stringify(appViewList)) + sessionStorage.setItem('appHomeId', homeId) + this.props.history.replace('/mobdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: homeId, type: 'view'})))) } - } - this.setState({ - oriConfig: config, - config: fromJS(config).toJS(), - openEdition: result.open_edition || '', }) } else { + sessionStorage.setItem('appViewList', JSON.stringify(appViewList)) + sessionStorage.setItem('appHomeId', homeId) + this.props.history.replace('/mobdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: homeId, type: 'view'})))) + } + }) + } + + getAppPictures = () => { + if (sessionStorage.getItem('app_videos') || sessionStorage.getItem('app_pictures')) return + + Api.getSystemConfig({ + func: 's_url_db_adduptdel', + PageIndex: 0, // 0 浠h〃鍏ㄩ儴 + PageSize: 0, // 0 浠h〃鍏ㄩ儴 + typecharone: 'image', + type: 'search' + }).then(res => { + if (res.status) { + sessionStorage.setItem('app_pictures', JSON.stringify(res.data || [])) + } + + Api.getSystemConfig({ + func: 's_url_db_adduptdel', + PageIndex: 0, // 0 浠h〃鍏ㄩ儴 + PageSize: 0, // 0 浠h〃鍏ㄩ儴 + typecharone: 'video', + type: 'search' + }).then(res => { + if (res.status) { + sessionStorage.setItem('app_videos', JSON.stringify(res.data || [])) + } + }) + }) + } + + updateCustomComponent = () => { + Api.getSystemConfig({ + func: 's_get_custom_components', + typecharone: '' + }).then(res => { + let coms = [] + if (res.cus_list && res.cus_list.length > 0) { + res.cus_list.forEach(item => { + let config = '' + + try { + config = JSON.parse(window.decodeURIComponent(window.atob(item.long_param))) + } catch (e) { + console.warn('Parse Failure') + config = '' + } + + if (!config || !item.c_name) return + + window.GLOB.UserComponentMap.set(item.c_id, item.c_name) + coms.push({ + uuid: item.c_id, + type: 'menu', + title: item.c_name, + url: item.images, + component: config.type, + subtype: config.subtype, + width: config.width || 24, + config + }) + }) + } + this.setState({customComponents: coms}) + this.getRoleFields() + }) + } + + updateComponentStyle = (parentId, keys, style) => { + const { config } = this.state + + if (config.uuid !== parentId) return + + let components = config.components.map(item => { + if (keys.includes(item.uuid)) { + item.style = {...item.style, ...style} + } + return item + }) + + this.setState({ + config: {...config, components: []} + }, () => { + this.setState({ + config: {...config, components: components} + }) + }) + } + + delButtons = (items) => { + const { copyButtons, delButtons } = this.state + + this.setState({ + delButtons: [...delButtons, ...items], + copyButtons: copyButtons.filter(item => !items.includes(item.uuid)) + }) + } + + copyButtons = (items) => { + this.setState({copyButtons: [...this.state.copyButtons, ...items]}) + } + + thawButtons = (item) => { + this.setState({thawButtons: [...this.state.thawButtons, item]}) + } + + closeView = () => { + const { oriConfig, config } = this.state + + if (!config) { + window.close() + return + } + + if (!oriConfig || !is(fromJS(oriConfig), fromJS(config))) { + confirm({ + title: '閰嶇疆淇℃伅鏈繚瀛橈紝纭畾鍏抽棴鍚楋紵', + content: '', + onOk() { + window.close() + }, + onCancel() {} + }) + } else { + window.close() + } + } + + getMenuParam = (urlParam) => { + const { MenuId } = this.state + + let param = { + func: 'sPC_Get_LongParam', + TypeCharOne: sessionStorage.getItem('kei_no'), + typename: 'mob', + MenuID: MenuId + } + + Api.getSystemConfig(param).then(result => { + if (!result.status) { notification.warning({ top: 92, message: result.message, duration: 5 }) + this.setState({loading: false}) + return + } else if (!result.LongParam && urlParam.copyMenuId) { + this.getCopyParam(urlParam) + } else { + let config = null + let isCreate = false + + try { + config = result.LongParam ? JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) : null + } catch (e) { + console.warn('Parse Failure') + config = null + } + + if (!config) { + isCreate = true + config = { + version: 1.0, + uuid: MenuId, + MenuID: MenuId, + Template: 'webPage', + enabled: false, + MenuName: '', + MenuNo: '', + tables: [], + components: [], + viewType: 'menu', + style: { + backgroundColor: '#ffffff', backgroundImage: '', paddingLeft: '20px', paddingRight: '20px' + } + } + } + + config.uuid = MenuId + config.MenuID = MenuId + config.open_edition = result.open_edition || '' + window.GLOB.urlFields = config.urlFields || [] + + if (urlParam.fixed) { + config.fixed = true + config.MenuName = urlParam.MenuName + config.MenuNo = urlParam.MenuNo + } + + let indeComs = [] + config.components.forEach(item => { + if (item.type === 'navbar') { + indeComs.push(fromJS(item).toJS()) + } + }) + + if (indeComs.length === 0) { + this.setState({ + oriConfig: isCreate ? null : config, + config: fromJS(config).toJS(), + loading: false + }) + + this.props.modifyCustomMenu(config) + } else { + this.jointComponents(config, indeComs, isCreate) + } + } + }) + this.getAppMenus() + } + + getAppMenus = () => { + let _param = { + func: 's_get_app_menus', + TypeCharOne: sessionStorage.getItem('kei_no'), + typename: 'mob', + LText: `select '${window.GLOB.appkey}'`, + timestamp: moment().format('YYYY-MM-DD HH:mm:ss') + } + + _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp) + + Api.getSystemConfig(_param).then(res => { + if (!res.status) { + notification.warning({ + top: 92, + message: res.message, + duration: 5 + }) + return + } + + let appIndeList = sessionStorage.getItem('appViewList') + appIndeList = JSON.parse(appIndeList) + appIndeList = appIndeList.map(item => (item.keys_type !== 'index' ? item.keys_id : '')).join(',') + + let menus = res.menus.filter(item => appIndeList.indexOf(item.MenuID) === -1) + sessionStorage.setItem('appMenus', JSON.stringify(menus)) + }) + } + + getCopyParam = (urlParam) => { + const { MenuId } = this.state + + let param = { + func: 'sPC_Get_LongParam', + TypeCharOne: sessionStorage.getItem('kei_no'), + typename: 'mob', + MenuID: urlParam.copyMenuId + } + + Api.getSystemConfig(param).then(result => { + if (!result.status) { + notification.warning({ + top: 92, + message: result.message, + duration: 5 + }) + this.setState({loading: false}) + return + } else if (!result.LongParam) { + notification.warning({ + top: 92, + message: '鏈煡璇㈠埌澶嶅埗鑿滃崟閰嶇疆淇℃伅锛�', + duration: 5 + }) + } + + let config = null + + try { + config = result.LongParam ? JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) : null + } catch (e) { + console.warn('Parse Failure') + config = null + } + + + if (!config) { + config = { + version: 1.0, + uuid: MenuId, + MenuID: MenuId, + Template: 'webPage', + enabled: false, + MenuName: '', + MenuNo: '', + tables: [], + components: [], + viewType: 'menu', + style: { + backgroundColor: '#ffffff', backgroundImage: '', paddingLeft: '20px', paddingRight: '20px' + } + } + } else { + config.components = MenuUtils.resetConfig(config.components) + message.success('澶嶅埗鎴愬姛锛屼繚瀛樺悗鐢熸晥銆�') + } + + config.uuid = MenuId + config.MenuID = MenuId + config.open_edition = '' + + let indeComs = [] + config.components.forEach(item => { + if (item.type === 'navbar') { + indeComs.push(fromJS(item).toJS()) + } + }) + + if (indeComs.length === 0) { + this.setState({ + oriConfig: null, + config: fromJS(config).toJS(), + loading: false + }) + + this.props.modifyCustomMenu(config) + } else { + this.jointComponents(config, indeComs, true) } }) } - deleteCard = (id) => { - let _this = this + jointComponents = (config, indeComs, isCreate) => { + let deffers = indeComs.map(item => { + return new Promise(resolve => { + Api.getSystemConfig({ + func: 'sPC_Get_LongParam', + TypeCharOne: sessionStorage.getItem('kei_no'), + typename: 'mob', + MenuID: item.uuid + }).then(res => { + res.uuid = item.uuid + + if (!res.status) { + notification.warning({ + top: 92, + message: res.message, + duration: 5 + }) + } + + resolve(res) + }) + }) + }) + Promise.all(deffers).then(result => { + let _conf = {} + result.forEach(res => { + let _config = null + try { + _config = res.LongParam ? JSON.parse(window.decodeURIComponent(window.atob(res.LongParam))) : null + } catch (e) { + console.warn('Parse Failure') + _config = null + } + + if (_config) { + _config.open_edition = res.open_edition || '' + _conf[res.uuid] = _config + window.GLOB.CacheIndependent.set(res.uuid, fromJS(_config).toJS()) + } + }) + + let _length = config.components.length + config.components = config.components.map(item => { + if (item.type === 'navbar') { + if (_conf[item.uuid]) { + item = _conf[item.uuid] + } else { + item = null + } + } + return item + }) + + config.components = config.components.filter(Boolean) + + if (_length > config.components.length) { + notification.warning({ + top: 92, + message: '閮ㄥ垎缁勪欢宸插垹闄わ紒', + duration: 5 + }) + } + + this.setState({ + oriConfig: isCreate ? null : fromJS(config).toJS(), + config: config, + loading: false + }) + + this.props.modifyCustomMenu(config) + }) + } + + getMenuMessage = () => { + const { config } = this.state + let buttons = [] + let _sort = 1 + + let traversal = (components) => { + components.forEach(item => { + if (item.type === 'tabs') { + item.subtabs.forEach(tab => { + traversal(tab.components) + }) + } else if (item.type === 'group') { + traversal(item.components) + } else if (item.type === 'card' || (item.type === 'table' && item.subtype === 'tablecard')) { + item.action && item.action.forEach(btn => { + this.checkBtn(btn) + buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) + _sort++ + }) + item.subcards.forEach(card => { + card.elements && card.elements.forEach(cell => { + if (cell.eleType !== 'button') return + this.checkBtn(cell) + buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`) + _sort++ + }) + card.backElements && card.backElements.forEach(cell => { + if (cell.eleType !== 'button') return + this.checkBtn(cell) + buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort`) + _sort++ + }) + }) + } else if (item.type === 'line' || item.type === 'bar') { + item.action && item.action.forEach(btn => { + this.checkBtn(btn) + buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) + _sort++ + }) + } else if (item.type === 'table' && item.subtype === 'normaltable') { + item.action && item.action.forEach(btn => { + this.checkBtn(btn) + buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) + _sort++ + }) + item.cols && item.cols.forEach(col => { + if (col.type !== 'action') return + col.elements.forEach(btn => { + this.checkBtn(btn) + buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort`) + _sort++ + }) + }) + } + }) + } + + traversal(config.components) + + return buttons + } + + checkBtn = (btn) => { + if (['prompt', 'exec', 'pop'].includes(btn.OpenType) && btn.Ot === 'required' && btn.verify && btn.verify.scripts && btn.verify.scripts.length > 0) { + let hascheck = false + btn.verify.scripts.forEach(item => { + if (item.status === 'false') return + + if (/\$check@|@check\$/ig.test(item.sql)) { + hascheck = true + } + }) + if (hascheck) { + notification.warning({ + top: 92, + message: `鍙�夋嫨澶氳鐨勬寜閽��${btn.label}銆嬩腑 $check@ 鎴� @check$ 灏嗕笉浼氱敓鏁堬紒`, + duration: 5 + }) + } + } + } + + filterConfig = (components) => { + return components.map(item => { + if (item.type === 'tabs') { + item.subtabs.forEach(tab => { + tab.components = this.filterConfig(tab.components) + }) + } else if (item.type === 'group') { + item.components = this.filterConfig(item.components) + } else if (item.type === 'table' && item.subtype === 'normaltable') { + item.search = item.search.filter(a => !a.origin) + item.action = item.action.filter(a => !a.origin) + item.cols = item.cols.filter(a => !a.origin) + } + return item + }) + } + + submitConfig = () => { + const { delButtons, copyButtons, thawButtons } = this.state let config = fromJS(this.state.config).toJS() - confirm({ - title: '纭畾鍒犻櫎鍏冪礌鍚楋紵', - content: '', - okText: this.state.dict['mob.confirm'], - cancelText: this.state.dict['mob.cancel'], - onOk() { - config.components = config.components.filter(item => item.uuid !== id) + if (!config.MenuName || !config.MenuNo || (config.cacheUseful === 'true' && !config.cacheTime)) { + notification.warning({ + top: 92, + message: '璇峰畬鍠勮彍鍗曞熀鏈俊鎭紒', + duration: 5 + }) + this.setState({ + activeKey: 'basedata' + }) + return + } - _this.setState({ - config: config + this.setState({ + menuloading: true + }) + + setTimeout(() => { + config.components = this.filterConfig(config.components) + + if (config.enabled && this.verifyConfig()) { + config.enabled = false + } + + let parMenuId = sessionStorage.getItem('kei_no') + 'pc' + sessionStorage.getItem('lang') + let param = { + func: 'sPC_TrdMenu_AddUpt', + FstID: parMenuId, + SndID: parMenuId, + ParentID: parMenuId, + MenuID: config.uuid, + MenuNo: config.MenuNo || '', + EasyCode: '', + Template: 'webPage', + TypeCharOne: sessionStorage.getItem('kei_no'), + Typename: 'pc', + MenuName: config.MenuName || '', + PageParam: JSON.stringify({Template: 'webPage'}), + open_edition: config.open_edition, + LText: '', + LTexttb: '' + } + + param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + param.secretkey = Utils.encrypt('', param.timestamp) + + let btnParam = { // 娣诲姞鑿滃崟鎸夐挳 + func: 'sPC_Button_AddUpt', + Type: 40, // 娣诲姞鑿滃崟涓嬬殑鎸夐挳type涓�40锛屾寜閽笅鐨勬寜閽畉ype涓�60 + ParentID: config.uuid, + MenuNo: config.MenuNo, + Template: 'webPage', + PageParam: '', + LongParam: '', + LText: [] + } + + btnParam.LText = this.getMenuMessage() + btnParam.LText = btnParam.LText.join(' union all ') + + let btnIds = btnParam.LText // 鐢ㄤ簬澶嶅埗鎸夐挳鐨勮繃婊� + + btnParam.LText = Utils.formatOptions(btnParam.LText) + btnParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + btnParam.secretkey = Utils.encrypt(btnParam.LText, btnParam.timestamp) + + new Promise(resolve => { + let _config = fromJS(config).toJS() + let indeComs = [] + _config.components = _config.components.map(item => { + if (item.type === 'navbar') { + indeComs.push(item) + return { + type: 'navbar', + uuid: item.uuid + } + } + return item + }) + + param.LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(_config))) + + if (indeComs.length === 0) { + resolve(true) + } else { + let new_open_edition = {} + let deffers = indeComs.map(item => { + return new Promise(resolve => { + let _item = window.GLOB.CacheIndependent.get(item.uuid) + if (_item && is(fromJS(_item), fromJS(item))) { + new_open_edition[item.uuid] = item.open_edition || '' + resolve() + return + } + + let _param = { + func: 'sPC_TrdMenu_AddUpt', + FstID: parMenuId, + SndID: parMenuId, + ParentID: parMenuId, + MenuID: item.uuid, + MenuNo: item.wrap.MenuNo || '', + EasyCode: '', + Template: item.type, + TypeCharOne: sessionStorage.getItem('kei_no'), + Typename: 'pc', + MenuName: item.name || '', + PageParam: JSON.stringify({Template: item.type}), + open_edition: item.open_edition || '', + LText: '', + LTexttb: '' + } + + _param.LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(item))) + _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + _param.secretkey = Utils.encrypt('', _param.timestamp) + + let appMenuParam = null + if (item.type === 'navbar') { + appMenuParam = { + func: 's_appmenus_addupt', + exec_type: 'y' + } + + appMenuParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + appMenuParam.secretkey = Utils.encrypt('', _param.timestamp) + + let LText = [] + let app_param = [] + let kei_no = sessionStorage.getItem('kei_no') + let userid = sessionStorage.getItem('CloudUserID') || '' + + item.menus.forEach((fst, findex) => { + // LText.push(`select '${fst.MenuID}','${fst.name}','','0','${sessionStorage.getItem('appId')}','0','${(findex + 1) * 10}','10','','${userid}','${window.GLOB.appkey}','${fst.MenuNo || ''}','${kei_no}','pc'`) + LText.push(`select '${fst.MenuID}','${fst.name}','','0','0','0','${(findex + 1) * 10}','10','','${userid}','${window.GLOB.appkey}','${fst.MenuNo || ''}','${kei_no}','pc'`) + app_param.push(`select '${window.GLOB.appkey}','${fst.MenuID}','${userid}','${(findex + 1) * 10}','','${fst.name}','${fst.MenuNo || ''}','0','10','${kei_no}','pc'`) + if (fst.property === 'classify' && fst.sublist.length > 0) { + fst.sublist.forEach(scd => { + LText.push(`select '${scd.MenuID}','${scd.name}','','0','${fst.MenuID}','0','${(findex + 1) * 10}','20','','${userid}','${window.GLOB.appkey}','${scd.MenuNo || ''}','${kei_no}','pc'`) + app_param.push(`select '${window.GLOB.appkey}','${scd.MenuID}','${userid}','${(findex + 1) * 10}','','${scd.name}','${scd.MenuNo || ''}','${fst.MenuID}','20','${kei_no}','pc'`) + + if (scd.property === 'classify' && scd.sublist.length > 0) { + scd.sublist.forEach(thd => { + LText.push(`select '${thd.MenuID}','${thd.name}','','0','${scd.MenuID}','0','${(findex + 1) * 10}','20','','${userid}','${window.GLOB.appkey}','${thd.MenuNo || ''}','${kei_no}','pc'`) + app_param.push(`select '${window.GLOB.appkey}','${thd.MenuID}','${userid}','${(findex + 1) * 10}','','${thd.name}','${thd.MenuNo || ''}','${scd.MenuID}','20','${kei_no}','pc'`) + }) + } + }) + } + }) + appMenuParam.LText = Utils.formatOptions(LText.join(' union ')) + appMenuParam.LText1 = Utils.formatOptions(app_param.join(' union ')) + } + + if (appMenuParam) { + Api.getSystemConfig(appMenuParam).then(_res => { + if (!_res.status) { + notification.warning({ + top: 92, + message: _res.message, + duration: 5 + }) + this.setState({ menuloading: false }) + return + } + + Api.getSystemConfig(_param).then(res => { + if (!res.status) { + notification.warning({ + top: 92, + message: res.message, + duration: 5 + }) + this.setState({ menuloading: false }) + return + } + + new_open_edition[item.uuid] = res.open_edition || '' + + resolve() + }) + }) + } else { + Api.getSystemConfig(_param).then(res => { + if (!res.status) { + notification.warning({ + top: 92, + message: res.message, + duration: 5 + }) + this.setState({ menuloading: false }) + return + } + + new_open_edition[item.uuid] = res.open_edition || '' + resolve() + }) + } + }) + }) + Promise.all(deffers).then(() => { + let appViewList = sessionStorage.getItem('appViewList') + appViewList = JSON.parse(appViewList) + let _length = appViewList.length + let appIndeList = appViewList.map(item => item.keys_id).join(',') + + + config.components = config.components.map(item => { + if (item.type === 'navbar') { + item.open_edition = new_open_edition[item.uuid] || '' + window.GLOB.CacheIndependent.set(item.uuid, fromJS(item).toJS()) + + if (appIndeList.indexOf(item.uuid) === -1) { + appViewList.unshift({ + appkey: window.GLOB.appkey || '', + bid: sessionStorage.getItem('appId') || '', + kei_no: sessionStorage.getItem('kei_no') || '', + keys_id: item.uuid, + keys_type: 'navbar', + remark: item.name + }) + } + } + return item + }) + + if (appViewList.length > _length) { + let param = { + func: 's_kei_link_keyids_addupt', + BID: sessionStorage.getItem('appId'), + exec_type: 'y', + LText: '' + } + + param.LText = appViewList.map(item => `select '${item.keys_id}','${item.keys_type}','${item.kei_no}','${item.appkey}','${item.bid}','${sessionStorage.getItem('CloudUserID')}','${item.remark}'`) + param.LText = param.LText.join(' union all ') + param.LText = Utils.formatOptions(param.LText) + + param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + param.secretkey = Utils.encrypt('', param.timestamp) + + Api.getSystemConfig(param).then(result => { + if (!result.status) { + notification.warning({ + top: 92, + message: result.message, + duration: 5 + }) + this.setState({ menuloading: false }) + } else { + sessionStorage.setItem('appViewList', JSON.stringify(appViewList)) + resolve(true) + } + }) + } else { + resolve(true) + } + }) + } + }).then(res => { // 鎸夐挳鎴栬彍鍗曞垹闄� + if (!res) return + + if (delButtons.length === 0) { + return { status: true, nonexec: true } + } else { + let appHomeId = sessionStorage.getItem('appHomeId') + let _param = { + func: 'sPC_MainMenu_Del', + MenuID: delButtons.filter(id => id !== appHomeId).join(',') + } + return Api.getSystemConfig(_param) + } + }).then(res => { // 鎸夐挳瑙i櫎鍐荤粨 + if (!res) return + if (!res.status) { + notification.warning({ + top: 92, + message: res.message, + duration: 5 + }) + return false + } else if (!res.nonexec) { // 鎵ц鍒犻櫎鍚庡埛鏂拌彍鍗曞垪琛� + this.getAppMenus() + } + + let ids = thawButtons.filter(item => btnIds.indexOf(item) !== -1) + if (ids.length === 0) { + return { status: true } + } else { + return Api.getSystemConfig({ + func: 'sPC_MainMenu_ReDel', + MenuID: ids.join(',') + }) + } + }).then(res => { // 椤甸潰淇濆瓨 + if (!res) return + + if (res.status) { + return Api.getSystemConfig(param) + } else { + notification.warning({ + top: 92, + message: res.message, + duration: 5 + }) + return false + } + }).then(res => { // 椤甸潰鎸夐挳鍏崇郴淇濆瓨 + if (!res) return + + if (res.status) { + config.open_edition = res.open_edition || '' + + this.setState({ + oriConfig: fromJS(config).toJS(), + }) + + if (btnParam.LText) { + return Api.getSystemConfig(btnParam) + } else { + return { + status: true + } + } + } else { + notification.warning({ + top: 92, + message: res.message, + duration: 5 + }) + return false + } + }).then(res => { // 鎸夐挳澶嶅埗 + if (!res) return + if (!res.status) { + notification.warning({ + top: 92, + message: res.message, + duration: 5 + }) + return false + } + + if (copyButtons.length === 0) { + return { + status: true + } + } else { + return new Promise(resolve => { + let deffers = copyButtons.map(item => { + return new Promise(resolve => { + if (btnIds.indexOf(item.uuid) === -1) { // 澶嶅埗鐨勬寜閽凡鍒犻櫎 + resolve({ + status: true + }) + return + } + + Api.getSystemConfig({ + func: 'sPC_Get_LongParam', + MenuID: item.$originUuid + }).then(result => { + if (result.status) { + let _conf = '' + + try { + _conf = result.LongParam ? JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) : '' + } catch (e) { + console.warn('Parse Failure') + _conf = '' + } + + if (_conf) { + _conf.components = MenuUtils.resetConfig(_conf.components) + _conf.uuid = item.uuid + _conf.MenuID = item.uuid + _conf.Template = 'webPage' + } else { + resolve({ + status: true + }) + return + } + + let _param = { + func: 'sPC_ButtonParam_AddUpt', + ParentID: config.uuid, + MenuID: item.uuid, + MenuNo: '', + Template: 'webPage', + MenuName: item.label, + PageParam: JSON.stringify({Template: 'webPage'}), + LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(_conf))) + } + + Api.getSystemConfig(_param).then(response => { + resolve(response) + }) + } + }) + }) + }) + Promise.all(deffers).then(result => { + let error = null + result.forEach(response => { + if (!response.status) { + error = response + } + }) + + if (error) { + notification.warning({ + top: 92, + message: error.message, + duration: 5 + }) + resolve(false) + } else { + resolve({ + status: true + }) + } + }) + }) + } + }).then(res => { + if (res && res.status) { + this.setState({ + delButtons: [], + copyButtons: [], + thawButtons: [], + menuloading: false, + config: {...config, components: []} + }, () => { + this.setState({ + config: {...this.state.config, components: this.state.oriConfig.components} + }) + }) + notification.success({ + top: 92, + message: '淇濆瓨鎴愬姛', + duration: 2 + }) + } else { + this.setState({ + menuloading: false + }) + } + }) + }, 300) + } + + getRoleFields = () => { + if (sessionStorage.getItem('sysRoles') || sessionStorage.getItem('permFuncField')) return + Api.getSystemConfig({func: 'sPC_Get_Roles_sModular'}).then(res => { + if (res.status) { + let _permFuncField = [] + let _sysRoles = [] + + if (res.Roles && res.Roles.length > 0) { + _sysRoles = res.Roles.map(role => { + return { + uuid: Utils.getuuid(), + value: role.RoleID, + text: role.RoleName + } + }) + } + + if (res.sModular && res.sModular.length > 0) { + res.sModular.forEach(field => { + if (field.ModularNo) { + _permFuncField.push(field.ModularNo) + } + }) + _permFuncField = _permFuncField.sort() + } + + sessionStorage.setItem('sysRoles', JSON.stringify(_sysRoles)) + sessionStorage.setItem('permFuncField', JSON.stringify(_permFuncField)) + } + }) + } + + onEnabledChange = () => { + const { config } = this.state + + if (!config || (!config.enabled && this.verifyConfig(true))) { + return + } + + this.setState({ + config: {...config, enabled: !config.enabled} + }) + } + + verifyConfig = (show) => { + const { config } = this.state + let error = '' + + config.components.forEach(item => { + if (error) return + if (['propcard', 'brafteditor', 'sandbox'].includes(item.subtype) && item.wrap.datatype === 'static') return + + if (item.setting) { + if (item.setting.interType === 'system' && item.setting.execute !== 'false' && !item.setting.dataresource) { + error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆鏁版嵁婧愶紒` + } else if (item.setting.interType === 'system' && item.setting.execute === 'false' && item.scripts.length === 0) { + error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆鏁版嵁婧愶紒` + } else if (item.setting.interType && !item.setting.primaryKey) { + error = `缁勪欢銆�${item.name}銆嬫湭璁剧疆涓婚敭锛乣 + } + } + if (item.type === 'bar' || item.type === 'line' || item.type === 'pie') { + if (!item.plot.Xaxis) { + error = `缁勪欢銆�${item.name}銆嬪浘琛ㄥ瓧娈靛皻鏈缃紒` + } + } + }) + + if (show && error) { + notification.warning({ + top: 92, + message: error, + duration: 5 + }) + } + + return error + } + + // 鏇存柊閰嶇疆淇℃伅 + updateConfig = (config) => { + this.setState({ + config: config + }) + + this.props.modifyCustomMenu(config) + } + + insert = (item) => { + let config = fromJS(this.state.config).toJS() + + config.components.push(item) + + this.setState({config}) + this.props.modifyCustomMenu(config) + } + + refreshView = () => { + const { oriConfig, config } = this.state + + if (!oriConfig || !is(fromJS(oriConfig), fromJS(config))) { + notification.warning({ + top: 92, + message: '閰嶇疆淇℃伅鏈繚瀛橈紒', + duration: 5 + }) + return + } + + // Api.getSystemConfig({ + // func: 'sPC_MainMenu_Del', + // MenuID: '1614740497468ku800sbg853vupf65v4' + // }) + + sessionStorage.removeItem('sysRoles') + sessionStorage.removeItem('permFuncField') + sessionStorage.removeItem('app_videos') + sessionStorage.removeItem('app_pictures') + + window.location.reload() + } + + setHomeView = () => { + const { oriConfig, config } = this.state + + if (!oriConfig || !is(fromJS(oriConfig), fromJS(config))) { + notification.warning({ + top: 92, + message: '閰嶇疆淇℃伅鏈繚瀛橈紒', + duration: 5 + }) + return + } + + let param = { + func: 's_kei_link_keyids_addupt', + BID: sessionStorage.getItem('appId'), + exec_type: 'y', + LText: '' + } + + let appViewList = sessionStorage.getItem('appViewList') + appViewList = appViewList ? JSON.parse(appViewList) : [] + appViewList = appViewList.filter(item => item.keys_type !== 'index') + + appViewList.unshift({ + appkey: window.GLOB.appkey || '', + bid: sessionStorage.getItem('appId') || '', + kei_no: sessionStorage.getItem('kei_no') || '', + keys_id: config.MenuID, + keys_type: 'index', + remark: config.MenuName + }) + + param.LText = appViewList.map(item => `select '${item.keys_id}','${item.keys_type}','${item.kei_no}','${item.appkey}','${item.bid}','${sessionStorage.getItem('CloudUserID')}','${item.remark}'`) + param.LText = param.LText.join(' union all ') + param.LText = Utils.formatOptions(param.LText) + + param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + param.secretkey = Utils.encrypt('', param.timestamp) + + confirm({ + title: '纭畾璁剧疆鏈〉闈负棣栭〉鍚楋紵', + content: '', + onOk() { + Api.getSystemConfig(param).then(result => { + if (!result.status) { + notification.warning({ + top: 92, + message: result.message, + duration: 5 + }) + } else { + sessionStorage.setItem('appHomeId', config.MenuID) + sessionStorage.setItem('appViewList', JSON.stringify(appViewList)) + } }) }, onCancel() {} }) } - editCard = (element) => { - this.setState({ - editElem: element - }) - } - - updateStyle = (proper) => { - const { config } = this.state - - config.components = config.components.map(component => { - if (component.uuid === proper.componentId) { - Object.keys(component).forEach(key => { - let _uuid = component[key].uuid - if (_uuid && (_uuid === proper.uuid || _uuid === proper.classId)) { - if (component[key].substyle) { - - } else { - component[key].style = {...component[key].style, ...proper.style} - // eslint-disable-next-line - for (let index in component[key].style) { - if (component[key].style[index] === '') { - delete component[key].style[index] - } - } - } - } - }) - } - return component - }) - this.setState({config}) - } - - updateConfig = (config) => { - this.setState({ - config: config - }) - } - render () { - const { appType, config, editElem } = this.state + const { localedict, loading, activeKey, dict, MenuId, config, menuloading, customComponents } = this.state return ( - <div className="mobile-view"> - <Header /> - <DndProvider backend={HTML5Backend}> - <div className="mob-body"> - <div className="mob-tool"> - <div className="mob-tool-content"> - <div className="plus-content"> - <Icon type="plus-circle" />娣� 鍔� 缁� 浠� - </div> - <div className="useable-component"> - <SourceWrap appType={appType} /> - </div> + <ConfigProvider locale={localedict}> + <div className="mk-mob-view" id="mk-mob-design-view"> + <Header /> + {loading ? <Spin className="view-spin" size="large" /> : null} + <DndProvider backend={HTML5Backend}> + <div className="menu-setting"> + <div className="pc-setting-tools"> + <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}> + {/* 鍩烘湰淇℃伅 */} + <Panel header={dict['mob.basemsg']} key="basedata"> + {/* 鑿滃崟淇℃伅 */} + {config ? <MenuForm + dict={dict} + config={config} + MenuId={MenuId} + updateConfig={this.updateConfig} + /> : null} + {config ? <UrlFieldComponent config={config} updateConfig={this.updateConfig}/> : null} + {/* 琛ㄥ悕娣诲姞 */} + {config ? <TableComponent config={config} updatetable={this.updateConfig}/> : null} + </Panel> + {/* 缁勪欢娣诲姞 */} + <Panel header={dict['mob.component']} key="component"> + <SourceWrap /> + </Panel> + {customComponents && customComponents.length ? <Panel header="鑷畾涔夌粍浠�" key="cuscomponent"> + <SourceWrap components={customComponents} /> + </Panel> : null} + <Panel header={'椤甸潰鏍峰紡'} key="background"> + {config ? <BgController config={config} updateConfig={this.updateConfig} /> : null} + </Panel> + </Collapse> </div> - <div className="mob-tool-other"></div> </div> - {appType === 'mob' && config ? + <div className="menu-control"> + <Button type="primary" onClick={this.submitConfig} loading={menuloading}>{dict['mob.save']}</Button> + <Switch className="big" checkedChildren={dict['mob.enable']} unCheckedChildren={dict['mob.disable']} checked={config && config.enabled} onChange={this.onEnabledChange} /> + <PasteController type="menu" Tab={null} insert={this.insert} /> + <StyleCombControlButton menu={config} /> + <SysInterface config={config} updateConfig={this.updateConfig}/> + <PictureController/> + <Quotecomponent config={config} updateConfig={this.updateConfig}/> + <Button className="mk-border-green" icon="home" onClick={this.setHomeView}>璁句负棣栭〉</Button> + <Button className="mk-border-danger" icon="redo" onClick={this.refreshView}>寮哄埗鍒锋柊</Button> + <Button type="default" onClick={this.closeView}>{dict['mob.return']}</Button> + </div> + <div className={'menu-body' + (menuloading ? 'saving' : '')}> <div className="mob-shell"> - <MobShell - config={config} - deleteCard={this.deleteCard} - editCard={this.editCard} - editId={editElem ? editElem.uuid : ''} - handleList={this.updateConfig} - /> - </div> : null - } - <div className="mob-setting"> - {config ? <Tabs defaultActiveKey="1" animated={false} size="small"> - <TabPane tab="閰嶇疆" key="1"> - <Controller editElem={editElem} updateStyle={this.updateStyle} /> - </TabPane> - <TabPane tab="鏁版嵁婧�" key="2"> - <DataSource config={config} updateConfig={this.updateConfig} /> - </TabPane> - </Tabs> : null} + {config ? <MobShell menu={config} handleList={this.updateConfig} /> : null} + </div> </div> - </div> - </DndProvider> - </div> + </DndProvider> + <StyleController /> + <StyleCombController /> + <ModalController /> + </div> + </ConfigProvider> ) } } -const mapStateToProps = () => { - return {} +const mapStateToProps = (state) => { + return { + memberLevel: state.memberLevel + } } -const mapDispatchToProps = () => { - return {} +const mapDispatchToProps = (dispatch) => { + return { + modifyCustomMenu: (customMenu) => dispatch(modifyCustomMenu(customMenu)) + } } -export default connect(mapStateToProps, mapDispatchToProps)(Mobile) \ No newline at end of file +export default withRouter(connect(mapStateToProps, mapDispatchToProps)(MobDesign)) \ No newline at end of file diff --git a/src/views/mobdesign/index.scss b/src/views/mobdesign/index.scss index 7251e22..7699f0b 100644 --- a/src/views/mobdesign/index.scss +++ b/src/views/mobdesign/index.scss @@ -1,78 +1,77 @@ -.mobile-view { - background: #000; +.mk-mob-view { min-height: 100vh; - .mob-body { - width: 100vw; - height: 100vh; - overflow-x: hidden; - position: relative; - background: #262626; - padding: 50px 300px 0px 40px; - .mob-tool { - position: fixed; - left: 0; - top: 48px; - height: 100%; - width: 40px; - background: #262626; - box-shadow: 2px 0px 2px #000; - .mob-tool-content { - width: 100%; - .plus-content { - position: relative; + >.view-spin { + position: absolute; + z-index: 3; + left: calc(50% - 16px); + top: calc(50vh - 70px); + } + .modal-form-board { + padding-top: 0; + } + .menu-setting { + position: fixed; + left: 0; + top: 48px; + z-index: 10; + transition: left 0.3s; + + .pc-setting-tools { + height: calc(100vh - 48px); + width: 300px; + background: #ffffff; + overflow-y: auto; + overflow-x: hidden; + + > .ant-collapse { + background-color: #ffffff; + .ant-collapse-item.ant-collapse-item-active { + border-bottom: 1px solid #d9d9d9; + } + .ant-collapse-header { + padding: 11px 16px 10px 40px; + border-bottom: 1px solid #d9d9d9; + background: #1890ff; color: #ffffff; - width: 100%; - display: flex; - align-items: center; - writing-mode: tb-rl; - padding: 16px 0; - border-bottom: 1px solid #000; - cursor: pointer; - z-index: 10; - background: #202735; - i { - margin-bottom: 5px; - margin-left: 2px; + } + .ant-collapse-content-box { + .ant-form-item { + margin-bottom: 10px; + } + .model-table-tablemanage-view { + >.ant-list { + margin-top: 20px; + .ant-list-item { + display: -webkit-box; + padding-right: 20px; + position: relative; + padding-left: 5px; + overflow: hidden; + text-overflow: ellipsis; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + min-height: 55px; + width: 100%; + .anticon { + position: absolute; + top: 0px; + right: 0px; + padding: 3px 3px 10px 10px; + cursor: pointer; + } + } + } + >.tables { + width: 66.66666667%!important; + } + >.ant-form-item-label { + width: 33.33333333%; + } } } - - .useable-component { - position: absolute; - width: 305px; - top: 0; - bottom: 0; - left: -340px; - background: #fff; - opacity: 0; - transition: left 0.3s linear 0.1s, opacity 0.3s linear 0.1s; - overflow-y: auto; - } } - .mob-tool-content:hover { - .useable-component { - opacity: 1; - left: 40px; - } - } - .mob-tool-other { - position: relative; - z-index: 10; - height: 1000px; - background: #202735; - } - } - - .mob-setting { - position: fixed; - right: 0; - top: 0; - z-index: 10; - height: 100%; - width: 300px; - background: #202735; - box-shadow: 0px 2px 2px #000; - + >.ant-tabs { >.ant-tabs-bar { border-bottom: 1px solid #181F29; @@ -88,62 +87,113 @@ } } } + .pc-setting-tools::-webkit-scrollbar { + width: 4px; + } + .pc-setting-tools::-webkit-scrollbar-thumb { + border-radius: 5px; + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.08); + background: rgba(0, 0, 0, 0.08); + } + .pc-setting-tools::-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); + } + } + .mob-shell { + width: 375px; + height: 680px; + margin: 0 auto; + background: #000000; + background-size: 100% 100%; + padding: 25px 13px 40px; + border-radius: 30px; - .mob-shell { - width: 375px; - height: 680px; - margin: 0 auto; + .mob-shell-inner { + width: 100%; + height: 100%; + overflow-y: auto; + overflow-x: hidden; background: #ffffff; - background-size: 100% 100%; - padding: 25px 13px 40px; - border-radius: 30px; + box-shadow: 0px 0px 2px #000000; + } + .mob-shell-inner::-webkit-scrollbar { + width: 2px; + } + .mob-shell-inner::-webkit-scrollbar-thumb { + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13); + background: rgba(0, 0, 0, 0.23); + border-radius: 5px; + } + .mob-shell-inner::-webkit-scrollbar-track { + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05); + border: 1px solid rgba(0, 0, 0, 0.07); + background: rgba(0, 0, 0, 0); + border-radius: 3px; + } + } + .menu-control { + position: fixed; + right: 0; + top: 48px; + height: 100vh; + padding: 20px 10px; + background: #ffffff; + z-index: 10; + transition: right 0.3s; - .mob-shell-inner { - width: 100%; - height: 100%; - overflow-y: auto; - overflow-x: hidden; - box-shadow: 0px 0px 2px #000000; + div:not(.draw), button:not(.ant-switch) { + display: block!important; + margin-bottom: 15px; + width: 100%; + } + .ant-switch.big { + min-width: 60px; + height: 24px; + line-height: 24px; + margin-bottom: 15px; + .ant-switch-inner { + font-size: 14px; } - .mob-shell-inner::-webkit-scrollbar { - width: 2px; - } - .mob-shell-inner::-webkit-scrollbar-thumb { - box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13); - background: rgba(0, 0, 0, 0.23); - border-radius: 5px; - } - .mob-shell-inner::-webkit-scrollbar-track { - box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05); - border: 1px solid rgba(0, 0, 0, 0.07); - background: rgba(0, 0, 0, 0); - border-radius: 3px; - } + } + .ant-switch.big:after { + width: 22px; + height: 22px; } } - .flex-container { - margin: 0 15px; + .menu-body { + width: 100vw; + height: 100vh; + overflow-x: hidden; + position: relative; + background: #959595; + padding: 50px 0px 0px; + overflow-y: auto; + .menu-shell-inner { + min-height: 100vh; + margin: 0 auto; + } } - .flex-container .inline { - width: 80px!important; - margin: 9px 9px 9px 0; + .menu-body.saving { + .anticon-tool { + display: none; + } } - .flex-container .small { - height: 20px!important; - line-height: 20px!important; + .menu-body::-webkit-scrollbar { + width: 7px; } - .sub-title { - color: #888; - font-size: 14px; - padding: 30px 0 18px 0; + .menu-body::-webkit-scrollbar-thumb { + border-radius: 5px; + box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.08); + background: rgba(0, 0, 0, 0.08); } - .placeholder { - background-color: #ebebef; - color: #bbb; - text-align: center; - height: 30px; - line-height: 30px; - width: 100%; + .menu-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); } -} +} \ No newline at end of file diff --git a/src/views/mobdesign/menuform/index.jsx b/src/views/mobdesign/menuform/index.jsx new file mode 100644 index 0000000..2335bcf --- /dev/null +++ b/src/views/mobdesign/menuform/index.jsx @@ -0,0 +1,138 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { Form, Row, Col, Input, Radio, Icon, Tooltip, InputNumber } from 'antd' + +import './index.scss' + +class CustomMenuForm extends Component { + static propTpyes = { + dict: PropTypes.object, // 瀛楀吀椤� + config: PropTypes.object, + MenuId: PropTypes.string, + updateConfig: PropTypes.func + } + + state = {} + + // 涓�浜岀骇鑿滃崟鍒囨崲 + selectChange = (key, value) => { + const { config } = this.props + + if (key === 'cacheUseful') { + this.props.updateConfig({...config, cacheUseful: value}) + } else if (key === 'timeUnit') { + this.props.updateConfig({...config, timeUnit: value}) + } + } + + // 鑿滃崟鍚嶇О + changeName = (e) => { + this.props.updateConfig({...this.props.config, MenuName: e.target.value}) + } + + // 鑿滃崟鍙傛暟 + changeNo = (e) => { + this.props.updateConfig({...this.props.config, MenuNo: e.target.value}) + } + + changeCacheDay = (val) => { + if (typeof(val) !== 'number') { + val = '' + } + this.props.updateConfig({...this.props.config, cacheTime: val}) + } + + render() { + const { dict, config } = this.props + const { getFieldDecorator } = this.props.form + const formItemLayout = { + labelCol: { + xs: { span: 24 }, + sm: { span: 8 } + }, + wrapperCol: { + xs: { span: 24 }, + sm: { span: 16 } + } + } + + return ( + <Form {...formItemLayout} className="custom-menu-form"> + <Row> + <Col span={24}> + <Form.Item label={dict['mob.menu'] + dict['mob.name']}> + {getFieldDecorator('MenuName', { + initialValue: config.MenuName, + rules: [ + { + required: true, + message: dict['mob.required.input'] + dict['mob.menu'] + dict['mob.name'] + '!' + } + ] + })(<Input placeholder="" disabled={!!(config.fixed && config.MenuName)} autoComplete="off" onChange={this.changeName}/>)} + </Form.Item> + </Col> + <Col span={24}> + <Form.Item label={dict['mob.menu'] + dict['mob.param']}> + {getFieldDecorator('MenuNo', { + initialValue: config.MenuNo, + rules: [ + { + required: true, + message: dict['mob.required.input'] + dict['mob.menu'] + dict['mob.param'] + '!' + } + ] + })(<Input placeholder="" disabled={!!(config.fixed && config.MenuName)} autoComplete="off" onChange={this.changeNo}/>)} + </Form.Item> + </Col> + <Col span={24}> + <Form.Item label={ + <Tooltip placement="topLeft" title="瀵逛簬涓嶇粡甯告�у彉鍔ㄧ殑淇℃伅锛岀紦瀛樻暟鎹湁鍔╀簬鎻愰珮鏌ヨ鏁堢巼銆�"> + <Icon type="question-circle" /> + 缂撳瓨鏁版嵁 + </Tooltip> + }> + {getFieldDecorator('cacheUseful', { + initialValue: config.cacheUseful || 'false' + })( + <Radio.Group onChange={(e) => {this.selectChange('cacheUseful', e.target.value)}}> + <Radio value="true">浣跨敤</Radio> + <Radio value="false">涓嶄娇鐢�</Radio> + </Radio.Group> + )} + </Form.Item> + </Col> + {config.cacheUseful === 'true' ? <Col span={24}> + <Form.Item label="鍗曚綅"> + {getFieldDecorator('timeUnit', { + initialValue: config.timeUnit || 'day' + })( + <Radio.Group onChange={(e) => {this.selectChange('timeUnit', e.target.value)}}> + <Radio value="day">澶�</Radio> + <Radio value="hour">灏忔椂</Radio> + </Radio.Group> + )} + </Form.Item> + </Col> : null} + {config.cacheUseful === 'true' ? <Col span={24}> + <Form.Item label="鏃堕暱"> + {getFieldDecorator('cacheTime', { + initialValue: config.cacheTime, + rules: [ + { + required: true, + message: dict['mob.required.input'] + '鏃堕暱!' + } + ] + })( + <InputNumber min={1} max={config.timeUnit !== 'hour' ? 7 : 23} precision={0} onChange={this.changeCacheDay}/> + )} + </Form.Item> + </Col> : null} + </Row> + </Form> + ) + } +} + +export default Form.create()(CustomMenuForm) \ No newline at end of file diff --git a/src/views/mobdesign/menuform/index.scss b/src/views/mobdesign/menuform/index.scss new file mode 100644 index 0000000..71a1a33 --- /dev/null +++ b/src/views/mobdesign/menuform/index.scss @@ -0,0 +1,10 @@ +.custom-menu-form { + .anticon-question-circle { + color: #c49f47; + position: relative; + left: -3px; + } + .ant-input-number { + width: 100%; + } +} \ No newline at end of file diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx index a6c55e8..c814a3f 100644 --- a/src/views/pcdesign/index.jsx +++ b/src/views/pcdesign/index.jsx @@ -31,6 +31,7 @@ const PasteController = asyncComponent(() => import('@/menu/pastecontroller')) const StyleController = asyncComponent(() => import('@/menu/stylecontroller')) const SysInterface = asyncComponent(() => import('@/menu/sysinterface')) +const UrlFieldComponent = asyncComponent(() => import('@/menu/urlfieldcomponent')) const PictureController = asyncComponent(() => import('@/menu/picturecontroller')) const ModalController = asyncComponent(() => import('@/menu/modalconfig/controller')) const StyleCombController = asyncComponent(() => import('@/menu/stylecombcontroller')) @@ -43,6 +44,7 @@ document.body.className = '' window.GLOB.UserComponentMap = new Map() // 缂撳瓨鐢ㄦ埛鑷畾涔夌粍浠� window.GLOB.CacheIndependent = new Map() +window.GLOB.urlFields = [] // url鍙橀噺 class MenuDesign extends Component { state = { @@ -446,6 +448,7 @@ config.uuid = MenuId config.MenuID = MenuId config.open_edition = result.open_edition || '' + window.GLOB.urlFields = config.urlFields || [] if (urlParam.fixed) { config.fixed = true @@ -1424,6 +1427,7 @@ MenuId={MenuId} updateConfig={this.updateConfig} /> : null} + {config ? <UrlFieldComponent config={config} updateConfig={this.updateConfig}/> : null} {/* 琛ㄥ悕娣诲姞 */} {config ? <TableComponent config={config} updatetable={this.updateConfig}/> : null} </Panel> -- Gitblit v1.8.0