From b8aa5da1b2873bea760483cc5ab335fde9fb6de6 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期四, 12 五月 2022 18:15:56 +0800
Subject: [PATCH] 2022-05-12

---
 src/views/mobdesign/index.jsx |  487 +++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 447 insertions(+), 40 deletions(-)

diff --git a/src/views/mobdesign/index.jsx b/src/views/mobdesign/index.jsx
index f6106f5..f2fdb32 100644
--- a/src/views/mobdesign/index.jsx
+++ b/src/views/mobdesign/index.jsx
@@ -6,7 +6,7 @@
 import moment from 'moment'
 import HTML5Backend from 'react-dnd-html5-backend'
 import { ConfigProvider, notification, Modal, Collapse, Switch, Button, message, Spin, Typography } from 'antd'
-import { DoubleLeftOutlined, DoubleRightOutlined, HomeOutlined, LoginOutlined, RedoOutlined } from '@ant-design/icons'
+import { DoubleLeftOutlined, DoubleRightOutlined, HomeOutlined, LoginOutlined, RedoOutlined, ArrowLeftOutlined, EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'
 
 import Api from '@/api'
 import Utils, { setGLOBFuncs } from '@/utils/utils.js'
@@ -30,6 +30,7 @@
 const CreateView = asyncComponent(() => import('@/pc/createview'))
 const Transfer = asyncComponent(() => import('@/pc/transfer'))
 const Versions = asyncComponent(() => import('@/menu/versions'))
+const ViewNodes = asyncComponent(() => import('@/menu/viewnodes'))
 const SourceWrap = asyncComponent(() => import('@/mob/modulesource'))
 const BgController = asyncComponent(() => import('@/pc/bgcontroller'))
 const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
@@ -72,7 +73,9 @@
     settingshow: true,
     controlshow: true,
     comloading: false,
-    adapters: []
+    adapters: [],
+    viewType: 'menu',
+    eyeopen: false
   }
 
   UNSAFE_componentWillMount() {
@@ -89,6 +92,8 @@
         sessionStorage.setItem('typename', param.typename || 'mob')
         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,
@@ -117,9 +122,11 @@
 
         this.setState({
           adapters,
-          MenuId: param.MenuID
+          MenuId: param.MenuID,
+          viewType: /^userbind/.test(param.MenuID) ? 'userbind' : 'menu'
         }, () => {
           this.getMenuParam(param)
+          this.getRelationMenus()
         })
       }
     } catch (e) {
@@ -156,6 +163,37 @@
       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
+      }
+    }
   }
 
   /**
@@ -214,11 +252,22 @@
         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 = {
       MenuID: menu.MenuID,
       copyMenuId: menu.copyMenuId || '',
+      clearMenu: menu.clearMenu !== 'false',
       type: 'view'
     }
 
@@ -406,10 +455,7 @@
 
     if (!config) {
       window.close()
-      return
-    }
-
-    if (!oriConfig || !is(fromJS(oriConfig), fromJS(config))) {
+    } else if (!oriConfig || !is(fromJS(oriConfig), fromJS(config))) {
       confirm({
         title: '閰嶇疆淇℃伅鏈繚瀛橈紝纭畾鍏抽棴鍚楋紵',
         content: '',
@@ -420,6 +466,25 @@
       })
     } 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()
     }
   }
 
@@ -453,6 +518,11 @@
         } catch (e) {
           console.warn('Parse Failure')
           config = null
+        }
+
+        if (/^userbind/.test(MenuId)) {
+          this.setUserBindMenu(config, result)
+          return
         }
 
         if (!config) {
@@ -503,6 +573,111 @@
     this.getAppMenus()
   }
 
+  getRelationMenus = () => {
+    const { MenuId } = this.state
+    
+    let param = {
+      func: 's_get_menu_used_list',
+      TypeCharOne: sessionStorage.getItem('kei_no'),
+      typename: sessionStorage.getItem('typename'),
+      par_menuid: MenuId,
+      // used_menuid: MenuId
+    }
+
+    Api.getSystemConfig(param).then(result => {
+      if (!result.status) {
+        notification.warning({
+          top: 92,
+          message: result.message,
+          duration: 5
+        })
+        return
+      }
+    })
+  }
+
+  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',
@@ -528,6 +703,13 @@
       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 => {
         item.value = item.MenuID
@@ -535,6 +717,7 @@
         return item
       })
       sessionStorage.setItem('appMenus', JSON.stringify(menus))
+      sessionStorage.setItem('allMenus', JSON.stringify(res.menus || []))
     })
   }
 
@@ -592,7 +775,7 @@
           }
         }
       } else {
-        config.components = MenuUtils.resetConfig(config.components)
+        config.components = MenuUtils.resetConfig(config.components, {}, urlParam.clearMenu)
         config.enabled = false
         message.success('澶嶅埗鎴愬姛锛屼繚瀛樺悗鐢熸晥銆�')
       }
@@ -701,36 +884,62 @@
     const { config } = this.state
     
     let traversal = (components) => {
-      let list = components.map(item => {
+      let list = []
+      components.forEach(item => {
         let m = {
           key: item.uuid,
           title: item.name,
           children: []
         }
 
-        if (item.type === 'topbar' || item.type === 'login' || item.type === 'navbar') {
+        if (item.type === 'topbar' || item.type === 'login' || item.type === 'navbar' || (item.type === 'menubar' && item.subtype === 'commonbar')) {
           return null
         } else if (item.type === 'tabs') {
           let tabs = []
+          let mm = []
           item.subtabs.forEach(tab => {
             let s = traversal(tab.components)
 
             if (s.length === 0) return
-
+            
             tabs.push({
               key: tab.uuid,
               title: tab.label,
               children: s
             })
+
+            mm.push(...s)
           })
 
           if (tabs.length > 0) {
             m.children = tabs
           }
+
+          if (item.setting.permission === 'true') {
+            list.push(m)
+          } else if (mm.length) {
+            list.push(...mm)
+          }
+          
+          return null
         } else if (item.type === 'group') {
           m.children = traversal(item.components)
+
+          if (item.setting.permission === 'true') {
+            list.push(m)
+          } else if (m.children.length) {
+            list.push(...m.children)
+          }
+          
+          return null
+        } if (item.plot && item.plot.permission !== 'true') {
+          return null
+        } if (item.wrap && item.wrap.permission !== 'true') {
+          return null
         } else if (item.type === 'card' || (item.type === 'table' && item.subtype === 'tablecard')) {
           item.action && item.action.forEach(btn => {
+            if (btn.hidden === 'true') return
+
             this.checkBtn(btn)
             m.children.push({
               key: btn.uuid,
@@ -740,6 +949,8 @@
           item.subcards.forEach(card => {
             card.elements && card.elements.forEach(cell => {
               if (cell.eleType !== 'button') return
+              if (cell.hidden === 'true') return
+
               this.checkBtn(cell)
               m.children.push({
                 key: cell.uuid,
@@ -751,6 +962,8 @@
           item.subcards.forEach(card => {
             card.elements && card.elements.forEach(cell => {
               if (cell.eleType !== 'button') return
+              if (cell.hidden === 'true') return
+
               this.checkBtn(cell)
               m.children.push({
                 key: cell.uuid,
@@ -761,6 +974,8 @@
         } else if (item.type === 'balcony') {
           item.elements && item.elements.forEach(cell => {
             if (cell.eleType !== 'button') return
+            if (cell.hidden === 'true') return
+
             this.checkBtn(cell)
             m.children.push({
               key: cell.uuid,
@@ -787,6 +1002,8 @@
           })
         } else if (item.type === 'table' && item.subtype === 'normaltable') {
           item.action && item.action.forEach(btn => {
+            if (btn.hidden === 'true') return
+
             this.checkBtn(btn)
             m.children.push({
               key: btn.uuid,
@@ -796,6 +1013,8 @@
           item.cols && item.cols.forEach(col => {
             if (col.type !== 'action') return
             col.elements.forEach(btn => {
+              if (btn.hidden === 'true') return
+
               this.checkBtn(btn)
               m.children.push({
                 key: btn.uuid,
@@ -805,10 +1024,8 @@
           })
         }
 
-        return m
+        list.push(m)
       })
-
-      list = list.filter(Boolean)
 
       return list
     }
@@ -816,6 +1033,148 @@
     let trees = traversal(config.components)
 
     return trees
+  }
+
+  getSubMenus = () => {
+    const { config } = this.state
+    let menus = []
+    let menuObj = {}
+    let allMenus = JSON.parse(sessionStorage.getItem('allMenus'))
+
+    allMenus.forEach(item => {
+      menuObj[item.MenuID] = item
+    })
+
+    let traversal = (components) => {
+      components.forEach(item => {
+        if (item.type === 'topbar') {
+          if (item.wrap.linkmenu && menuObj[item.wrap.linkmenu]) {
+            menus.push(menuObj[item.wrap.linkmenu])
+          }
+          if (item.wrap.menus) {
+            item.wrap.menus.forEach(m => {
+              if (!menuObj[m.menu]) return
+
+              menus.push(menuObj[m.menu])
+            })
+          }
+        } else if (item.type === 'login') {
+          if (item.wrap.linkmenu && menuObj[item.wrap.linkmenu]) {
+            menus.push(menuObj[item.wrap.linkmenu])
+          }
+        } else if (item.type === 'menubar' && item.subtype !== 'commonbar') {
+          item.subMenus.forEach(m => {
+            if (m.setting.type === 'menu') {
+              if (menuObj[m.uuid]) {
+                menus.push(menuObj[m.uuid])
+              } else {
+                menus.push({
+                  MenuID: m.uuid,
+                  MenuName: m.setting.name,
+                  MenuNo: m.setting.MenuNo
+                })
+              }
+            } else if (m.setting.type === 'linkmenu' && menuObj[m.setting.linkMenuId]) {
+              menus.push(menuObj[m.setting.linkMenuId])
+            }
+          })
+        } else 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 => {
+            if (btn.linkmenu && menuObj[btn.linkmenu]) {
+              menus.push(menuObj[btn.linkmenu])
+            } else if (btn.openmenu && menuObj[btn.openmenu]) {
+              menus.push(menuObj[btn.openmenu])
+            }
+          })
+          item.subcards.forEach(card => {
+            if (card.setting.click === 'menu' && menuObj[card.setting.menu]) {
+              menus.push(menuObj[card.setting.menu])
+            } else if (card.setting.click === 'menus' && card.menus) {
+              card.menus.forEach(m => {
+                if (menuObj[m.menu]) {
+                  menus.push(menuObj[m.menu])
+                }
+              })
+            }
+            card.elements && card.elements.forEach(cell => {
+              if (cell.eleType !== 'button') return
+
+              if (cell.linkmenu && menuObj[cell.linkmenu]) {
+                menus.push(menuObj[cell.linkmenu])
+              } else if (cell.openmenu && menuObj[cell.openmenu]) {
+                menus.push(menuObj[cell.openmenu])
+              }
+            })
+          })
+        } else if (item.type === 'carousel' || item.type === 'timeline') {
+          item.subcards.forEach(card => {
+            if (card.setting.click === 'menu' && menuObj[card.setting.menu]) {
+              menus.push(menuObj[card.setting.menu])
+            }
+            card.elements && card.elements.forEach(cell => {
+              if (cell.eleType !== 'button') return
+
+              if (cell.linkmenu && menuObj[cell.linkmenu]) {
+                menus.push(menuObj[cell.linkmenu])
+              } else if (cell.openmenu && menuObj[cell.openmenu]) {
+                menus.push(menuObj[cell.openmenu])
+              }
+            })
+          })
+        } else if (item.type === 'balcony') {
+          item.elements && item.elements.forEach(cell => {
+            if (cell.eleType !== 'button') return
+
+            if (cell.linkmenu && menuObj[cell.linkmenu]) {
+                menus.push(menuObj[cell.linkmenu])
+              } else if (cell.openmenu && menuObj[cell.openmenu]) {
+                menus.push(menuObj[cell.openmenu])
+              }
+          })
+        } else if (item.type === 'form') {
+          item.subcards.forEach(m => {
+            if (m.subButton && m.subButton.linkmenu && menuObj[m.subButton.linkmenu]) {
+              menus.push(menuObj[m.subButton.linkmenu])
+            }
+          })
+        } else if (item.type === 'table' && item.subtype === 'normaltable') {
+          item.action && item.action.forEach(btn => {
+            if (btn.linkmenu && menuObj[btn.linkmenu]) {
+              menus.push(menuObj[btn.linkmenu])
+            } else if (btn.openmenu && menuObj[btn.openmenu]) {
+              menus.push(menuObj[btn.openmenu])
+            }
+          })
+          item.cols && item.cols.forEach(col => {
+            if (col.type !== 'action') return
+            col.elements.forEach(btn => {
+              if (btn.linkmenu && menuObj[btn.linkmenu]) {
+                menus.push(menuObj[btn.linkmenu])
+              } else if (btn.openmenu && menuObj[btn.openmenu]) {
+                menus.push(menuObj[btn.openmenu])
+              }
+            })
+          })
+        }
+      })
+    }
+
+    traversal(config.components)
+
+    let map = new Map()
+    menus = menus.filter(m => {
+      if (map.has(m.MenuID)) return false
+      map.set(m.MenuID, true)
+      return true
+    })
+
+    return menus
   }
 
   checkBtn = (btn) => {
@@ -945,19 +1304,33 @@
         config.enabled = false
       }
 
-      let roleParam = {type: 'view', key: config.uuid, title: config.MenuName, children: []}
+      let roleParam = {type: 'view', version: '1.0', key: config.uuid, title: config.MenuName, children: []}
       roleParam.children = this.getMenuMessage()
+      config.loginview = false
+      config.tabview = false
 
-      if (config.components.findIndex(item => item.type === 'login') > -1) {
-        roleParam.login = true
-        config.loginview = true
-      } else {
-        config.loginview = false
+      if (config.permission !== 'true') {
+        roleParam.pass = true
+        roleParam.children = []
       }
+
+      config.components.forEach(item => {
+        if (item.type === 'login') {
+          roleParam.login = true
+          roleParam.children = []
+          config.loginview = true
+        } else if (item.type === 'navbar') {
+          config.tabview = true
+        }
+      })
 
       if (adapters.includes('wxmini')) {
         config = this.getMiniStyle(config)
       }
+
+      let subMenus = this.getSubMenus()
+      let menus_used_list = subMenus.map(m => `'${config.uuid}','${config.MenuName || ''}','${config.MenuNo || ''}','${m.MenuID}','${m.MenuName}'`).join(';')
+      menus_used_list = window.btoa(window.encodeURIComponent(menus_used_list || 'del'))
 
       let param = {
         func: 'sPC_TrdMenu_AddUpt',
@@ -975,7 +1348,8 @@
         open_edition: config.open_edition,
         menus_rolelist: window.btoa(window.encodeURIComponent(JSON.stringify(roleParam))),
         LText: '',
-        LTexttb: ''
+        LTexttb: '',
+        menus_used_list
       }
 
       param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
@@ -1012,17 +1386,22 @@
 
               let roles = {
                 type: 'navbar',
+                version: '1.0',
                 key: item.uuid,
                 title: item.name,
                 children: []
               }
       
-              roles.children = item.menus.map(menu => {
-                return {
-                  key: menu.MenuID,
-                  title: menu.name
-                }
-              })
+              if (item.wrap.permission === 'true') {
+                roles.children = item.menus.map(menu => {
+                  return {
+                    key: menu.MenuID,
+                    title: menu.name
+                  }
+                })
+              } else {
+                roles.pass = true
+              }
 
               let _param = {
                 func: 'sPC_TrdMenu_AddUpt',
@@ -1236,11 +1615,18 @@
           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 (['voucher'].includes(item.subtype)) return
         if (['propcard', 'brafteditor', 'sandbox', 'tabbar', 'stepform', 'tabform'].includes(item.subtype) && item.wrap.datatype === 'static') return
         if (['balcony'].includes(item.type) && item.wrap.datatype === 'static') return
         if (['menubar'].includes(item.type) && item.wrap.datatype !== 'dynamic') return
@@ -1269,6 +1655,10 @@
     }
 
     check(config.components)
+
+    // if (!error && viewType === 'userbind' && config.components.filter(item => item.type === 'login').length === 0) {
+    //   error = '鐢ㄦ埛缁戝畾椤甸潰蹇呴』娣诲姞鐧诲綍銆�'
+    // }
 
     if (!error && searchSum > 1) {
       error = '鎼滅储缁勪欢涓庡鑸爮鐨勬悳绱㈠姛鑳戒笉鍙悓鏃朵娇鐢ㄣ��'
@@ -1299,13 +1689,27 @@
   insert = (item) => {
     let config = fromJS(this.state.config).toJS()
 
-    if (item.type === 'topbar' && config.components.findIndex(m => m.type === 'topbar') > -1) {
+    if (item.type === 'search') {
       notification.warning({
         top: 92,
-        message: '瀵艰埅鏍忎笉鍙噸澶嶆坊鍔狅紒',
+        message: '绉诲姩绔悳绱㈢粍浠朵笉鍙矘璐达紒',
         duration: 5
       })
       return
+    }
+    
+    if (item.type === 'topbar') {
+      if (config.components.findIndex(m => m.type === 'topbar') > -1) {
+        notification.warning({
+          top: 92,
+          message: '瀵艰埅鏍忎笉鍙噸澶嶆坊鍔狅紒',
+          duration: 5
+        })
+        return
+      }
+      if (!config.style.paddingTop) {
+        config.style.paddingTop = '50px'
+      }
     }
 
     config.components.push(item)
@@ -1496,11 +1900,11 @@
 
 
   render () {
-    const { localedict, comloading, loading, settingshow, controlshow, activeKey, dict, MenuId, config, menuloading, customComponents, adapters } = this.state
+    const { viewType, localedict, comloading, loading, settingshow, controlshow, activeKey, dict, MenuId, config, menuloading, customComponents, adapters, eyeopen } = 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}>
@@ -1512,7 +1916,7 @@
               <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}
@@ -1527,10 +1931,10 @@
                     {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">
@@ -1539,30 +1943,33 @@
                 </Collapse>
               </div>
             </div>
-            <div className={'menu-control ' + (!controlshow ? 'hidden' : '')}>
+            <div className={'menu-control' + (!controlshow ? ' hidden' : '')}>
               <div className="draw">
                 {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} />
+                <ArrowLeftOutlined title="鍚庨��" className="back-view" onClick={this.backView}/>
+                <Button className="mk-border-purple" onClick={() => this.setState({eyeopen: !eyeopen})}>{!eyeopen ? <EyeOutlined /> : <EyeInvisibleOutlined />} 缁勪欢鍚�</Button>
                 <CreateView resetmenu={this.getAppMenus} />
                 <PasteController insert={this.insert} />
-                <StyleCombControlButton menu={config} />
+                <ViewNodes config={config} MenuId={MenuId}/>
                 <SysInterface config={config} updateConfig={this.updateConfig}/>
                 <PictureController/>
                 <Quotecomponent config={config} updateConfig={this.updateConfig}/>
-                <Button className="mk-border-green" onClick={this.setHomeView}><HomeOutlined /> 璁句负棣栭〉</Button>
-                <Button className="mk-border-purple" onClick={this.setLoginView}><LoginOutlined /> 璁句负鐧诲綍椤�</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 : ''}/>
+                <StyleCombControlButton menu={config} />
                 <Button className="mk-border-danger" onClick={this.refreshView}><RedoOutlined /> 寮哄埗鍒锋柊</Button>
                 <Button type="default" onClick={this.closeView}>鍏抽棴</Button>
               </div>
             </div>
-            <div className={'menu-body menu-view' + (menuloading ? 'saving' : '')}>
+            <div className={'menu-body menu-view' + (menuloading ? ' saving' : '') + (eyeopen ? ' eye-open' : '')}>
               {config && !comloading ? <div className="mob-shell" style={{width: window.GLOB.shellWidth, height: window.GLOB.shellHeight}}>
                 <MobShell menu={config} handleList={this.updateConfig} />
               </div> : null}

--
Gitblit v1.8.0