| | |
| | | import { is, fromJS } from 'immutable' |
| | | import moment from 'moment' |
| | | import HTML5Backend from 'react-dnd-html5-backend' |
| | | import { ConfigProvider, notification, Modal, Collapse, Switch, Button, message, Spin, Icon, Typography } from 'antd' |
| | | import { ConfigProvider, notification, Modal, Collapse, Switch, Button, message, Spin, Typography } from 'antd' |
| | | import { DoubleLeftOutlined, DoubleRightOutlined, HomeOutlined, LoginOutlined, RedoOutlined } from '@ant-design/icons' |
| | | |
| | | import Api from '@/api' |
| | | import Utils, { setGLOBFuncs } from '@/utils/utils.js' |
| | |
| | | import MKEmitter from '@/utils/events.js' |
| | | import MenuUtils from '@/utils/utils-custom.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import backurl from '@/assets/img/back.jpg' |
| | | |
| | | import './index.scss' |
| | | |
| | |
| | | direction: 'vertical', |
| | | settingshow: true, |
| | | controlshow: true, |
| | | comloading: false |
| | | comloading: false, |
| | | adapters: [], |
| | | viewType: 'menu' |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | |
| | | sessionStorage.setItem('role_type', param.role_type || 'true') |
| | | sessionStorage.setItem('login_types', param.login_types || 'false') |
| | | sessionStorage.setItem('typename', param.typename || 'mob') |
| | | sessionStorage.setItem('adapter', param.adapter || 'false') |
| | | sessionStorage.setItem('adapter', param.adapter || '') |
| | | sessionStorage.setItem('sysBgColor', param.sysBgColor || '#ffffff') |
| | | sessionStorage.setItem('userbind', param.userbind || '') |
| | | sessionStorage.setItem('instantMessage', param.instantMessage || '') |
| | | |
| | | this.setState({ |
| | | localedict: sessionStorage.getItem('lang') !== 'en-US' ? antdZhCN : antdEnUS, |
| | |
| | | window.GLOB.shellHeight = 853 |
| | | } |
| | | |
| | | let adapters = sessionStorage.getItem('adapter') |
| | | if (adapters) { |
| | | adapters = adapters.split(',') |
| | | } else { |
| | | adapters = [] |
| | | } |
| | | |
| | | this.setState({ |
| | | MenuId: param.MenuID |
| | | adapters, |
| | | MenuId: param.MenuID, |
| | | viewType: /^userbind/.test(param.MenuID) ? 'userbind' : 'menu' |
| | | }, () => { |
| | | this.getMenuParam(param) |
| | | }) |
| | |
| | | this.getSmStemp() |
| | | setGLOBFuncs() |
| | | }, 1000) |
| | | |
| | | document.onkeydown = (event) => { |
| | | let e = event || window.event |
| | | let keyCode = e.keyCode || e.which || e.charCode |
| | | let preKey = '' |
| | | |
| | | if (e.ctrlKey) { |
| | | preKey = 'ctrl' |
| | | } |
| | | if (e.shiftKey) { |
| | | preKey = 'shift' |
| | | } else if (e.altKey) { |
| | | preKey = 'alt' |
| | | } |
| | | |
| | | if (!preKey || !keyCode) return |
| | | |
| | | let _shortcut = `${preKey}+${keyCode}` |
| | | |
| | | if (_shortcut === 'ctrl+83') { |
| | | let node = document.getElementById('save-modal-config') |
| | | if (!node) { |
| | | node = document.getElementById('save-config') |
| | | } |
| | | |
| | | if (node) { |
| | | node.click() |
| | | } |
| | | return false |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (['AIService'].includes(menu.MenuID)) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '系统页面不可编辑!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (menu.routerUrl) { |
| | | this.props.history.push(menu.routerUrl) |
| | | return |
| | | } |
| | | |
| | | let param = { |
| | |
| | | return |
| | | } |
| | | |
| | | let homeId = MenuID || '' |
| | | let homeId = '' |
| | | let appViewList = [] |
| | | if (!homeId && res.data && res.data.length > 0) { |
| | | if (res.data && res.data.length > 0) { |
| | | appViewList = res.data |
| | | appViewList.forEach(item => { |
| | | if (item.keys_type === 'index') { |
| | |
| | | } |
| | | |
| | | if (!homeId) { |
| | | homeId = Utils.getuuid() |
| | | homeId = MenuID || Utils.getuuid() |
| | | |
| | | let param = { |
| | | func: 's_kei_link_keyids_addupt', |
| | |
| | | }) |
| | | } else { |
| | | sessionStorage.setItem('appViewList', JSON.stringify(appViewList)) |
| | | this.props.history.replace('/mobdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: homeId, type: 'view'})))) |
| | | this.props.history.replace('/mobdesign/' + window.btoa(window.encodeURIComponent(JSON.stringify({MenuID: MenuID || homeId, type: 'view'})))) |
| | | } |
| | | }) |
| | | } |
| | |
| | | |
| | | if (!config) { |
| | | window.close() |
| | | return |
| | | } |
| | | |
| | | if (!oriConfig || !is(fromJS(oriConfig), fromJS(config))) { |
| | | } else if (!oriConfig || !is(fromJS(oriConfig), fromJS(config))) { |
| | | confirm({ |
| | | title: '配置信息未保存,确定关闭吗?', |
| | | content: '', |
| | |
| | | }) |
| | | } else { |
| | | window.close() |
| | | } |
| | | } |
| | | |
| | | backView = () => { |
| | | const { oriConfig, config } = this.state |
| | | |
| | | if (!config) { |
| | | window.history.back() |
| | | } else if (!oriConfig || !is(fromJS(oriConfig), fromJS(config))) { |
| | | confirm({ |
| | | title: '配置信息未保存,确定后退吗?', |
| | | content: '', |
| | | onOk() { |
| | | window.history.back() |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } else { |
| | | window.history.back() |
| | | } |
| | | } |
| | | |
| | |
| | | config = null |
| | | } |
| | | |
| | | if (/^userbind/.test(MenuId)) { |
| | | this.setUserBindMenu(config, result) |
| | | return |
| | | } |
| | | |
| | | if (!config) { |
| | | isCreate = true |
| | | config = { |
| | |
| | | tables: [], |
| | | components: [], |
| | | viewType: 'menu', |
| | | statusBarbgColor: sessionStorage.getItem('sysBgColor') || '#ffffff', |
| | | style: { |
| | | backgroundColor: '#ffffff', backgroundImage: '' |
| | | backgroundColor: sessionStorage.getItem('sysBgColor') || '#ffffff', backgroundImage: '' |
| | | } |
| | | } |
| | | } |
| | |
| | | this.getAppMenus() |
| | | } |
| | | |
| | | setUserBindMenu = (config, result) => { |
| | | const { MenuId } = this.state |
| | | let isCreate = !config |
| | | |
| | | if (!config) { |
| | | config = { |
| | | version: 1.0, |
| | | uuid: MenuId, |
| | | MenuID: MenuId, |
| | | Template: 'webPage', |
| | | enabled: false, |
| | | MenuName: '用户绑定', |
| | | MenuNo: 'user_bind', |
| | | tables: [], |
| | | components: [], |
| | | viewType: 'userbind', |
| | | statusBarbgColor: '#ffffff', |
| | | style: { |
| | | backgroundColor: '#ffffff', backgroundImage: '' |
| | | } |
| | | } |
| | | |
| | | config.components.push({ |
| | | subcards:[ |
| | | { |
| | | uuid: Utils.getuuid(), setting: {width:24, primaryId: '', click: ''}, style: {}, backStyle: {}, |
| | | elements: [{maxWidth: 120, datatype: 'static', width: 24, marks: null, url: 'http://cloud.mk9h.cn/Content/images/20220120/cb5cd13a-2ef4-41cc-ab6a-a202f1c04da5.png', style: {borderRadius: '50%'}, eleType: 'picture', link: '', uuid: Utils.getuuid(), lenWidRadio: '1:1', $type: ''}], |
| | | backElements: [] |
| | | } |
| | | ], |
| | | headerStyle: {}, parentId: '', width: 24, scripts: [], btnlog: [], pageable: false, |
| | | wrap: {name: 'logo', width: 24, datatype: 'static', cardType: '', blacklist: []}, |
| | | name: 'logo', floor: 1, switchable: true, |
| | | setting:{interType: 'system'}, tabId: '', style:{paddingTop: '8vh', paddingBottom: '10vh'}, dataName: Utils.getuuid(), format: 'object', subtype: 'propcard', type: 'card', uuid: Utils.getuuid(), columns: [] |
| | | }) |
| | | |
| | | config.components.push({ |
| | | uuid: Utils.getuuid(), |
| | | type: 'login', |
| | | floor: 1, |
| | | tabId: '', |
| | | parentId: '', |
| | | dataName: '', |
| | | width: 24, |
| | | name: '用户绑定', |
| | | subtype: 'bindlogin', |
| | | wrap: { name: '用户绑定', width: 24, loginWays: ['uname_pwd'], shortcut: 'none', height: '45vh' }, |
| | | style: {}, |
| | | loginWays: [ |
| | | {type: 'uname_pwd', label: '账号登录', shortcut: 'none'}, |
| | | {type: 'sms_vcode', label: '短信登录'}, |
| | | ] |
| | | }) |
| | | |
| | | config.components.push({ |
| | | subcards:[ |
| | | { |
| | | uuid: Utils.getuuid(), setting: {width:24, primaryId: '', click: ''}, style: {}, backStyle: {}, |
| | | elements: [{datatype: 'static', width: 24, marks: null, height: null, value: 'Power by Minkesoft', style: { fontSize: '13px', textAlign: 'center'}, eleType: 'text', link: '', uuid: Utils.getuuid(), $type: ''}], |
| | | backElements: [] |
| | | } |
| | | ], |
| | | headerStyle: {}, parentId: '', width: 24, scripts: [], btnlog: [], pageable: false, |
| | | wrap: {name: 'Power', width: 24, datatype: 'static', cardType: '', blacklist: []}, |
| | | name: 'Power', floor: 1, switchable: true, |
| | | setting:{interType: 'system'}, tabId: '', style:{}, dataName: Utils.getuuid(), format: 'object', subtype: 'propcard', type: 'card', uuid: Utils.getuuid(), columns: [] |
| | | }) |
| | | } |
| | | |
| | | config.uuid = MenuId |
| | | config.MenuID = MenuId |
| | | config.open_edition = result.open_edition || '' |
| | | |
| | | this.setState({ |
| | | oriConfig: isCreate ? null : config, |
| | | config: fromJS(config).toJS(), |
| | | activeKey: isCreate ? 'basedata' : 'component', |
| | | loading: false |
| | | }) |
| | | window.GLOB.customMenu = config |
| | | } |
| | | |
| | | getAppMenus = () => { |
| | | let _param = { |
| | | func: 's_get_app_menus', |
| | |
| | | let appIndeList = sessionStorage.getItem('appViewList') |
| | | appIndeList = JSON.parse(appIndeList) |
| | | appIndeList = appIndeList.map(item => (item.keys_type !== 'index' ? item.keys_id : '')).join(',') |
| | | |
| | | if (sessionStorage.getItem('userbind')) { |
| | | appIndeList = appIndeList + ',' + sessionStorage.getItem('userbind') |
| | | } |
| | | if (sessionStorage.getItem('instantMessage')) { |
| | | appIndeList = appIndeList + ',' + sessionStorage.getItem('instantMessage') |
| | | } |
| | | |
| | | let menus = res.menus.filter(item => appIndeList.indexOf(item.MenuID) === -1) |
| | | menus = menus.map(item => { |
| | |
| | | } |
| | | |
| | | submitConfig = () => { |
| | | const { adapters } = this.state |
| | | let config = fromJS(this.state.config).toJS() |
| | | |
| | | if (!config.MenuName || !config.MenuNo || (config.cacheUseful === 'true' && !config.cacheTime)) { |
| | |
| | | config.loginview = false |
| | | } |
| | | |
| | | if (sessionStorage.getItem('adapter') === 'true') { |
| | | if (adapters.includes('wxmini')) { |
| | | config = this.getMiniStyle(config) |
| | | } |
| | | |
| | |
| | | Typename: sessionStorage.getItem('typename'), |
| | | MenuName: item.name || '', |
| | | PageParam: JSON.stringify({Template: item.type}), |
| | | open_edition: _item.open_edition || '', |
| | | open_edition: _item ? (_item.open_edition || '') : '', |
| | | menus_rolelist: window.btoa(window.encodeURIComponent(JSON.stringify(roles))), |
| | | LText: '', |
| | | LTexttb: '' |
| | |
| | | } |
| | | |
| | | verifyConfig = (show) => { |
| | | const { config } = this.state |
| | | const { config, viewType } = this.state |
| | | let error = '' |
| | | let searchSum = 0 |
| | | let swipes = [] |
| | | |
| | | let check = (components) => { |
| | | components.forEach(item => { |
| | |
| | | return |
| | | } else if (item.type === 'navbar' && !item.wrap.MenuNo) { |
| | | error = `导航栏《${item.name}》未设置菜单参数!` |
| | | } else if (item.type === 'topbar') { |
| | | if (item.wrap.type === 'search' || item.wrap.type === 'searchIcon' || (item.wrap.type === 'navbar' && item.wrap.search === 'true')) { |
| | | searchSum += 1 |
| | | } |
| | | } else if (item.type === 'search') { |
| | | searchSum += 1 |
| | | if (!item.wrap.field) { |
| | | error = `搜索条件《${item.name}》未设置搜索字段!` |
| | | } |
| | | } else if (item.subtype === 'propcard' && item.subcards.length === 0) { |
| | | error = `组件《${item.name}》中卡片不可为空!` |
| | | return |
| | | } else if (item.type === 'login' && !item.wrap.linkmenu && item.wrap.link !== 'menu') { |
| | | error = '登录组件未设置关联菜单!' |
| | | return |
| | | } |
| | | if (item.wrap && item.wrap.pagestyle === 'slide') { |
| | | swipes.push(item.name) |
| | | } |
| | | |
| | | if (['propcard', 'brafteditor', 'sandbox', 'tabbar', 'stepform', 'tabform'].includes(item.subtype) && item.wrap.datatype === 'static') return |
| | |
| | | } |
| | | |
| | | check(config.components) |
| | | |
| | | if (!error && viewType === 'userbind' && config.components.filter(item => item.type === 'login').length === 0) { |
| | | error = '用户绑定页面必须添加登录。' |
| | | } |
| | | |
| | | if (!error && searchSum > 1) { |
| | | error = '搜索组件与导航栏的搜索功能不可同时使用。' |
| | | } else if (!error && swipes.length > 1) { |
| | | error = `页面中不可同时使用多个滑动加载组件。(${swipes.join('、')})` |
| | | } |
| | | |
| | | if (show && error) { |
| | | notification.warning({ |
| | |
| | | |
| | | |
| | | render () { |
| | | const { localedict, comloading, loading, settingshow, controlshow, activeKey, dict, MenuId, config, menuloading, customComponents } = this.state |
| | | const { viewType, localedict, comloading, loading, settingshow, controlshow, activeKey, dict, MenuId, config, menuloading, customComponents, adapters } = this.state |
| | | |
| | | return ( |
| | | <ConfigProvider locale={localedict}> |
| | | <div className="mk-mob-view" id="mk-mob-design-view"> |
| | | <div className={'mk-mob-view ' + viewType} id="mk-mob-design-view"> |
| | | <Header changeView={this.changeView}/> |
| | | {loading ? <Spin className="view-spin" size="large" /> : null} |
| | | <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} |
| | | {settingshow ? <DoubleLeftOutlined onClick={() => {this.setState({settingshow: false})}} /> : null} |
| | | {!settingshow ? <DoubleRightOutlined onClick={() => {this.setState({settingshow: true})}} /> : null} |
| | | </div> |
| | | <div className="pc-setting-tools"> |
| | | <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}> |
| | | {/* 基本信息 */} |
| | | <Panel header={dict['mob.basemsg']} forceRender key="basedata"> |
| | | <Panel header={dict['mob.basemsg']} forceRender className="basedata" key="basedata"> |
| | | {/* 菜单信息 */} |
| | | {config ? <MenuForm |
| | | dict={dict} |
| | | config={config} |
| | | MenuId={MenuId} |
| | | adapters={adapters} |
| | | updateConfig={this.updateConfig} |
| | | /> : null} |
| | | {config ? <UrlFieldComponent config={config} updateConfig={this.updateConfig}/> : null} |
| | |
| | | {config ? <Paragraph style={{padding: '15px 0px 0px 18px'}} copyable={{ text: MenuId }}>菜单ID</Paragraph> : null} |
| | | </Panel> |
| | | {/* 组件添加 */} |
| | | <Panel header={dict['mob.component']} key="component"> |
| | | <Panel header={dict['mob.component']} className="component" key="component"> |
| | | <SourceWrap /> |
| | | </Panel> |
| | | {customComponents && customComponents.length ? <Panel header="自定义组件" key="cuscomponent"> |
| | | {customComponents && customComponents.length ? <Panel header="自定义组件" className="cuscomponent" key="cuscomponent"> |
| | | <SourceWrap components={customComponents} /> |
| | | </Panel> : null} |
| | | <Panel header={'页面样式'} key="background"> |
| | |
| | | </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} |
| | | {controlshow ? <DoubleRightOutlined onClick={() => {this.setState({controlshow: false})}}/> : null} |
| | | {!controlshow ? <DoubleLeftOutlined onClick={() => {this.setState({controlshow: true})}}/> : null} |
| | | </div> |
| | | <div className="wrap"> |
| | | <Button type="primary" onClick={this.submitConfig} loading={menuloading}>{dict['mob.save']}</Button> |
| | | <Button type="primary" onClick={this.submitConfig} id="save-config" loading={menuloading}>{dict['mob.save']}</Button> |
| | | <Switch className="big" checkedChildren={dict['mob.enable']} unCheckedChildren={dict['mob.disable']} checked={config && config.enabled} onChange={this.onEnabledChange} /> |
| | | <img title="后退" className="back-view" onClick={this.backView} src={backurl} alt=""/> |
| | | <CreateView resetmenu={this.getAppMenus} /> |
| | | <PasteController 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-purple" icon="login" onClick={this.setLoginView}>设为登录页</Button> |
| | | <Button className="mk-border-green set-home" onClick={this.setHomeView}><HomeOutlined /> 设为首页</Button> |
| | | <Button className="mk-border-purple set-login" onClick={this.setLoginView}><LoginOutlined /> 设为登录页</Button> |
| | | <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/> |
| | | <Transfer MenuID={MenuId} /> |
| | | <Versions MenuId={MenuId} open_edition={config ? config.open_edition : ''}/> |
| | | <Button className="mk-border-danger" icon="redo" onClick={this.refreshView}>强制刷新</Button> |
| | | <Button className="mk-border-danger" onClick={this.refreshView}><RedoOutlined /> 强制刷新</Button> |
| | | <Button type="default" onClick={this.closeView}>关闭</Button> |
| | | </div> |
| | | </div> |