| | |
| | | import React, { Component } from 'react' |
| | | import { connect } from 'react-redux' |
| | | import { DndProvider } from 'react-dnd' |
| | | import { withRouter } from 'react-router' |
| | | import { is, fromJS } from 'immutable' |
| | |
| | | |
| | | const MenuForm = asyncComponent(() => import('./menuform')) |
| | | const Transfer = asyncComponent(() => import('@/pc/transfer')) |
| | | const PopviewController = asyncComponent(() => import('@/menu/popview')) |
| | | const Versions = asyncComponent(() => import('@/menu/versions')) |
| | | const MenuShell = asyncComponent(() => import('@/pc/menushell')) |
| | | const ViewNodes = asyncComponent(() => import('@/menu/viewnodes')) |
| | |
| | | const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent')) |
| | | |
| | | sessionStorage.setItem('isEditState', 'true') |
| | | sessionStorage.setItem('editMenuType', 'menu') // 编辑菜单类型 |
| | | |
| | | sessionStorage.setItem('appType', 'pc') // 应用类型 |
| | | sessionStorage.setItem('typename', 'pc') |
| | | document.body.className = '' |
| | | window.GLOB.UserComponentMap = new Map() // 缓存用户自定义组件 |
| | | window.GLOB.TabsMap = new Map() // 缓存用户操作的标签页 |
| | | window.GLOB.CacheIndependent = new Map() |
| | | window.GLOB.urlFields = [] // url变量 |
| | | window.GLOB.customMenu = null // 保存菜单信息 |
| | | |
| | | const memberLevel = Utils.getMemberLevel() |
| | | |
| | | class MenuDesign extends Component { |
| | | state = { |
| | |
| | | MenuNo: '', |
| | | delButtons: [], |
| | | copyButtons: [], |
| | | thawButtons: [], |
| | | activeKey: 'basedata', |
| | | menuloading: false, |
| | | oriConfig: null, |
| | | config: null, |
| | | popBtn: null, // 弹窗标签页 |
| | | visible: false, |
| | | customComponents: [], |
| | | settingshow: sessionStorage.getItem('settingshow') !== 'false', |
| | | controlshow: sessionStorage.getItem('controlshow') !== 'false', |
| | | comloading: false, |
| | | eyeopen: false |
| | | eyeopen: false, |
| | | modalStatus: false // 弹窗是否开启,判断ctrl+s是否可用 |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | | if (this.props.memberLevel < 30) return |
| | | if (memberLevel < 30) return |
| | | |
| | | sessionStorage.setItem('editMenuType', 'menu') // 编辑菜单类型 |
| | | |
| | | window.GLOB.UserComponentMap = new Map() // 缓存用户自定义组件 |
| | | window.GLOB.TabsMap = new Map() // 缓存用户操作的标签页 |
| | | window.GLOB.CacheIndependent = new Map() |
| | | window.GLOB.urlFields = [] // url变量 |
| | | window.GLOB.customMenu = null // 保存菜单信息 |
| | | |
| | | try { |
| | | let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param))) |
| | | |
| | |
| | | } |
| | | |
| | | componentDidMount () { |
| | | if (this.props.memberLevel < 30) { |
| | | if (memberLevel < 30) { |
| | | document.getElementById('mk-pc-design-view').innerHTML = '<div style="text-align: center; font-size: 30px; margin-top: 40vh; height: 100vh; background: #fff;">本应用没有PC端页面的编辑权限,请联系管理员!</div>' |
| | | return |
| | | } |
| | | MKEmitter.addListener('delButtons', this.delButtons) |
| | | MKEmitter.addListener('thawButtons', this.thawButtons) |
| | | MKEmitter.addListener('modalStatus', this.modalStatus) |
| | | MKEmitter.addListener('copyButtons', this.copyButtons) |
| | | MKEmitter.addListener('changePopview', this.initPopview) |
| | | MKEmitter.addListener('changeEditMenu', this.changeEditMenu) |
| | |
| | | MKEmitter.addListener('submitComponentStyle', this.updateComponentStyle) |
| | | MKEmitter.addListener('updateCustomComponent', this.updateCustomComponent) |
| | | setTimeout(() => { |
| | | if (sessionStorage.getItem('app_custom_components')) { |
| | | let list = sessionStorage.getItem('app_custom_components') |
| | | list = JSON.parse(list) |
| | | |
| | | this.setCustomComponent(list) |
| | | } else { |
| | | this.updateCustomComponent() |
| | | } |
| | | this.getAppPictures() |
| | | this.getSmStemp() |
| | | this.getRoleFields() |
| | | setGLOBFuncs() |
| | | }, 1000) |
| | | |
| | |
| | | let _shortcut = `${preKey}+${keyCode}` |
| | | |
| | | if (_shortcut === 'ctrl+83') { |
| | | if (this.state.modalStatus) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请保存' + this.state.modalStatus, |
| | | duration: 5 |
| | | }) |
| | | return false |
| | | } |
| | | |
| | | let node = document.getElementById('save-modal-config') |
| | | if (!node) { |
| | | node = document.getElementById('save-pop-config') |
| | |
| | | return |
| | | } |
| | | MKEmitter.removeListener('delButtons', this.delButtons) |
| | | MKEmitter.removeListener('thawButtons', this.thawButtons) |
| | | MKEmitter.removeListener('modalStatus', this.modalStatus) |
| | | MKEmitter.removeListener('copyButtons', this.copyButtons) |
| | | MKEmitter.removeListener('changePopview', this.initPopview) |
| | | MKEmitter.removeListener('changeEditMenu', this.changeEditMenu) |
| | |
| | | MKEmitter.removeListener('updateCustomComponent', this.updateCustomComponent) |
| | | } |
| | | |
| | | triggerMenuSave = () => { |
| | | if (this.state.visible) return |
| | | modalStatus = (val) => { |
| | | this.setState({modalStatus: val}) |
| | | } |
| | | |
| | | triggerMenuSave = () => { |
| | | this.submitConfig() |
| | | } |
| | | |
| | |
| | | type: 'view' |
| | | } |
| | | |
| | | param.MenuNo = menu.MenuNo || '' |
| | | // param.MenuNo = menu.MenuNo || '' |
| | | param.MenuName = menu.MenuName || '' |
| | | |
| | | param = window.btoa(window.encodeURIComponent(JSON.stringify(param))) |
| | |
| | | typename: 'pc', |
| | | typecharone: '' |
| | | }).then(res => { |
| | | let coms = [] |
| | | if (!res.status) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | } else if (res.cus_list && res.cus_list.length > 0) { |
| | | res.cus_list.forEach(item => { |
| | | } else if (res.cus_list) { |
| | | sessionStorage.setItem('app_custom_components', JSON.stringify(res.cus_list)) |
| | | this.setCustomComponent(res.cus_list) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | setCustomComponent = (cus_list) => { |
| | | let coms = [] |
| | | |
| | | cus_list.forEach(item => { |
| | | let config = '' |
| | | |
| | | try { |
| | |
| | | url: item.images, |
| | | component: config.type, |
| | | subtype: config.subtype, |
| | | width: config.width || 24, |
| | | config |
| | | }) |
| | | }) |
| | | } |
| | | this.setState({customComponents: coms}) |
| | | this.getRoleFields() |
| | | }) |
| | | } |
| | | |
| | | handleBack = () => { |
| | | this.setState({popBtn: null, delButtons: [], copyButtons: [], thawButtons: []}, () => { |
| | | sessionStorage.setItem('editMenuType', 'menu') |
| | | window.GLOB.customMenu = this.state.config |
| | | this.setState({visible: false}) |
| | | }) |
| | | } |
| | | |
| | | updateComponentStyle = (parentId, keys, style) => { |
| | |
| | | this.setState({copyButtons: [...this.state.copyButtons, ...items]}) |
| | | } |
| | | |
| | | thawButtons = (item) => { |
| | | this.setState({thawButtons: [...this.state.thawButtons, item]}) |
| | | } |
| | | |
| | | initPopview = (card, btn) => { |
| | | const { oriConfig, config } = this.state |
| | | |
| | |
| | | return |
| | | } |
| | | |
| | | btn.config = fromJS(config).toJS() |
| | | btn.component = card |
| | | let _btn = fromJS(btn).toJS() |
| | | _btn.MenuName = config.MenuName + '-' + card.name + '-' + btn.label |
| | | _btn.ParentMenuID = config.uuid |
| | | |
| | | sessionStorage.setItem('editMenuType', 'popview') // 编辑弹窗标签 |
| | | |
| | | this.setState({popBtn: btn, visible: true}) |
| | | this.props.history.push('/popdesign/' + window.btoa(window.encodeURIComponent((JSON.stringify(_btn))))) |
| | | } |
| | | |
| | | closeView = () => { |
| | |
| | | Template: 'webPage', |
| | | enabled: false, |
| | | MenuName: urlParam.MenuName || '', |
| | | MenuNo: urlParam.MenuNo || '', |
| | | MenuNo: '', |
| | | tables: [], |
| | | components: [], |
| | | viewType: 'menu', |
| | |
| | | config.MenuID = MenuId |
| | | config.open_edition = '' |
| | | config.MenuName = urlParam.MenuName || '' |
| | | config.MenuNo = urlParam.MenuNo || '' |
| | | config.MenuNo = '' |
| | | |
| | | let indeComs = [] |
| | | config.components.forEach(item => { |
| | |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.hidden === 'true') return |
| | | |
| | | this.checkBtn(btn) |
| | | m.children.push({ |
| | | key: btn.uuid, |
| | | title: btn.label, |
| | |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') return |
| | | |
| | | this.checkBtn(cell) |
| | | m.children.push({ |
| | | key: cell.uuid, |
| | | title: cell.label, |
| | |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') return |
| | | |
| | | this.checkBtn(cell) |
| | | m.children.push({ |
| | | key: cell.uuid, |
| | | title: cell.label, |
| | |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') return |
| | | |
| | | this.checkBtn(cell) |
| | | m.children.push({ |
| | | key: cell.uuid, |
| | | title: cell.label, |
| | |
| | | if (cell.eleType !== 'button') return |
| | | if (cell.hidden === 'true') return |
| | | |
| | | this.checkBtn(cell) |
| | | m.children.push({ |
| | | key: cell.uuid, |
| | | title: cell.label, |
| | |
| | | } |
| | | }) |
| | | } else if (item.type === 'form') { |
| | | if (item.subtype !== 'simpleform') { |
| | | m.children = item.subcards.map(m => { |
| | | return { |
| | | key: m.uuid, |
| | | title: m.setting.title |
| | | } |
| | | }) |
| | | } |
| | | } else if (item.type === 'table' && (item.subtype === 'normaltable' || item.subtype === 'editable')) { |
| | | item.action && item.action.forEach(btn => { |
| | | if (btn.hidden === 'true') return |
| | | |
| | | this.checkBtn(btn) |
| | | m.children.push({ |
| | | key: btn.uuid, |
| | | title: btn.label, |
| | |
| | | col.elements.forEach(btn => { |
| | | if (btn.hidden === 'true') return |
| | | |
| | | this.checkBtn(btn) |
| | | m.children.push({ |
| | | key: btn.uuid, |
| | | title: btn.label, |
| | |
| | | nodes.login = true |
| | | nodes.children = [] |
| | | } |
| | | if (config.permission !== 'true') { |
| | | if (nodes.children.length === 0) { |
| | | nodes.pass = true |
| | | nodes.children = [] |
| | | } |
| | | |
| | | return nodes |
| | | } |
| | | |
| | | 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 |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | |
| | | getSubMenus = () => { |
| | |
| | | } |
| | | |
| | | submitConfig = () => { |
| | | const { delButtons, copyButtons, thawButtons } = this.state |
| | | const { delButtons, copyButtons } = this.state |
| | | let config = fromJS(this.state.config).toJS() |
| | | |
| | | if (!config.MenuName || !config.MenuNo || (config.cacheUseful === 'true' && !config.cacheTime)) { |
| | |
| | | } |
| | | return Api.getSystemConfig(_param) |
| | | } |
| | | }).then(res => { // 按钮解除冻结 |
| | | if (!res) return |
| | | if (!res.status) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | return false |
| | | } else if (!res.nonexec) { // 执行删除后刷新菜单列表 |
| | | this.getAppMenus() |
| | | } |
| | | |
| | | if (thawButtons.length === 0) { |
| | | return { status: true } |
| | | } else { |
| | | return Api.getSystemConfig({ |
| | | func: 'sPC_MainMenu_ReDel', |
| | | MenuID: thawButtons.join(',') |
| | | }) |
| | | } |
| | | }).then(res => { // 页面保存 |
| | | if (!res) return |
| | | |
| | |
| | | this.setState({ |
| | | delButtons: [], |
| | | copyButtons: [], |
| | | thawButtons: [], |
| | | menuloading: false |
| | | }) |
| | | notification.success({ |
| | |
| | | } |
| | | MKEmitter.emit('completeSave') |
| | | }) |
| | | }, 300) |
| | | }, 300 + (+sessionStorage.getItem('mkDelay'))) |
| | | } |
| | | |
| | | getRoleFields = () => { |
| | |
| | | } else if (item.type === 'group') { |
| | | check(item.components) |
| | | return |
| | | } 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 = '登录组件未设置关联菜单!' |
| | | } else if (!item.errors || item.errors.length === 0) { |
| | | return |
| | | } |
| | | |
| | | if (['voucher'].includes(item.subtype)) return |
| | | if (['propcard', 'brafteditor', 'sandbox', 'stepform', 'tabform'].includes(item.subtype) && item.wrap.datatype === 'static') return |
| | | if (['balcony'].includes(item.type) && 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.primaryKey) { |
| | | error = `组件《${item.name}》未设置主键!` |
| | | } else if (!item.setting.supModule && item.type !== 'balcony' && (!item.wrap || item.wrap.supType !== 'multi')) { |
| | | error = `组件《${item.name}》未设置上级组件!` |
| | | } |
| | | } |
| | | if (item.type === 'bar' || item.type === 'line' || item.type === 'pie') { |
| | | if (!item.plot.Xaxis) { |
| | | error = `组件《${item.name}》图表字段尚未设置!` |
| | | } |
| | | } else if (item.type === 'dashboard' && !item.plot.valueField) { |
| | | error = `组件《${item.name}》显示值尚未设置!` |
| | | } else if (item.type === 'scatter' && (!item.plot.Xaxis || !item.plot.Yaxis || !item.plot.gender)) { |
| | | error = `组件《${item.name}》坐标轴尚未设置!` |
| | | } else if (item.type === 'tree' && (!item.wrap.valueField || !item.wrap.labelField || !item.wrap.parentField)) { |
| | | error = `组件《${item.name}》基本信息尚未设置!` |
| | | } else if (item.type === 'table' && item.wrap.doubleClick) { |
| | | let _actions = [...item.action] |
| | | item.cols.forEach(col => { |
| | | if (col.type !== 'action') return |
| | | _actions.push(...col.elements) |
| | | item.errors.forEach(err => { |
| | | if (err.level !== 0 || error) return |
| | | error = `组件《${item.name}》${err.detail}` |
| | | }) |
| | | if (_actions.findIndex((m) => m.uuid === item.wrap.doubleClick) === -1) { |
| | | error = `组件《${item.name}》绑定的双击按钮已删除!` |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | render () { |
| | | const { localedict, loading, visible, popBtn, comloading, activeKey, settingshow, controlshow, dict, MenuId, config, menuloading, customComponents, eyeopen } = this.state |
| | | const { localedict, loading, comloading, activeKey, settingshow, controlshow, dict, MenuId, config, menuloading, customComponents, eyeopen } = this.state |
| | | |
| | | return ( |
| | | <ConfigProvider locale={localedict}> |
| | | <div className={'mk-pc-view '} id="mk-pc-design-view"> |
| | | {loading ? <Spin className="view-spin" size="large" /> : null} |
| | | {!popBtn && !visible ? <DndProvider backend={HTML5Backend}> |
| | | <DndProvider backend={HTML5Backend}> |
| | | <div className={'menu-setting ' + (!settingshow ? 'hidden' : '')}> |
| | | <div className="draw"> |
| | | {settingshow ? <DoubleLeftOutlined onClick={() => {sessionStorage.setItem('settingshow', 'false'); this.setState({settingshow: false})}}/> : null} |
| | |
| | | <div className="pc-setting-tools"> |
| | | <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}> |
| | | {/* 基本信息 */} |
| | | <Panel header={dict['mob.basemsg']} key="basedata"> |
| | | <Panel header="基本信息" key="basedata"> |
| | | {/* 菜单信息 */} |
| | | {config ? <MenuForm |
| | | dict={dict} |
| | |
| | | <div className={'menu-body menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}> |
| | | {config && !comloading ? <MenuShell menu={config} handleList={this.updateConfig} /> : null} |
| | | </div> |
| | | </DndProvider> : null} |
| | | {popBtn && visible ? <PopviewController btn={popBtn} handleBack={this.handleBack}/> : null} |
| | | </DndProvider> |
| | | <StyleController /> |
| | | <StyleCombController /> |
| | | <ModalController /> |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | memberLevel: state.memberLevel |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default withRouter(connect(mapStateToProps, mapDispatchToProps)(MenuDesign)) |
| | | export default withRouter(MenuDesign) |