From 5a7e0659e6365709e2f5c02307d5d5b0a6bd1cc8 Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期一, 22 二月 2021 17:15:40 +0800 Subject: [PATCH] 2021-02-22 --- src/pc/padcontroller/index.scss | 9 src/mob/header/index.jsx | 6 src/views/appmanage/index.scss | 0 src/views/design/header/index.jsx | 6 src/pc/bgcontroller/index.jsx | 103 +++ src/views/pcdesign/menuform/index.scss | 10 src/menu/components/card/cardcellcomponent/index.jsx | 3 src/mob/datasource/verifycard/settingform/index.jsx | 2 src/views/appmanage/mutilform/index.scss | 0 src/views/pcdesign/index.jsx | 989 ++++++++++++++++++++++++++++++++++ src/views/pcdesign/menuform/index.jsx | 161 +++++ src/pc/padcontroller/index.jsx | 105 +++ src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx | 2 src/menu/datasource/verifycard/settingform/index.jsx | 2 src/router/index.js | 8 src/pc/bgcontroller/index.scss | 43 + src/api/index.js | 14 src/views/pcdesign/index.scss | 190 ++++++ src/views/appmanage/index.jsx | 12 src/views/appmanage/submutilform/index.scss | 0 src/tabviews/zshare/settingcomponent/editTable/index.jsx | 2 src/views/appmanage/submutilform/index.jsx | 12 src/views/mobdesign/index.jsx | 22 src/views/appmanage/mutilform/index.jsx | 2 24 files changed, 1,646 insertions(+), 57 deletions(-) diff --git a/src/api/index.js b/src/api/index.js index aa7e885..64de6d8 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -373,7 +373,7 @@ * @description 鑾峰彇鎴栦慨鏀逛簯绔厤缃� */ getCloudConfig (param) { - param.lang = localStorage.getItem('lang') || '' + param.lang = param.lang || localStorage.getItem('lang') || '' param.appkey = window.GLOB.appkey || '' param.SessionUid = localStorage.getItem('SessionUid') || '' @@ -403,7 +403,7 @@ * @description 鑾峰彇浜戠閰嶇疆锛屽苟缂撳瓨淇℃伅 */ getCloudCacheConfig (param) { - param.lang = localStorage.getItem('lang') || '' + param.lang = param.lang || localStorage.getItem('lang') || '' param.appkey = window.GLOB.appkey || '' param.SessionUid = localStorage.getItem('SessionUid') || '' @@ -452,7 +452,7 @@ */ getSystemConfig (param) { param.userid = sessionStorage.getItem('UserID') || '' - param.lang = localStorage.getItem('lang') || '' + param.lang = param.lang || localStorage.getItem('lang') || '' param.SessionUid = localStorage.getItem('SessionUid') || '' param.LoginUID = sessionStorage.getItem('LoginUID') || '' param.appkey = window.GLOB.appkey || '' @@ -479,7 +479,7 @@ */ getLocalConfig (param) { param.userid = sessionStorage.getItem('UserID') || '' - param.lang = localStorage.getItem('lang') || '' + param.lang = param.lang || localStorage.getItem('lang') || '' param.SessionUid = localStorage.getItem('SessionUid') || '' param.LoginUID = sessionStorage.getItem('LoginUID') || '' param.appkey = window.GLOB.appkey || '' @@ -499,7 +499,7 @@ */ getCacheConfig (param) { param.userid = sessionStorage.getItem('UserID') || '' - param.lang = localStorage.getItem('lang') || '' + param.lang = param.lang || localStorage.getItem('lang') || '' param.SessionUid = localStorage.getItem('SessionUid') || '' param.LoginUID = sessionStorage.getItem('LoginUID') || '' param.appkey = window.GLOB.appkey || '' @@ -593,7 +593,7 @@ */ getLocalCacheConfig (param) { param.userid = sessionStorage.getItem('UserID') || '' - param.lang = localStorage.getItem('lang') || '' + param.lang = param.lang || localStorage.getItem('lang') || '' param.SessionUid = localStorage.getItem('SessionUid') || '' param.LoginUID = sessionStorage.getItem('LoginUID') || '' param.appkey = window.GLOB.appkey || '' @@ -650,7 +650,7 @@ */ getSystemCacheConfig (param) { param.userid = param.userid || sessionStorage.getItem('UserID') || '' - param.lang = localStorage.getItem('lang') || '' + param.lang = param.lang || localStorage.getItem('lang') || '' param.SessionUid = localStorage.getItem('SessionUid') || '' param.LoginUID = param.LoginUID || sessionStorage.getItem('LoginUID') || '' param.appkey = window.GLOB.appkey || '' diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx index 045c3e1..24a3b29 100644 --- a/src/menu/components/card/cardcellcomponent/index.jsx +++ b/src/menu/components/card/cardcellcomponent/index.jsx @@ -558,6 +558,9 @@ dropButton = (id) => { const { cards } = this.props + + if (!cards.action) return + let index = cards.action.findIndex(item => item.uuid === id) if (index === -1) return diff --git a/src/menu/datasource/verifycard/settingform/index.jsx b/src/menu/datasource/verifycard/settingform/index.jsx index da631aa..a000237 100644 --- a/src/menu/datasource/verifycard/settingform/index.jsx +++ b/src/menu/datasource/verifycard/settingform/index.jsx @@ -315,7 +315,7 @@ {config.format === 'array' ? <Col span={8}> <Form.Item label="榛樿鎺掑簭"> {getFieldDecorator('order', { - initialValue: setting.order || '', + initialValue: setting.order || 'ID asc', rules: [ { required: true, diff --git a/src/mob/datasource/verifycard/settingform/index.jsx b/src/mob/datasource/verifycard/settingform/index.jsx index cfe861a..41c3e3f 100644 --- a/src/mob/datasource/verifycard/settingform/index.jsx +++ b/src/mob/datasource/verifycard/settingform/index.jsx @@ -286,7 +286,7 @@ {structure === 'array' ? <Col span={8}> <Form.Item label="榛樿鎺掑簭"> {getFieldDecorator('order', { - initialValue: setting.order || '' + initialValue: setting.order || 'ID asc' })(<Input placeholder={'ID asc, UID desc'} autoComplete="off" />)} </Form.Item> </Col> : null} diff --git a/src/mob/header/index.jsx b/src/mob/header/index.jsx index 34db685..d2fa1e6 100644 --- a/src/mob/header/index.jsx +++ b/src/mob/header/index.jsx @@ -19,7 +19,6 @@ view: PropTypes.string, saveIng: PropTypes.any, triggerSave: PropTypes.func, - jumpToManage: PropTypes.func } state = { @@ -64,11 +63,6 @@ theme="dark" inlineCollapsed={this.state.collapsed} > - <Menu.Item key="1"> - <Tooltip placement="bottom" title="杩斿洖搴旂敤绠$悊"> - <Icon type="arrow-left" onClick={this.props.jumpToManage} /> - </Tooltip> - </Menu.Item> <Menu.Item key="2"> <Tooltip placement="bottom" title="淇濆瓨"> <Button icon="save" loading={this.props.saveIng} onClick={this.props.triggerSave}></Button> diff --git a/src/pc/bgcontroller/index.jsx b/src/pc/bgcontroller/index.jsx new file mode 100644 index 0000000..ab2155c --- /dev/null +++ b/src/pc/bgcontroller/index.jsx @@ -0,0 +1,103 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Form } from 'antd' + +import zhCN from '@/locales/zh-CN/mob.js' +import enUS from '@/locales/en-US/mob.js' +import asyncComponent from '@/utils/asyncComponent' +import './index.scss' + +const ColorSketch = asyncComponent(() => import('@/mob/colorsketch')) +const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent')) + +class MobController extends Component { + static propTpyes = { + config: PropTypes.any, + updateConfig: PropTypes.func, + } + + state = { + dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, + backgroundColor: '', + backgroundImage: '', + } + + UNSAFE_componentWillMount () { + const { config } = this.props + + let bgImg = config.style.backgroundImage || '' + + if (bgImg && /^url/.test(bgImg)) { + bgImg = bgImg.replace('url(', '') + bgImg = bgImg.replace(')', '') + } + + this.setState({ + backgroundColor: config.style.backgroundColor, + backgroundImage: bgImg + }) + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + /** + * @description 淇敼鑳屾櫙棰滆壊 锛岄鑹叉帶浠� + */ + changeBackgroundColor = (val) => { + let config = fromJS(this.props.config).toJS() + + this.setState({ + backgroundColor: val + }) + + config.style.backgroundColor = val + this.props.updateConfig(config) + } + + imgChange = (val) => { + this.setState({ + backgroundImage: val + }) + + let config = fromJS(this.props.config).toJS() + + if (val) { + config.style.backgroundImage = `url(${val})` + } else { + delete config.style.backgroundImage + } + this.props.updateConfig(config) + } + + render () { + const { backgroundColor, backgroundImage } = this.state + const formItemLayout = { + labelCol: { + xs: { span: 24 }, + sm: { span: 4 } + }, + wrapperCol: { + xs: { span: 24 }, + sm: { span: 20 } + } + } + + return ( + <div className="menu-background-controller"> + <Form {...formItemLayout}> + <Form.Item className="color-control" colon={false} label="棰滆壊"> + <ColorSketch value={backgroundColor} onChange={this.changeBackgroundColor} /> + </Form.Item> + <Form.Item colon={false} label="鍥剧墖"> + <SourceComponent value={backgroundImage} type="" placement="right" onChange={this.imgChange}/> + </Form.Item> + </Form> + </div> + ) + } +} + +export default MobController \ No newline at end of file diff --git a/src/pc/bgcontroller/index.scss b/src/pc/bgcontroller/index.scss new file mode 100644 index 0000000..0d6ed73 --- /dev/null +++ b/src/pc/bgcontroller/index.scss @@ -0,0 +1,43 @@ +.menu-background-controller { + width: 100%; + height: 100%; + overflow: hidden; + .color-control .ant-form-item-control { + padding-top: 10px; + line-height: 35px; + } + .mk-source-wrap { + height: 32px; + .mk-source-item-info { + top: 5px; + } + } +} + +.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/pc/padcontroller/index.jsx b/src/pc/padcontroller/index.jsx new file mode 100644 index 0000000..ec3f6bb --- /dev/null +++ b/src/pc/padcontroller/index.jsx @@ -0,0 +1,105 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Form, Col, Icon } from 'antd' + +import zhCN from '@/locales/zh-CN/mob.js' +import enUS from '@/locales/en-US/mob.js' +import StyleInput from '@/menu/stylecontroller/styleInput' +import './index.scss' + +class MobController extends Component { + static propTpyes = { + config: PropTypes.any, + updateConfig: PropTypes.func, + } + + state = { + dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, + paddingTop: '', + paddingBottom: '', + paddingLeft: '', + paddingRight: '' + } + + UNSAFE_componentWillMount () { + + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + /** + * @description 淇敼鑳屾櫙棰滆壊 锛岄鑹叉帶浠� + */ + changePadding = (val, type) => { + let config = fromJS(this.props.config).toJS() + + config.style[type] = val + this.props.updateConfig(config) + } + + render () { + const { config } = this.props + const formItemLayout = { + labelCol: { + xs: { span: 24 }, + sm: { span: 4 } + }, + wrapperCol: { + xs: { span: 24 }, + sm: { span: 20 } + } + } + + return ( + <div className="menu-padding-controller"> + <Form {...formItemLayout}> + <Col span={24}> + <Form.Item + colon={false} + label={<Icon title="瀹藉害" type="column-width" />} + > + <StyleInput defaultValue={config.style.width || '100%'} options={['px', '%', 'vw']} onChange={(val) => this.changePadding(val, 'width')}/> + </Form.Item> + </Col> + <Col span={24}> + <Form.Item + colon={false} + label={<Icon title="涓婅竟璺�" type="arrow-up"/>} + > + <StyleInput defaultValue={config.style.paddingTop || '0px'} options={['px', 'vh', 'vw']} onChange={(val) => this.changePadding(val, 'paddingTop')}/> + </Form.Item> + </Col> + <Col span={24}> + <Form.Item + colon={false} + label={<Icon title="涓嬭竟璺�" type="arrow-down"/>} + > + <StyleInput defaultValue={config.style.paddingBottom || '0px'} options={['px', 'vh', 'vw']} onChange={(val) => this.changePadding(val, 'paddingBottom')}/> + </Form.Item> + </Col> + <Col span={24}> + <Form.Item + colon={false} + label={<Icon title="宸﹁竟璺�" type="arrow-left"/>} + > + <StyleInput defaultValue={config.style.paddingLeft || '0px'} options={['px', 'vh', 'vw']} onChange={(val) => this.changePadding(val, 'paddingLeft')}/> + </Form.Item> + </Col> + <Col span={24}> + <Form.Item + colon={false} + label={<Icon title="鍙宠竟璺�" type="arrow-right"/>} + > + <StyleInput defaultValue={config.style.paddingRight || '0px'} options={['px', 'vh', 'vw']} onChange={(val) => this.changePadding(val, 'paddingRight')}/> + </Form.Item> + </Col> + </Form> + </div> + ) + } +} + +export default MobController \ No newline at end of file diff --git a/src/pc/padcontroller/index.scss b/src/pc/padcontroller/index.scss new file mode 100644 index 0000000..95c0abe --- /dev/null +++ b/src/pc/padcontroller/index.scss @@ -0,0 +1,9 @@ +.menu-padding-controller { + width: 100%; + height: 100%; + overflow: hidden; + .ant-form-item label > .anticon { + font-size: 16px; + vertical-align: middle; + } +} diff --git a/src/router/index.js b/src/router/index.js index 65fd766..8f61de0 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -12,7 +12,8 @@ const Design = asyncLoadComponent(() => import('@/views/design')) const Login = asyncLoadComponent(() => import('@/views/login')) const NotFound = asyncComponent(() => import('@/views/404')) -const MobManage = asyncLoadComponent(() => import('@/views/mobmanage')) +const AppManage = asyncLoadComponent(() => import('@/views/appmanage')) +const PCDesign = asyncLoadComponent(() => import('@/views/pcdesign')) const MobDesign = asyncLoadComponent(() => import('@/views/mobdesign')) const MenuDesign = asyncLoadComponent(() => import('@/views/menudesign')) const BillPrint = asyncLoadComponent(() => import('@/views/billprint')) @@ -25,8 +26,9 @@ {path: '/ssologin/:param', name: 'ssologin', component: Sso, auth: false}, {path: '/main', name: 'main', component: Main, auth: true}, {path: '/design', name: 'design', component: Design, auth: true}, - {path: '/mobmanage', name: 'mobmanage', component: MobManage, auth: true}, - {path: '/mobdesign/:appId/:appType/:appCode/:appName', name: 'mobdesign', component: MobDesign, auth: true}, + {path: '/appmanage', name: 'appmanage', component: AppManage, auth: true}, + {path: '/pcdesign/:param', name: 'pcdesign', component: PCDesign, auth: true}, + {path: '/mobdesign/:param', name: 'mobdesign', component: MobDesign, auth: true}, {path: '/menudesign/:param', name: 'menudesign', component: MenuDesign, auth: true}, {path: '/billprint/:param', name: 'billprint', component: BillPrint, auth: true}, {path: '/paramsmain/:param', name: 'pmain', component: Main, auth: true} diff --git a/src/tabviews/zshare/settingcomponent/editTable/index.jsx b/src/tabviews/zshare/settingcomponent/editTable/index.jsx index 214f0ad..7f8286f 100644 --- a/src/tabviews/zshare/settingcomponent/editTable/index.jsx +++ b/src/tabviews/zshare/settingcomponent/editTable/index.jsx @@ -21,7 +21,7 @@ if (inputType === 'select') { let _options = [] if (record.$port) { - _options = window.GLOB.UserCacheMap.get(record.$port) + _options = window.GLOB.UserCacheMap.get(record.$port) || [] } return ( <Select allowClear> diff --git a/src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx b/src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx index e303c63..7c11299 100644 --- a/src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx +++ b/src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx @@ -465,7 +465,7 @@ <Col span={12}> <Form.Item label="榛樿鎺掑簭"> {getFieldDecorator('order', { - initialValue: setting.order || '', + initialValue: setting.order || 'ID asc', rules: [ { required: true, diff --git a/src/views/mobmanage/index.jsx b/src/views/appmanage/index.jsx similarity index 97% rename from src/views/mobmanage/index.jsx rename to src/views/appmanage/index.jsx index 64056b2..8b9b2fc 100644 --- a/src/views/mobmanage/index.jsx +++ b/src/views/appmanage/index.jsx @@ -231,7 +231,14 @@ } jumpApp = (item) => { - console.log(item) + const { selectApp } = this.state + + let route = 'mobdesign' + if (item.typename === 'pc') { + route = 'pcdesign' + } + + window.open(window.location.href.replace(/#.+/ig, `#/${route}/${window.btoa(window.encodeURIComponent(JSON.stringify({...item, kei_no: selectApp.kei_no, remark: selectApp.remark, type: 'app'})))}`)) } /** @@ -262,7 +269,6 @@ * @description 鐐瑰嚮鏁磋锛岃Е鍙戝垏鎹紝 鍒ゆ柇鏄惁鍙�夛紝鍗曢�夋垨澶氶�夛紝杩涜瀵瑰簲鎿嶄綔 */ changeSubRow = (record) => { - console.log(record) this.setState({ selectedSubRowKeys: [record.ID], selectSubApp: record }) } @@ -370,7 +376,7 @@ const { selectApp, subVisible, selectSubApp } = this.state this.submobcardRef.handleConfirm().then(res => { - if (subVisible === 'plus' && selectApp.sublist.filter(item => item.typename === res.typename).length > 0) { + if (subVisible === 'plus' && selectApp.sublist.filter(item => item.typename === res.typename && item.lang === res.lang).length > 0) { notification.warning({ top: 92, message: '搴旂敤绫诲瀷宸插瓨鍦紒', diff --git a/src/views/mobmanage/index.scss b/src/views/appmanage/index.scss similarity index 100% rename from src/views/mobmanage/index.scss rename to src/views/appmanage/index.scss diff --git a/src/views/mobmanage/mutilform/index.jsx b/src/views/appmanage/mutilform/index.jsx similarity index 98% rename from src/views/mobmanage/mutilform/index.jsx rename to src/views/appmanage/mutilform/index.jsx index 0dca07e..f27151f 100644 --- a/src/views/mobmanage/mutilform/index.jsx +++ b/src/views/appmanage/mutilform/index.jsx @@ -43,7 +43,7 @@ }, wrapperCol: { xs: { span: 24 }, - sm: { span: 16 } + sm: { span: 12 } } } return ( diff --git a/src/views/mobmanage/mutilform/index.scss b/src/views/appmanage/mutilform/index.scss similarity index 100% rename from src/views/mobmanage/mutilform/index.scss rename to src/views/appmanage/mutilform/index.scss diff --git a/src/views/mobmanage/submutilform/index.jsx b/src/views/appmanage/submutilform/index.jsx similarity index 91% rename from src/views/mobmanage/submutilform/index.jsx rename to src/views/appmanage/submutilform/index.jsx index 36af92e..10741c4 100644 --- a/src/views/mobmanage/submutilform/index.jsx +++ b/src/views/appmanage/submutilform/index.jsx @@ -43,7 +43,7 @@ }, wrapperCol: { xs: { span: 24 }, - sm: { span: 16 } + sm: { span: 12 } } } return ( @@ -52,13 +52,7 @@ <Col span={24}> <Form.Item label="搴旂敤绫诲瀷"> {getFieldDecorator('typename', { - initialValue: card ? card.typename : 'mob', - rules: [ - { - required: true, - message: '璇烽�夋嫨搴旂敤绫诲瀷!' - } - ] + initialValue: card ? card.typename : 'mob' })( <Select disabled={type === 'edit'}> <Select.Option value="mob">绉诲姩绔�(鍖呮嫭android銆乮os)</Select.Option> @@ -72,7 +66,7 @@ {getFieldDecorator('lang', { initialValue: card ? card.lang || 'zh-CN' : 'zh-CN' })( - <Radio.Group> + <Radio.Group disabled={type === 'edit'}> <Radio value="zh-CN">涓枃</Radio> <Radio value="en-US">鑻辨枃</Radio> </Radio.Group> diff --git a/src/views/mobmanage/submutilform/index.scss b/src/views/appmanage/submutilform/index.scss similarity index 100% rename from src/views/mobmanage/submutilform/index.scss rename to src/views/appmanage/submutilform/index.scss diff --git a/src/views/design/header/index.jsx b/src/views/design/header/index.jsx index 99584b2..97057a3 100644 --- a/src/views/design/header/index.jsx +++ b/src/views/design/header/index.jsx @@ -328,9 +328,9 @@ {editLevel === 'HS' ? <Button className="level4-close" type="primary" onClick={this.exitManage}>閫�鍑�</Button> : null} {/* 杩涘叆缂栬緫鎸夐挳 */} {!editLevel ? <Icon onClick={this.enterEdit} className="edit-check" type="edit" /> : null} - {/* {!editLevel && options.sysType === 'local' && window.GLOB.systemType !== 'production' ? - <a href="#/mobmanage" target="_blank" className="mobile" type="edit"> 搴旂敤绠$悊 <Icon type="arrow-right" /></a> : null - } */} + {!editLevel && options.sysType === 'local' && window.GLOB.systemType !== 'production' ? + <a href="#/appmanage" target="_blank" className="mobile" type="edit"> 搴旂敤绠$悊 <Icon type="arrow-right" /></a> : null + } {/* window.btoa(window.encodeURIComponent(JSON.stringify({ MenuType: 'home', MenuId: 'home_page_id', MenuName: '棣栭〉' }))) */} {!editLevel && window.GLOB.systemType !== 'production' && this.props.memberLevel >= 20 ? <a className="home-edit" href={`#/menudesign/JTdCJTIyTWVudVR5cGUlMjIlM0ElMjJob21lJTIyJTJDJTIyTWVudUlkJTIyJTNBJTIyaG9tZV9wYWdlX2lkJTIyJTJDJTIyTWVudU5hbWUlMjIlM0ElMjIlRTklQTYlOTYlRTklQTElQjUlMjIlN0Q=`} target="_blank" rel="noopener noreferrer"> diff --git a/src/views/mobdesign/index.jsx b/src/views/mobdesign/index.jsx index b090a70..552d5e1 100644 --- a/src/views/mobdesign/index.jsx +++ b/src/views/mobdesign/index.jsx @@ -1,7 +1,7 @@ import React, { Component } from 'react' import { connect } from 'react-redux' import { DndProvider } from 'react-dnd' -import { is, fromJS } from 'immutable' +import { fromJS } from 'immutable' import moment from 'moment' import HTML5Backend from 'react-dnd-html5-backend' import { Icon, Tabs, notification, Modal } from 'antd' @@ -50,26 +50,6 @@ componentWillUnmount () { this.setState = () => { return - } - } - - jumpToManage = () => { - const { oriConfig, config } = this.state - const _this = this - - if (!is(fromJS(oriConfig), fromJS(config))) { - confirm({ - title: '閰嶇疆宸蹭慨鏀癸紝鏀惧純淇濆瓨鍚楋紵', - content: '', - okText: _this.state.dict['mob.confirm'], - cancelText: _this.state.dict['mob.cancel'], - onOk() { - _this.props.history.replace('/mobmanage') - }, - onCancel() {} - }) - } else { - _this.props.history.replace('/mobmanage') } } diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx new file mode 100644 index 0000000..1c39a05 --- /dev/null +++ b/src/views/pcdesign/index.jsx @@ -0,0 +1,989 @@ +import React, { Component } from 'react' +import { connect } from 'react-redux' +import { DndProvider } from 'react-dnd' +import { is, fromJS } from 'immutable' +import moment from 'moment' +import HTML5Backend from 'react-dnd-html5-backend' +import { ConfigProvider, notification, Modal, Collapse, Switch, Button, Icon } from 'antd' +// import html2canvas from 'html2canvas' + +import Api from '@/api' +// import options from '@/store/options.js' +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 '@/menu/utils/menuUtils.js' +import asyncComponent from '@/utils/asyncComponent' +import { modifyCustomMenu } from '@/store/action' + +import './index.scss' + +const { Panel } = Collapse +const { confirm } = Modal +const _locale = localStorage.getItem('lang') !== 'en-US' ? antdZhCN : antdEnUS + +const MenuForm = asyncComponent(() => import('./menuform')) +const MenuShell = asyncComponent(() => import('@/menu/menushell')) +const SourceWrap = asyncComponent(() => import('@/menu/modulesource')) +const BgController = asyncComponent(() => import('@/pc/bgcontroller')) +const PasteController = asyncComponent(() => import('@/menu/pastecontroller')) +const PaddingController = asyncComponent(() => import('@/pc/padcontroller')) +const StyleController = asyncComponent(() => import('@/menu/stylecontroller')) +const SysInterface = asyncComponent(() => import('@/menu/sysinterface')) +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')) + +sessionStorage.setItem('isEditState', 'true') +sessionStorage.setItem('editMenuType', 'menu') // 缂栬緫鑿滃崟绫诲瀷 +document.body.className = '' +window.GLOB.UserComponentMap = new Map() // 缂撳瓨鐢ㄦ埛鑷畾涔夌粍浠� + +class MenuDesign extends Component { + state = { + dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, + MenuId: '', + MenuName: '', + MenuNo: '', + tableFields: [], + delButtons: [], + copyButtons: [], + thawButtons: [], + activeKey: 'basedata', + menuloading: false, + oriConfig: null, + openEdition: '', + config: null, + popBtn: null, // 寮圭獥鏍囩椤� + visible: false, + customComponents: [], + settingshow: true, + controlshow: true, + } + + UNSAFE_componentWillMount() { + 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') + } else if (param.type === 'view') { + this.setState({ + MenuId: param.MenuID + }) + } + this.getAppMessage() + } catch { + notification.warning({ + top: 92, + message: '鑿滃崟淇℃伅瑙f瀽閿欒锛�', + duration: 5 + }) + } + } + + shouldComponentUpdate (nextProps, nextState) { + return !is(fromJS(this.state), fromJS(nextState)) + } + + componentDidMount () { + MKEmitter.addListener('delButtons', this.delButtons) + MKEmitter.addListener('thawButtons', this.thawButtons) + MKEmitter.addListener('copyButtons', this.copyButtons) + MKEmitter.addListener('changePopview', this.initPopview) + MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle) + MKEmitter.addListener('updateCustomComponent', this.updateCustomComponent) + setTimeout(() => { + this.updateCustomComponent() + this.getAppPictures() + }, 1000) + } + + /** + * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊 + */ + componentWillUnmount () { + this.setState = () => { + return + } + MKEmitter.removeListener('delButtons', this.delButtons) + MKEmitter.removeListener('thawButtons', this.thawButtons) + MKEmitter.removeListener('copyButtons', this.copyButtons) + MKEmitter.removeListener('changePopview', this.initPopview) + MKEmitter.removeListener('submitComponentStyle', this.updateComponentStyle) + MKEmitter.removeListener('updateCustomComponent', this.updateCustomComponent) + } + + getAppMessage = () => { + Api.getSystemConfig({ + func: 's_get_keyids', + bid: sessionStorage.getItem('appId') + }).then(res => { + if (!res) { + notification.warning({ + top: 92, + message: res.message, + duration: 5 + }) + return + } + + let homeId = '' + if (this.state.MenuId) { + homeId = this.state.MenuId + } else { + 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: '' + } + + 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 + }) + } + }) + } + + sessionStorage.setItem('appViewList', JSON.stringify(appViewList)) + } + this.props.history.replace('/pcdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: homeId, type: 'view'})))) + + this.setState({MenuId: homeId}, () => { + this.getMenuParam() + }) + }) + } + + getAppPictures = () => { + 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 } = this.state + + this.setState({ + delButtons: [...this.state.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]}) + } + + initPopview = (card, btn) => { + // const { oriConfig, config } = this.state + + // let _config = fromJS(config).toJS() + // delete _config.tableFields + + // if (!is(fromJS(oriConfig), fromJS(_config))) { + // notification.warning({ + // top: 92, + // message: '閰嶇疆宸蹭慨鏀癸紝璇蜂繚瀛橈紒', + // duration: 5 + // }) + // return + // } + + // btn.config = _config + // btn.component = card + + // sessionStorage.setItem('editMenuType', 'popview') // 缂栬緫寮圭獥鏍囩 + + // this.setState({popBtn: btn, visible: true}) + } + + closeView = () => { + const { oriConfig, config } = this.state + + if (!config) { + window.close() + return + } + + let _config = fromJS(config).toJS() + delete _config.tableFields + + if (!is(fromJS(oriConfig), fromJS(_config))) { + confirm({ + title: '閰嶇疆宸蹭慨鏀癸紝鏀惧純淇濆瓨鍚楋紵', + content: '', + onOk() { + window.close() + }, + onCancel() {} + }) + } else { + window.close() + } + } + + getMenuParam = () => { + const { MenuId } = this.state + + let param = { + func: 'sPC_Get_LongParam', + MenuID: MenuId + } + + Api.getSystemConfig(param).then(result => { + if (result.status) { + 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', + easyCode: '', + enabled: false, + MenuName: '', + MenuNo: '', + tables: [], + components: [], + viewType: 'menu', + style: { + backgroundColor: '#ffffff', backgroundImage: '', paddingLeft: '20px', paddingRight: '20px' + } + } + } + + config.uuid = MenuId + config.MenuID = MenuId + + this.setState({ + oriConfig: config, + config: fromJS(config).toJS(), + openEdition: result.open_edition || '', + }) + + this.props.modifyCustomMenu(config) + } else { + notification.warning({ + top: 92, + message: result.message, + duration: 5 + }) + } + }) + } + + 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 { openEdition, delButtons, copyButtons, thawButtons } = this.state + let config = fromJS(this.state.config).toJS() + + if (!config.MenuName || !config.MenuNo || (config.cacheUseful === 'true' && !config.cacheTime)) { + notification.warning({ + top: 92, + message: '璇峰畬鍠勮彍鍗曞熀鏈俊鎭紒', + duration: 5 + }) + return + } + + this.setState({ + menuloading: true + }) + + setTimeout(() => { + config.components = this.filterConfig(config.components) + + if (config.enabled && this.verifyConfig()) { + config.enabled = false + } + + let _config = fromJS(config).toJS() + delete _config.tableFields + + let parMenuId = 'pc' + sessionStorage.getItem('kei_no') + sessionStorage.getItem('lang') + let param = { + func: 'sPC_TrdMenu_AddUpt', + FstID: parMenuId, + SndID: parMenuId, + ParentID: parMenuId, + MenuID: _config.uuid, + MenuNo: _config.MenuNo || '', + EasyCode: _config.easyCode || '', + Template: 'webPage', + MenuName: _config.MenuName || '', + PageParam: JSON.stringify({Template: 'webPage'}), + LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(_config))), + LText: '', + LTexttb: '' + } + + param.LText = Utils.formatOptions(param.LText) + param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + param.secretkey = Utils.encrypt(param.LText, param.timestamp) + + if (openEdition) { // 鐗堟湰绠$悊 + param.open_edition = openEdition + } + + 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 => { + // html2canvas(document.getElementById('menu-shell-inner')).then(canvas => { + // let _param = { + // Base64Img: canvas.toDataURL('image/png') // 鑾峰彇鐢熸垚鐨勫浘鐗� + // } + + // _param.rduri = options.cloudServiceApi + // _param.userid = sessionStorage.getItem('CloudUserID') || '' + // _param.LoginUID = sessionStorage.getItem('CloudLoginUID') || '' + + // Api.fileuploadbase64(_param).then(result => { + // if (result.status) { + // let Images = Utils.getcloudurl(result.Images) + // param.PageParam = JSON.stringify({Template: 'webPage', Images}) + // resolve(true) + // } else { + // notification.warning({ + // top: 92, + // message: result.ErrMesg, + // duration: 5 + // }) + // resolve(false) + // } + // }) + // }) + resolve(true) + }).then(res => { // 鎸夐挳鍒犻櫎 + if (!res) return + + if (delButtons.length === 0) { + return { + status: true + } + } else { + let _param = { + func: 'sPC_MainMenu_Del', + MenuID: delButtons.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 + } + + 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) { + this.setState({ + oriConfig: fromJS(_config).toJS(), + openEdition: res.open_edition || '' + }) + + 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 = () => { + 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) + } + + /** + * @description 鏇存柊甯哥敤琛ㄤ俊鎭紝蹇嵎娣诲姞鍚庢洿鏂伴厤缃俊鎭� + */ + updatetable = (config, fields) => { + const { tableFields } = this.state + + config.tableFields = fields ? fields : tableFields + + this.setState({ + tableFields: fields ? fields : tableFields, + config + }) + + this.props.modifyCustomMenu(config) + } + + render () { + const { activeKey, settingshow, controlshow, dict, MenuId, config, menuloading, customComponents } = this.state + + return ( + <ConfigProvider locale={_locale}> + <div className={'mk-pc-view '} id="mk-menu-design-view"> + <DndProvider backend={HTML5Backend}> + <div className={'menu-setting ' + (!settingshow ? 'hidden' : '')}> + <div className="draw"> + {settingshow ? <Icon onClick={() => this.setState({settingshow: false})} type="double-left" /> : null} + {!settingshow ? <Icon onClick={() => this.setState({settingshow: true})} type="double-right" /> : null} + </div> + <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 ? <TableComponent config={config} updatetable={this.updatetable}/> : null} + </Panel> + {/* 缁勪欢娣诲姞 */} + <Panel header={dict['mob.component']} key="component"> + <SourceWrap MenuType={'pc'} /> + </Panel> + {customComponents && customComponents.length ? <Panel header="鑷畾涔夌粍浠�" key="cuscomponent"> + <SourceWrap components={customComponents} MenuType={'pc'} /> + </Panel> : null} + <Panel header={'椤甸潰鑳屾櫙'} key="background"> + {config ? <BgController config={config} updateConfig={this.updateConfig} /> : null} + </Panel> + <Panel header={'椤甸潰鍐呰竟璺�'} key="padding"> + {config ? <PaddingController config={config} updateConfig={this.updateConfig} /> : null} + </Panel> + </Collapse> + </div> + </div> + <div className={'menu-control ' + (!controlshow ? 'hidden' : '')}> + <div className="draw"> + {controlshow ? <Icon onClick={() => this.setState({controlshow: false})} type="double-right" /> : null} + {!controlshow ? <Icon onClick={() => this.setState({controlshow: true})} type="double-left" /> : null} + </div> + <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/> + <Button type="default" onClick={this.closeView}>{dict['mob.return']}</Button> + </div> + <div className={'menu-body ' + (menuloading ? 'saving' : '')}> + {config && config.components ? <MenuShell menu={config} handleList={this.updateConfig} /> : null} + </div> + </DndProvider> + <StyleController /> + <StyleCombController /> + <ModalController /> + </div> + </ConfigProvider> + ) + } +} + +const mapStateToProps = () => { + return {} +} + +const mapDispatchToProps = (dispatch) => { + return { + modifyCustomMenu: (customMenu) => dispatch(modifyCustomMenu(customMenu)) + } +} + +export default connect(mapStateToProps, mapDispatchToProps)(MenuDesign) \ No newline at end of file diff --git a/src/views/pcdesign/index.scss b/src/views/pcdesign/index.scss new file mode 100644 index 0000000..590b099 --- /dev/null +++ b/src/views/pcdesign/index.scss @@ -0,0 +1,190 @@ +.mk-pc-view { + background: #000; + min-height: 100vh; + .menu-setting { + position: fixed; + left: 0; + top: 0px; + z-index: 10; + transition: left 0.3s; + + .draw { + position: absolute; + z-index: 1; + background: #ffffff; + right: -20px; + top: 0px; + box-shadow: 0 0 1px #959595; + border-radius: 0 2px 2px 0px; + + i { + padding: 12px 3px; + } + } + + .pc-setting-tools { + height: 100vh; + width: 300px; + background: #ffffff; + box-shadow: 0px 2px 5px #bcbcbc; + 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; + } + .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%; + } + } + } + } + + >.ant-tabs { + >.ant-tabs-bar { + border-bottom: 1px solid #181F29; + margin-bottom: 0px; + min-height: 48px; + .ant-tabs-tab { + padding: 14px 16px; + color: rgba(255, 255, 255, 0.85); + } + .ant-tabs-tab-active.ant-tabs-tab { + color: #1890ff; + } + } + } + } + .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); + } + } + .menu-setting.hidden { + left: -300px; + } + + .menu-control { + position: fixed; + right: 0; + top: 0px; + height: 100vh; + padding: 20px 10px; + background: #ffffff; + z-index: 10; + transition: right 0.3s; + box-shadow: 0px 0px 5px #bcbcbc; + + .draw { + position: absolute; + z-index: 1; + background: #ffffff; + left: -21px; + top: 0px; + box-shadow: 0 0 1px #959595; + border-radius: 0 2px 2px 0px; + + i { + padding: 12px 3px; + } + } + 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; + } + } + .ant-switch.big:after { + width: 22px; + height: 22px; + } + } + .menu-control.hidden { + right: -130px; + } + + .menu-body { + width: 100vw; + height: 100vh; + overflow-x: hidden; + position: relative; + background: #ffffff; + padding: 0px; + overflow-y: auto; + } + .menu-body.saving { + .anticon-tool { + display: none; + } + } + .menu-body::-webkit-scrollbar { + width: 7px; + } + .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); + } + .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/pcdesign/menuform/index.jsx b/src/views/pcdesign/menuform/index.jsx new file mode 100644 index 0000000..13163ce --- /dev/null +++ b/src/views/pcdesign/menuform/index.jsx @@ -0,0 +1,161 @@ +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 = {} + + UNSAFE_componentWillMount () { + + } + + UNSAFE_componentWillReceiveProps(nextProps) { + const { config } = this.props + if (!config && nextProps.config) { + this.props.form.setFieldsValue({easyCode: nextProps.config.easyCode}) + } + } + + // 涓�浜岀骇鑿滃崟鍒囨崲 + 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}) + } + + // 鍔╄鐮� + changeEasyCode = (e) => { + this.props.updateConfig({...this.props.config, easyCode: 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="" 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="" 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} + <Col span={24}> + <Form.Item label={dict['mob.menu.easycode']}> + {getFieldDecorator('easyCode', { + initialValue: config.easyCode + })(<Input placeholder="" autoComplete="off" onChange={this.changeEasyCode}/>)} + </Form.Item> + </Col> + </Row> + </Form> + ) + } +} + +export default Form.create()(CustomMenuForm) \ No newline at end of file diff --git a/src/views/pcdesign/menuform/index.scss b/src/views/pcdesign/menuform/index.scss new file mode 100644 index 0000000..71a1a33 --- /dev/null +++ b/src/views/pcdesign/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 -- Gitblit v1.8.0