From 365ea069f179ee71a7a8cc7785ccd2d86bd4881c Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期三, 03 二月 2021 18:33:45 +0800
Subject: [PATCH] 2021-02-03

---
 src/components/tabview/index.jsx                           |   14 
 src/components/tabview/index.scss                          |    2 
 src/templates/sharecomponent/settingcomponent/index.jsx    |    7 
 src/views/design/index.jsx                                 |   29 
 src/views/design/header/index.scss                         |  207 ++++
 src/assets/css/viewstyle.scss                              |  160 ++-
 src/views/design/header/index.jsx                          |  388 +++++++
 src/components/header/index.jsx                            |  278 +----
 src/components/sidemenu/index.scss                         |   12 
 src/tabviews/zshare/normalTable/index.jsx                  |    6 
 src/templates/formtabconfig/index.jsx                      |   11 
 src/views/main/index.jsx                                   |    3 
 src/templates/menuconfig/editsecmenu/index.scss            |    2 
 src/views/design/sidemenu/index.scss                       |  119 ++
 src/store/action.js                                        |   15 
 src/tabviews/custom/components/share/normalTable/index.jsx |    4 
 src/views/design/sidemenu/index.jsx                        |  326 ++++++
 src/utils/utils.js                                         |  479 +++++++++
 src/index.js                                               |   12 
 src/views/sso/index.jsx                                    |    6 
 src/components/header/index.scss                           |   30 
 src/views/design/index.scss                                |    5 
 src/menu/components/card/cardcellcomponent/index.jsx       |    2 
 src/store/reducer.js                                       |   23 
 src/components/querylog/index.jsx                          |    3 
 src/store/action-type.js                                   |    6 
 src/views/design/sidemenu/config.jsx                       |   14 
 src/router/index.js                                        |    8 
 src/templates/menuconfig/editfirstmenu/index.scss          |    2 
 src/menu/components/share/actioncomponent/index.jsx        |   19 
 src/store/options.js                                       |   75 
 src/templates/menuconfig/editthdmenu/index.scss            |    2 
 /dev/null                                                  |  459 ---------
 src/templates/sharecomponent/actioncomponent/index.jsx     |   19 
 src/components/sidemenu/index.jsx                          |  218 ----
 src/views/login/index.jsx                                  |    6 
 36 files changed, 1,860 insertions(+), 1,111 deletions(-)

diff --git a/src/assets/css/global.scss b/src/assets/css/global.scss
deleted file mode 100644
index d117c7c..0000000
--- a/src/assets/css/global.scss
+++ /dev/null
@@ -1,59 +0,0 @@
-$header-bg: #2b3643;
-$header-font: #c4c7d0;
-
-$blue: #3190e8;
-$bc: #e4e4e4;
-$fc:#fff;
-$common-left: 0.2rem;
-$common-right: 0.6rem;
-
-// $header-bg: #505771;
-// 鍏冪礌闀垮
-@mixin wh($width, $height) {
-  width: $width;
-  height: $height;
-}
-
-// 瀛椾綋棰滆壊,澶у皬, 姘村钩甯冨眬
-@mixin font($size, $color: #333, $text-align: left){
-  font-size: $size;
-  color: $color;
-  text-align: $text-align;
-}
-
-// flex甯冨眬
-@mixin flex($justify-content: center, $align-items: center) {
-  display: flex;
-  justify-content: $justify-content;
-  align-items: $align-items;
-}
-
-// 榛樿鎸夌収鐖跺厓绱犵殑鍓т腑
-@mixin positionCenter($position: absolute) {
-  position: $position;
-  top: 50%;
-  left: 50%;
-  transform: translate3d(-50%, -50%, 0);
-}
-
-// 榛樿鎸夌収鐖跺厓绱犵殑鍓т腑
-@mixin positionHCenter($position: absolute) {
-  position: $position;
-  top: 50%;
-  transform: translate3d(0, -50%, 0);
-}
-
-@mixin positionLeft($position: absolute, $left: $common-left) {
-  position: $position;
-  top: 50%;
-  left: $left;
-  transform: translate3d(0, -50%, 0);
-}
-
-@mixin positionRight($position: absolute, $right: $common-right) {
-  position: $position;
-  top: 50%;
-  right: $right;
-  transform: translate3d(0, -50%, 0);
-}
-
diff --git a/src/assets/css/viewstyle.scss b/src/assets/css/viewstyle.scss
index 7b2ad40..a4167f4 100644
--- a/src/assets/css/viewstyle.scss
+++ b/src/assets/css/viewstyle.scss
@@ -153,41 +153,7 @@
           }
         }
       }
-      .normal-data-table, .normal-custom-table {
-        table {
-          .ant-table-tbody {
-            > tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td {
-              background-color: $color1;
-            }
-            > tr.ant-table-row-selected:not(.background) td {
-              background-color: $color1;
-            }
-            > tr.ant-table-row-selected:not(.background):hover .ant-table-column-sort {
-              background-color: $color1;
-            }
-            > tr.mk-row-active:not(.background) td {
-              background-color: $color3;
-            }
-            > tr.ant-table-row-selected.mk-row-active:not(.background):hover .ant-table-column-sort {
-              background-color: $color3;
-            }
-          }
-        }
-      }
-      .top-search {
-        >.ant-row {
-          .ant-col.search-button {
-            .ant-btn:not(.ant-btn-primary):active, .ant-btn:not(.ant-btn-primary).active, .ant-btn:not(.ant-btn-primary):hover, .ant-btn:not(.ant-btn-primary):focus {
-              color: $color7;
-              border-color: $color7;
-            }
-            .ant-btn-primary {
-              background-color: $color6;
-              border-color: $color6;
-            }
-          }
-        }
-      }
+
       .ant-tabs-nav .ant-tabs-tab-active {
         color: $color6;
       }
@@ -199,23 +165,6 @@
       }
       .ant-tabs-nav .ant-tabs-tab:hover {
         color: $color5;
-      }
-      .ant-pagination {
-        .ant-pagination-item-active {
-          border-color: $color6;
-          a {
-            color: $color6;
-          }
-        }
-        .ant-pagination-item:hover a {
-          color: $color6;
-        }
-        .ant-pagination-prev:hover .ant-pagination-item-link {
-          color: $color6;
-        }
-        .ant-pagination-next:hover .ant-pagination-item-link {
-          color: $color6;
-        }
       }
     }
   }
@@ -248,6 +197,78 @@
       color: $color5;
     }
   }
+  // 鎼滅储鏍�
+  .top-search {
+    >.ant-row {
+      .ant-col.search-button {
+        .ant-btn:not(.ant-btn-primary):active, .ant-btn:not(.ant-btn-primary).active, .ant-btn:not(.ant-btn-primary):hover, .ant-btn:not(.ant-btn-primary):focus {
+          color: $color7;
+          border-color: $color7;
+        }
+        .ant-btn-primary {
+          background-color: $color6;
+          border-color: $color6;
+        }
+      }
+    }
+  }
+  // 琛ㄦ牸
+  .normal-data-table, .normal-custom-table {
+    table {
+      .ant-table-tbody {
+        > tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td {
+          background-color: $color1;
+        }
+        > tr.ant-table-row-selected:not(.background) td {
+          background-color: $color1;
+        }
+        > tr.ant-table-row-selected:not(.background):hover .ant-table-column-sort {
+          background-color: $color1;
+        }
+        > tr.mk-row-active:not(.background) td {
+          background-color: $color3;
+        }
+        > tr.ant-table-row-selected.mk-row-active:not(.background):hover .ant-table-column-sort {
+          background-color: $color3;
+        }
+      }
+    }
+  }
+  // 寮圭獥鎸夐挳
+  .popview-modal {
+    .ant-modal-footer {
+      .ant-btn:not(.ant-btn-primary):active, .ant-btn:not(.ant-btn-primary).active, .ant-btn:not(.ant-btn-primary):hover, .ant-btn:not(.ant-btn-primary):focus {
+        color: $color7;
+        border-color: $color7;
+      }
+    }
+  }
+  // 琛ㄥ崟寮圭獥
+  .action-modal {
+    .ant-modal-footer {
+      .ant-btn:not(.ant-btn-primary):active, .ant-btn:not(.ant-btn-primary).active, .ant-btn:not(.ant-btn-primary):hover, .ant-btn:not(.ant-btn-primary):focus {
+        color: $color7;
+        border-color: $color7;
+      }
+      .ant-btn-primary {
+        background-color: $color6;
+        border-color: $color6;
+      }
+    }
+  }
+  // 鏄惁妗�
+  .ant-modal-confirm-confirm {
+    .ant-modal-confirm-btns {
+      .ant-btn:not(.ant-btn-primary):active, .ant-btn:not(.ant-btn-primary).active, .ant-btn:not(.ant-btn-primary):hover, .ant-btn:not(.ant-btn-primary):focus {
+        color: $color7;
+        border-color: $color7;
+      }
+      .ant-btn-primary {
+        background-color: $color6;
+        border-color: $color6;
+      }
+    }
+  }
 
   // 绯荤粺鏍峰紡淇敼
   .ant-select-dropdown-menu-item:hover:not(.ant-select-dropdown-menu-item-disabled) {
@@ -255,6 +276,19 @@
   }
   .ant-select-dropdown-menu-item-active:not(.ant-select-dropdown-menu-item-disabled) {
     background-color: $color1;
+  }
+  // 鍗曢�夋
+  .ant-radio-checked .ant-radio-inner {
+    border-color: $color6;
+  }
+  .ant-radio-checked::after {
+    border: 1px solid $color6;
+  }
+  .ant-radio-inner::after {
+    background-color: $color6;
+  }
+  .ant-radio-wrapper:hover .ant-radio, .ant-radio:hover .ant-radio-inner, .ant-radio-input:focus + .ant-radio-inner {
+    border-color: $color6;
   }
   // 澶嶉�夋
   .ant-checkbox-checked .ant-checkbox-inner {
@@ -307,6 +341,28 @@
   .ant-calendar-picker:hover .ant-calendar-picker-input:not(.ant-input-disabled) {
     border-color: $color5;
   }
+  // 鍒嗛〉
+  .ant-pagination {
+    .ant-pagination-item-active {
+      border-color: $color6;
+      a {
+        color: $color6;
+      }
+    }
+    .ant-pagination-item:hover a {
+      color: $color6;
+    }
+    .ant-pagination-prev:hover .ant-pagination-item-link {
+      color: $color6;
+    }
+    .ant-pagination-next:hover .ant-pagination-item-link {
+      color: $color6;
+    }
+  }
+  // 琛ㄦ牸鎺掑簭鍥炬爣
+  .ant-table-thead > tr > th .ant-table-column-sorter .ant-table-column-sorter-inner .ant-table-column-sorter-up.on, .ant-table-thead > tr > th .ant-table-column-sorter .ant-table-column-sorter-inner .ant-table-column-sorter-down.on {
+    color: $color6;
+  }
 }
 
 body.hidden-split-line #root { // 鍘婚櫎鐧诲綍椤靛垎鍓茬嚎
diff --git a/src/components/header/index.jsx b/src/components/header/index.jsx
index 5d9c7b7..df39098 100644
--- a/src/components/header/index.jsx
+++ b/src/components/header/index.jsx
@@ -4,17 +4,13 @@
 import {connect} from 'react-redux'
 import { is, fromJS } from 'immutable'
 import moment from 'moment'
-import { Dropdown, Menu, Icon, Modal, Form, notification, Switch, Button, Input, Badge } from 'antd'
+import { Dropdown, Menu, Icon, Modal, Form, notification, Switch, Input, Badge } from 'antd'
 
-import asyncComponent from '@/utils/asyncComponent'
 import {
   toggleCollapse,
   modifyMenuTree,
   modifyMainMenu,
   modifyTabview,
-  resetState,
-  resetEditState,
-  resetEditLevel,
   initActionPermission,
   initMenuPermission,
   logout
@@ -25,12 +21,10 @@
 import enUS from '@/locales/en-US/main.js'
 import Utils from '@/utils/utils.js'
 import avatar from '@/assets/img/avatar.jpg'
-import MainLogo from '@/assets/img/main-logo.png'
 import Resetpwd from './resetpwd'
 import LoginForm from './loginform'
 import './index.scss'
 
-const EditMenu = asyncComponent(() => import('@/templates/menuconfig/editfirstmenu'))
 const { confirm } = Modal
 const { Search } = Input
 
@@ -58,10 +52,8 @@
 
   handleCollapse = () => {
     // 灞曞紑銆佹敹璧峰乏渚ц彍鍗曟爮
-    if (!this.props.editState) {
-      this.props.toggleCollapse(!this.props.collapse)
-      localStorage.setItem('collapse', !this.props.collapse)
-    }
+    this.props.toggleCollapse(!this.props.collapse)
+    localStorage.setItem('collapse', !this.props.collapse)
   }
 
   changePassword = () => {
@@ -133,49 +125,10 @@
 
   changeMenu (value) {
     // 涓昏彍鍗曞垏鎹�
-    if (this.props.editState && this.props.editLevel) {
-      // 缂栬緫鐘舵�佷笅锛屼笉鍙垏鎹㈣彍鍗�
-      return
-    }
     if (value.PageParam.OpenType === 'menu') {
       this.props.modifyMainMenu(value)
     } else if (value.PageParam.OpenType === 'outpage') {
       window.open(value.PageParam.linkUrl)
-    }
-  }
-
-  async loadmenu () {
-    // 鑾峰彇涓昏彍鍗�
-    let _param = {func: 's_get_pc_menus', systemType: options.sysType}
-    if (sessionStorage.getItem('isEditState') === 'true') { // 缂栬緫鐘舵�佹椂锛屽鍔犲弬鏁癲ebug
-      _param.debug = 'Y'
-    }
-    if (options.sysType !== 'cloud' && window.GLOB.systemType !== 'production') {
-      _param.linkurl = window.GLOB.linkurl
-    }
-    _param.pro_sys = window.GLOB.systemType === 'production' ? 'Y' : ''
-
-    let result = await Api.getSystemConfig(_param)
-
-    // 鐧诲綍瓒呮椂
-    if (!result) return
-
-    if (result.status) {
-      const { menulist } = this.getMenulist(result)
-
-      this.setState({
-        menulist,
-        systems: []
-      })
-
-      this.props.modifyMenuTree(menulist)
-      this.props.modifyMainMenu(menulist[0] || null)
-    } else {
-      notification.error({
-        top: 92,
-        message: result.message,
-        duration: 10
-      })
     }
   }
 
@@ -352,7 +305,6 @@
               if (trd.LinkUrl && iframes.includes(trd.LinkUrl.split('?')[0])) {
                 trdItem.type = 'iframe'
                 trdItem.LinkUrl = trd.LinkUrl
-                trdItem.forbidden = true
               } else {
                 try {
                   trdItem.PageParam = trd.PageParam ? JSON.parse(trd.PageParam) : {OpenType: 'newtab'}
@@ -363,9 +315,6 @@
                 trdItem.type = trdItem.PageParam.Template || trdItem.type
                 trdItem.OpenType = trdItem.PageParam.OpenType || trdItem.OpenType
 
-                if (trdItem.type === 'CustomPage' && this.props.memberLevel < 20) { // 浼氬憳绛夌骇澶т簬绛変簬20鏃讹紝鏈夌紪杈戞潈闄�
-                  trdItem.forbidden = true
-                }
                 if (trdItem.type === 'NewPage') {
                   trdItem.src = trdItem.PageParam.url || ''
                   
@@ -408,16 +357,7 @@
     return { menulist, thdMenuList }
   }
 
-  reload = () => {
-    this.loadmenu()
-  }
-
-  changeEditState = (state) => {
-    if (!state) { // 閫�鍑虹紪杈戯紝椤甸潰鍒锋柊
-      window.location.reload()
-      return
-    }
-
+  changeEditState = () => {
     // 淇敼缂栬緫鐘舵��
     let UserID = sessionStorage.getItem('CloudUserID')
     let LoginUID = sessionStorage.getItem('CloudLoginUID')
@@ -427,64 +367,15 @@
         loginVisible: true
       })
     } else {
-      sessionStorage.setItem('isEditState', 'true')
       sessionStorage.setItem('role_id', sessionStorage.getItem('cloudRole_id'))
       sessionStorage.setItem('dataM', sessionStorage.getItem('cloudDataM'))
+      sessionStorage.setItem('isEditState', 'true')
 
-      if (window.GLOB.systemType === 'production') {
-        this.props.resetEditLevel('HS')
-        this.props.modifyMainMenu({
-          MenuID: 'systemManageView'
-        })
-
-        this.setState({
-          userName: sessionStorage.getItem('CloudUserName'),
-          avatar: Utils.getrealurl(sessionStorage.getItem('CloudAvatar'))
-        })
-        this.props.resetEditState(state)
-
-        return
-      }
-
-      this.setState({
-        menulist: null,
-        userName: sessionStorage.getItem('CloudUserName'),
-        avatar: Utils.getrealurl(sessionStorage.getItem('CloudAvatar'))
-      })
-      this.loadmenu()
+      this.props.modifyMenuTree([])
       this.props.modifyMainMenu(null)
-      this.props.resetEditState(state)
-    }
+      this.props.modifyTabview([])
 
-    if (window.GLOB.systemType !== 'production') {
-      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))
-        }
-      })
+      this.props.history.replace('/design')
     }
   }
 
@@ -507,33 +398,11 @@
           sessionStorage.setItem('dataM', res.dataM ? 'true' : '')
           sessionStorage.setItem('isEditState', 'true')
 
-          if (window.GLOB.systemType === 'production') {
-            this.props.resetEditLevel('HS')
-            this.props.modifyMainMenu({
-              MenuID: 'systemManageView'
-            })
-    
-            this.setState({
-              loginVisible: false,
-              loginLoading: false,
-              userName: res.UserName,
-              avatar: res.icon
-            })
-            this.props.resetEditState(true)
-    
-            return
-          }
-
-          this.setState({
-            menulist: null,
-            loginVisible: false,
-            loginLoading: false,
-            userName: res.UserName,
-            avatar: res.icon
-          })
-          this.loadmenu()
+          this.props.modifyMenuTree([])
           this.props.modifyMainMenu(null)
-          this.props.resetEditState(true)
+          this.props.modifyTabview([])
+
+          this.props.history.replace('/design')
         } else {
           this.setState({
             loginLoading: false
@@ -546,43 +415,6 @@
         }
       })
     })
-  }
-
-  enterEdit = () => {
-    // 杩涘叆缂栬緫鐘舵��
-    this.props.resetEditLevel('level1')
-  }
-
-  enterEditManage = () => {
-    const { editLevel } = this.props
-
-    if (editLevel === 'HS')  return
-
-    this.props.resetEditLevel('HS')
-    this.props.modifyMainMenu({
-      MenuID: 'systemManageView'
-    })
-  }
-
-  /**
-   * @description 閫�鍑虹鐞嗙晫闈㈣彍鍗�
-   */
-  exitManage = () => {
-    const { menulist } = this.state
-
-    if (window.GLOB.systemType === 'production') { // 姝e紡绯荤粺鐗堟湰鍗囩骇鍚庯紝椤甸潰鍒锋柊
-      window.location.reload()
-      return
-    }
-
-    this.props.modifyMainMenu(menulist[0] || null)
-    this.props.resetEditLevel(false)
-    this.props.modifyTabview([])
-  }
-  
-  exitEdit = () => {
-    // 閫�鍑虹紪杈戠姸鎬�
-    this.props.resetEditLevel(false)
   }
 
   changeSystem = (system) => {
@@ -679,6 +511,15 @@
     return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
   }
 
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
   verup = () => {
     const { oriVersion, newVersion } = this.state
     const _this = this
@@ -729,9 +570,9 @@
       <Menu className="header-dropdown">
         {debug && <Menu.Item key="switch">
           {this.state.dict['main.edit']}
-          <Switch size="small" style={{marginLeft: '7px'}} disabled={!!this.props.editLevel} checked={this.props.editState} onChange={this.changeEditState} />
+          <Switch size="small" style={{marginLeft: '7px'}} checked={false} onChange={this.changeEditState} />
         </Menu.Item>}
-        {!this.props.editState ? <Menu.Item key="password" onClick={this.changePassword}>{this.state.dict['main.password']}</Menu.Item> : null}
+        <Menu.Item key="password" onClick={this.changePassword}>{this.state.dict['main.password']}</Menu.Item>
         {this.state.systems.length ? <Menu.SubMenu style={{minWidth: '110px'}} title="鍒囨崲绯荤粺">
           {this.state.systems.map((system, index) => (
             <Menu.Item style={{minWidth: '100px', lineHeight: '30px'}} key={'sub' + index} onClick={() => {this.changeSystem(system)}}> {system.AppName} </Menu.Item>
@@ -747,13 +588,13 @@
 
     return (
       <header className="header-container ant-menu-dark" id="main-header-container">
-        <div className={'header-logo ' + (collapse ? 'collapse' : '')}><img src={!this.props.editState ? this.state.logourl : MainLogo} alt=""/></div>
+        <div className={'header-logo ' + (collapse ? 'collapse' : '')}><img src={this.state.logourl} alt=""/></div>
         <div className={'header-collapse ' + (collapse ? 'collapse' : '')}>
           {menulist && menulist.length ? <Icon type={collapse ? 'menu-unfold' : 'menu-fold'} onClick={this.handleCollapse}/> : null}
         </div>
         {/* 姝e父鑿滃崟 */}
-        {this.props.editLevel !== 'level1' && menulist ?
-          <ul className={'header-menu ' + this.props.editLevel}>{
+        {menulist ?
+          <ul className="header-menu">{
             menulist.map(item => {
               return (
                 <li key={item.MenuID} onClick={() => {this.changeMenu(item)}} className={mainMenu && mainMenu.MenuID === item.MenuID ? 'active' : ''}>
@@ -761,27 +602,50 @@
                 </li>
               )
             })}
-            {this.props.editState && (!this.props.editLevel || this.props.editLevel === 'HS') ?
-              <li key="HS" onClick={this.enterEditManage} className={this.props.editLevel === 'HS' ? 'active' : ''}>
-                <span>HS</span>
-              </li> : null
-            }
           </ul> : null
         }
-        {this.props.editLevel === 'HS' ? <Button className="level4-close" type="primary" onClick={this.exitManage}>閫�鍑�</Button> : null}
-        {/* 杩涘叆缂栬緫鎸夐挳 */}
-        {this.props.editState && !this.props.editLevel ? <Icon onClick={this.enterEdit} className="edit-check" type="edit" /> : null}
-        {/* {this.props.editState && !this.props.editLevel && options.sysType === 'local' && window.GLOB.systemType !== 'production' ?
-          <a href="#/mobmanage" 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: '棣栭〉' }))) */}
-        {this.props.editState && !this.props.editLevel && window.GLOB.systemType !== 'production' && this.props.memberLevel >= 20 ?
-          <a className="home-edit" href={`#/menudesign/JTdCJTIyTWVudVR5cGUlMjIlM0ElMjJob21lJTIyJTJDJTIyTWVudUlkJTIyJTNBJTIyaG9tZV9wYWdlX2lkJTIyJTJDJTIyTWVudU5hbWUlMjIlM0ElMjIlRTklQTYlOTYlRTklQTElQjUlMjIlN0Q=`} target="_blank" rel="noopener noreferrer">
-            棣栭〉 <Icon type="arrow-right" />
-          </a> : null
+        {/* {menulist ?
+          <Menu className="header-vertical-menu" mode="horizontal">
+            {menulist.map(item => {
+              if (!item.children || item.children.length === 0) {
+                return (
+                  <Menu.Item key={item.MenuID}>
+                    {item.MenuName}
+                  </Menu.Item>
+                )
+              } else {
+                return (
+                  <Menu.SubMenu key={item.MenuID} title={item.MenuName}>
+                    <Menu mode="vertical">
+                      {item.children.map(cell => {
+                        if (!cell.children || cell.children.length === 0) {
+                          return (
+                            <Menu.Item key={cell.MenuID}>
+                              {cell.MenuName}
+                            </Menu.Item>
+                          )
+                        } else {
+                          return (
+                            <Menu.SubMenu key={cell.MenuID} title={cell.MenuName}>
+                              <Menu mode="vertical">
+                                {cell.children.map(m => (
+                                  <Menu.Item key={m.MenuID}>
+                                    {m.MenuName}
+                                  </Menu.Item>
+                                ))}
+                              </Menu>
+                            </Menu.SubMenu>
+                          )
+                        }
+                      })}
+                    </Menu>
+                  </Menu.SubMenu>
+                )
+              }
+            })}
+          </Menu> : null
         }
-        {/* 缂栬緫鑿滃崟 */}
-        {this.props.editLevel === 'level1' ? <EditMenu menulist={this.state.menulist} reload={this.reload} exitEdit={this.exitEdit}/> : null}
+         */}
         {/* 澶村儚銆佺敤鎴峰悕 */}
         <Dropdown className="header-setting" overlay={menu}>
           <div>
@@ -792,7 +656,7 @@
           </div>
         </Dropdown>
         {/* 鑿滃崟鎼滅储 */}
-        {!this.props.editState && thdMenuList.length > 0 ?
+        {thdMenuList.length > 0 ?
           <Dropdown overlayClassName="menu-select-dropdown" getPopupContainer={() => document.getElementById('main-header-container')} overlay={
             <div>
               <Search
@@ -861,10 +725,7 @@
     collapse: state.collapse,
     menuTree: state.menuTree,
     mainMenu: state.mainMenu,
-    editState: state.editState,
-    editLevel: state.editLevel,
     permAction: state.permAction,
-    memberLevel: state.memberLevel
   }
 }
 
@@ -874,11 +735,8 @@
     modifyTabview: (tabviews) => dispatch(modifyTabview(tabviews)),
     modifyMenuTree: (menuTree) => dispatch(modifyMenuTree(menuTree)),
     modifyMainMenu: (mainMenu) => dispatch(modifyMainMenu(mainMenu)),
-    resetEditState: (state) => dispatch(resetEditState(state)),
-    resetEditLevel: (level) => dispatch(resetEditLevel(level)),
     initActionPermission: (permAction) => dispatch(initActionPermission(permAction)),
     initMenuPermission: (permMenus) => dispatch(initMenuPermission(permMenus)),
-    resetState: () => dispatch(resetState()),
     logout: () => dispatch(logout())
   }
 }
diff --git a/src/components/header/index.scss b/src/components/header/index.scss
index 28137d8..62bde22 100644
--- a/src/components/header/index.scss
+++ b/src/components/header/index.scss
@@ -1,5 +1,3 @@
-@import '../../assets/css/global.scss';
-
 .header-container {
   position: fixed;
   z-index: 1060;
@@ -77,22 +75,18 @@
       }
     }
   }
-
-  .header-menu.level4 {
-    li {
-      cursor: default;
-      &:hover {
-        span {
-          cursor: default;
-          color: rgba(255, 255, 255, 0.65);
-          border-bottom: none;
-        }
-      }
-      &.active {
-        span {
-          color: #ffffff;
-          border-bottom: 4px solid #1890ff;
-        }
+  .header-vertical-menu {
+    float: left;
+    margin: 0;
+    line-height: 48px;
+    background: transparent;
+    .ant-menu-submenu {
+      border-bottom: 0!important;
+    }
+    >li {
+      >.ant-menu-submenu-title {
+        color: rgba(255, 255, 255, 0.85);
+        font-size: 1.3rem;
       }
     }
   }
diff --git a/src/components/querylog/index.jsx b/src/components/querylog/index.jsx
index 13e2293..16337a5 100644
--- a/src/components/querylog/index.jsx
+++ b/src/components/querylog/index.jsx
@@ -5,6 +5,9 @@
 import Utils from '@/utils/utils.js'
 import MKEmitter from '@/utils/events.js'
 
+/**
+ * @description 鎿嶄綔璁板綍锛屾瘡闅斿叚鍒嗛挓鏇存柊涓�娆�
+ */
 class QueryLog extends Component {
   state = {
     logs: []
diff --git a/src/components/sidemenu/index.jsx b/src/components/sidemenu/index.jsx
index fe1c20f..adcd930 100644
--- a/src/components/sidemenu/index.jsx
+++ b/src/components/sidemenu/index.jsx
@@ -1,22 +1,15 @@
 import React, {Component} from 'react'
-import { withRouter } from 'react-router-dom'
 import PropTypes from 'prop-types'
 import { connect } from 'react-redux'
 import { is, fromJS } from 'immutable'
-import { Menu, Icon, notification } from 'antd'
+import { Menu, Icon } from 'antd'
 
-import asyncComponent from '@/utils/asyncComponent'
-import { modifyTabview, resetEditLevel, modifyMenuTree, modifyMainMenu } from '@/store/action'
-import { SySMenuList } from './config'
-import options from '@/store/options.js'
+import { modifyTabview } from '@/store/action'
 import MKEmitter from '@/utils/events.js'
 import zhCN from '@/locales/zh-CN/main.js'
 import enUS from '@/locales/en-US/main.js'
-import Api from '@/api'
 import './index.scss'
 
-const EditSecMenu = asyncComponent(() => import('@/templates/menuconfig/editsecmenu'))
-const EditThdMenu = asyncComponent(() => import('@/templates/menuconfig/editthdmenu'))
 const { SubMenu } = Menu
 
 class Sidemenu extends Component {
@@ -27,9 +20,7 @@
   state = {
     dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
     subMenulist: [],         // 浜岀骇鑿滃崟
-    editMenu: null,          // 缂栬緫涓夌骇鑿滃崟鏃惰缃�
     rootSubmenuKeys: null,
-    createThirdMenu: false,
     openKeys: null,
     preview: null
   }
@@ -40,7 +31,6 @@
         subMenulist: [],
         rootSubmenuKeys: [],
         openKeys: [],
-        editMenu: null
       })
       return
     }
@@ -56,39 +46,11 @@
       subMenulist: menu.children,
       rootSubmenuKeys: menu.children.map(item => item.MenuID),
       openKeys: this.props.collapse ? [] : [openKey],
-      editMenu: this.props.editLevel === 'level3' ? menu.children.filter(_menu => _menu.MenuID === this.state.editMenu.MenuID)[0] : null
-    })
-  }
-
-  enterManageView = () => {
-    let menulist = SySMenuList
-
-    if (window.GLOB.systemType === 'production') {
-      menulist.forEach(menu => {
-        menu.children = menu.children.filter(item => item.systems && item.systems.includes(window.GLOB.systemType))
-      })
-
-      menulist = menulist.filter(menu => menu.children.length > 0)
-    } else {
-      menulist.forEach(menu => {
-        menu.children = menu.children.filter(item => !item.systems || item.systems.includes(options.sysType))
-      })
-
-      menulist = menulist.filter(menu => menu.children.length > 0)
-    }
-
-    this.setState({
-      subMenulist: menulist,
-      rootSubmenuKeys: menulist.map(item => item.MenuID),
-      openKeys: this.props.collapse ? [] : [menulist[0].MenuID]
     })
   }
 
   changemenu(e, menu) {
     e.preventDefault()
-    if (this.props.editState && this.props.editLevel !== 'HS') {
-      return
-    }
 
     if (menu.OpenType === 'newpage' || menu.OpenType === 'NewPage') {
       window.open(menu.src)
@@ -119,9 +81,7 @@
   }
 
   UNSAFE_componentWillReceiveProps (nextProps) {
-    if (!is(fromJS(this.props.mainMenu), fromJS(nextProps.mainMenu)) && nextProps.mainMenu && nextProps.mainMenu.MenuID === 'systemManageView') {
-      this.enterManageView()
-    } else if (!is(fromJS(this.props.mainMenu), fromJS(nextProps.mainMenu))) {
+    if (!is(fromJS(this.props.mainMenu), fromJS(nextProps.mainMenu))) {
       // 涓昏彍鍗曞垏鎹紝璇锋眰2銆�3绾ц彍鍗曟暟鎹�
       this.loadsubmenu(nextProps.mainMenu)
     } else if (nextProps.collapse && this.props.collapse !== nextProps.collapse) {
@@ -147,161 +107,25 @@
     }
   }
 
-  enterSubEdit = (e) => {
-    // 缂栬緫浜岀骇鑿滃崟
-    e.stopPropagation()
-    this.props.resetEditLevel('level2')
-  }
-
-  enterThrEdit = (e, menu) => {
-    // 缂栬緫涓夌骇鑿滃崟
-    e.stopPropagation()
-    this.props.resetEditLevel('level3')
-    this.setState({editMenu: menu})
-  }
-
-  reload = () => {
-    const { mainMenu } = this.props
-    let _param = {func: 's_get_pc_menus', systemType: options.sysType, debug: 'Y'}
-    if (options.sysType !== 'cloud' && window.GLOB.systemType !== 'production') {
-      _param.linkurl = window.GLOB.linkurl
-    }
-    _param.pro_sys = window.GLOB.systemType === 'production' ? 'Y' : ''
-
-    Api.getSystemConfig(_param).then(result => {
-      // 鐧诲綍瓒呮椂
-      if (!result) return
-  
-      if (result.status) {
-        let res = this.getMenulist(result)
-        let _mainMenu = res.menulist.filter(item => item.MenuID === mainMenu.MenuID)[0]
-  
-        this.props.modifyMenuTree(res.menulist)
-        this.props.modifyMainMenu(_mainMenu || null)
-      } else {
-        notification.error({
-          top: 92,
-          message: result.message,
-          duration: 10
-        })
-      }
-      this.loadsubmenu(this.props.mainMenu)
-    })
-  }
-
-  getMenulist = (result) => {
-    let iframes = ['Main/Index', 'bda/rdt', 'Home/rdt']
-    let menulist = result.fst_menu.map(fst => {
-      let fstItem = {
-        MenuID: fst.MenuID,
-        MenuName: fst.MenuName,
-        PageParam: {OpenType: 'menu', linkUrl: ''},
-        children: []
-      }
-      if (fst.PageParam) {
-        try {
-          fstItem.PageParam = JSON.parse(fst.PageParam)
-        } catch (e) {
-          fstItem.PageParam = {OpenType: 'menu', linkUrl: ''}
-        }
-      }
-
-      if (fst.snd_menu) {
-        fstItem.children = fst.snd_menu.map(snd => {
-          let sndItem = {
-            ParentId: fst.MenuID,
-            MenuID: snd.MenuID,
-            MenuName: snd.MenuName,
-            PageParam: {Icon: 'folder'},
-            children: []
-          }
-
-          if (snd.PageParam) {
-            try {
-              sndItem.PageParam = JSON.parse(snd.PageParam)
-            } catch (e) {
-              sndItem.PageParam = {Icon: 'folder'}
-            }
-          }
-
-          if (snd.trd_menu) {
-            sndItem.children = snd.trd_menu.map(trd => {
-              let trdItem = {
-                FstId: fst.MenuID,
-                ParentId: snd.MenuID,
-                MenuID: trd.MenuID,
-                MenuName: trd.MenuName,
-                MenuNo: trd.MenuNo,
-                EasyCode: trd.EasyCode,
-                type: 'CommonTable',            // 榛樿鍊间负甯哥敤琛�
-                OpenType: 'newtab'              // 鎵撳紑鏂瑰紡
-              }
-  
-              if (trd.LinkUrl && iframes.includes(trd.LinkUrl.split('?')[0])) {
-                trdItem.type = 'iframe'
-                trdItem.LinkUrl = trd.LinkUrl
-                trdItem.forbidden = true
-              } else {
-                try {
-                  trdItem.PageParam = trd.PageParam ? JSON.parse(trd.PageParam) : {OpenType: 'newtab'}
-                } catch (e) {
-                  trdItem.PageParam = {OpenType: 'newtab'}
-                }
-
-                trdItem.type = trdItem.PageParam.Template || trdItem.type
-                trdItem.OpenType = trdItem.PageParam.OpenType || trdItem.OpenType
-
-                if (trdItem.type === 'CustomPage' && this.props.memberLevel < 20) { // 浼氬憳绛夌骇澶т簬绛変簬20鏃讹紝鏈夌紪杈戞潈闄�
-                  trdItem.forbidden = true
-                }
-              }
-
-              return trdItem
-            })
-          }
-
-          return sndItem
-        })
-      }
-
-      return fstItem
-    })
-
-    return { menulist }
-  }
-
-  exitEdit = () => {
-    if (this.props.editLevel === 'level3') {
-      this.setState({editMenu: null})
-    }
-    this.props.resetEditLevel(false)
-  }
-
   render () {
     const { mainMenu } = this.props
-    const editShow = (this.props.editState && !this.props.editLevel) || false
 
     if (mainMenu === '') return (<span className="mk-side-menu-hidden"></span>)
 
     return (
-      <aside id="mk-sidemenu-wrap" className={'mk-side-menu ant-menu-dark' + (this.props.collapse ? ' collapsed' : '') + (this.props.isiframe ? ' mk-iframe' : '') + (this.props.editState ? ' mk-edit' : '')}>
-        {!(this.props.editLevel === 'level2' || this.props.editLevel === 'level3') &&
-          <Menu openKeys={this.state.openKeys} onOpenChange={this.onOpenChange} mode="inline" theme="dark" inlineCollapsed={this.props.collapse}>
-          {editShow && <li className="sup-menu"><Icon onClick={this.enterSubEdit} className="edit-check" type="edit" /></li>}
-          {this.state.subMenulist && this.state.subMenulist.map((item, index) => {
+      <aside id="mk-sidemenu-wrap" className={'mk-side-menu ant-menu-dark' + (this.props.collapse ? ' collapsed' : '') + (this.props.isiframe ? ' mk-iframe' : '')}>
+        <Menu openKeys={this.state.openKeys} onOpenChange={this.onOpenChange} mode="inline" theme="dark" inlineCollapsed={this.props.collapse}>
+          {this.state.subMenulist && this.state.subMenulist.map((item) => {
             return (
               <SubMenu
                 key={item.MenuID}
                 title={
-                  <span className={editShow && index === 0 ? 'edit-control' : ''}>
+                  <span>
                     <Icon type={item.PageParam.Icon} />
                     <span>{item.MenuName}</span>
                   </span>
                 }
               >
-                {editShow ? <li className={'ant-menu-item ' + (item.children.length > 0 ? 'sub-menu' : '')}>
-                  <Icon onClick={(e) => {this.enterThrEdit(e, item)}} className="edit-check" type="edit" />
-                </li> : null}
                 {item.children.map(cell => {
                   return (
                     <Menu.Item key={cell.MenuID}>
@@ -312,25 +136,7 @@
               </SubMenu>
             )
           })}
-        </Menu>}
-        {this.props.editLevel === 'level2' ?
-          <EditSecMenu
-            menulist={this.state.subMenulist}
-            menuTree={this.props.menuTree}
-            supMenu={this.props.mainMenu}
-            reload={this.reload}
-            exitEdit={this.exitEdit}
-          /> : null
-        }
-        {this.props.editLevel === 'level3' && this.state.editMenu ?
-          <EditThdMenu
-            menulist={this.state.editMenu.children}
-            supMenuList={this.state.subMenulist}
-            supMenu={this.state.editMenu}
-            reload={this.reload}
-            exitEdit={this.exitEdit}
-          /> : null
-        }
+        </Menu>
       </aside>
     )
   }
@@ -343,19 +149,13 @@
     isiframe: state.isiframe,
     mainMenu: state.mainMenu,
     menuTree: state.menuTree,
-    memberLevel: state.memberLevel,
-    editState: state.editState,
-    editLevel: state.editLevel
   }
 }
 
 const mapDispatchToProps = (dispatch) => {
   return {
-    modifyMenuTree: (menuTree) => dispatch(modifyMenuTree(menuTree)),
-    modifyMainMenu: (mainMenu) => dispatch(modifyMainMenu(mainMenu)),
     modifyTabview: (tabviews) => dispatch(modifyTabview(tabviews)),
-    resetEditLevel: (level) => dispatch(resetEditLevel(level))
   }
 }
 
-export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Sidemenu))
\ No newline at end of file
+export default connect(mapStateToProps, mapDispatchToProps)(Sidemenu)
\ No newline at end of file
diff --git a/src/components/sidemenu/index.scss b/src/components/sidemenu/index.scss
index e0c6a33..9cce86f 100644
--- a/src/components/sidemenu/index.scss
+++ b/src/components/sidemenu/index.scss
@@ -1,5 +1,4 @@
 @import '../../assets/css/iconfont.css';
-@import '../../assets/css/global.scss';
 
 .mk-side-menu {
   flex: 0 0 235px;
@@ -94,16 +93,7 @@
     left: 187px;
   }
 }
-.mk-side-menu.mk-edit { // 缂栬緫鏃舵帶鍒惰彍鍗曞簳鑹�
-  .ant-menu-sub.ant-menu-inline {
-    > .ant-menu-item.ant-menu-item-selected {
-      background: unset;
-    }
-    > .ant-menu-item.ant-menu-item-active {
-      background: unset;
-    }
-  }
-}
+
 .mk-side-menu.mk-iframe { // tab椤典腑涓篿frame鏃�
   max-height: 100vh;
   overflow-y: scroll;
diff --git a/src/components/tabview/index.jsx b/src/components/tabview/index.jsx
index 01abafb..7f5d069 100644
--- a/src/components/tabview/index.jsx
+++ b/src/components/tabview/index.jsx
@@ -157,13 +157,15 @@
   }
 
   componentDidMount () {
-    let home = {
-      MenuID: 'home_page_id',
-      MenuName: this.state.dict['main.homepage'],
-      selected: true,
-      type: 'Home'
+    if (sessionStorage.getItem('isEditState') !== 'true') {
+      let home = {
+        MenuID: 'home_page_id',
+        MenuName: this.state.dict['main.homepage'],
+        selected: true,
+        type: 'Home'
+      }
+      this.props.modifyTabview([home])
     }
-    this.props.modifyTabview([home])
   }
 
   UNSAFE_componentWillReceiveProps (nextProps) {
diff --git a/src/components/tabview/index.scss b/src/components/tabview/index.scss
index 24f4644..c99ba4e 100644
--- a/src/components/tabview/index.scss
+++ b/src/components/tabview/index.scss
@@ -28,7 +28,7 @@
           }
           span.tab-control i.anticon-redo {
             position: absolute;
-            left: -3px;
+            left: -2px;
             top: 18px;
             font-size: 14px;
             margin: 0px;
diff --git a/src/index.js b/src/index.js
index b79cd9c..e03e548 100644
--- a/src/index.js
+++ b/src/index.js
@@ -4,7 +4,7 @@
 import { Provider } from 'react-redux'
 import store from '@/store'
 import * as serviceWorker from './serviceWorker'
-import options from '@/store/options.js'
+import options, { styles } from '@/store/options.js'
 import '@/assets/css/main.scss'
 import '@/assets/css/action.scss'
 import '@/assets/css/minkeicon.css'
@@ -12,6 +12,8 @@
 
 if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
   window.location.replace(window.location.href.split(/(index.html)+/ig)[0] + 'mob/index.html')
+} else if (window.location.href.indexOf('#/design') > -1) { // 缂栬緫椤甸潰鍒锋柊鏃讹紝璺宠浆鑷充富椤�
+  window.location.replace(window.location.href.replace(/design/ig, 'main'))
 }
 
 options.sysType = window.atob(options.sysType.replace('$mk', ''))
@@ -160,8 +162,8 @@
           link.href = GLOB.favicon
           document.getElementsByTagName('head')[0].appendChild(link)
         }
-        if (GLOB.style && options.styles[GLOB.style]) {
-          document.body.className = options.styles[GLOB.style] + ' ' + (GLOB.showline === 'false' ? 'hidden-split-line' : '')
+        if (GLOB.style && styles[GLOB.style]) {
+          document.body.className = styles[GLOB.style] + ' ' + (GLOB.showline === 'false' ? 'hidden-split-line' : '')
         }
       } catch {
         console.warn('Parse Failure')
@@ -189,10 +191,6 @@
       GLOB.linkurl = ''
       GLOB.location = 'http://qingqiumarket.cn'
       GLOB.service = 'mkwms/'
-    }
-
-    if (GLOB.style && options.styles[GLOB.style]) {
-      document.getElementById('root').className = options.styles[GLOB.style]
     }
 
     Object.defineProperty(GLOB, 'appId', {
diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx
index 24433e0..045c3e1 100644
--- a/src/menu/components/card/cardcellcomponent/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/index.jsx
@@ -19,7 +19,6 @@
 const { confirm } = Modal
 
 const ActionForm = asyncComponent(() => import('@/menu/components/share/actioncomponent/actionform'))
-const CreateFunc = asyncComponent(() => import('@/templates/zshare/createfunc'))
 const VerifyCard = asyncComponent(() => import('@/templates/zshare/verifycard'))
 const VerifyPrint = asyncComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyprint'))
 const VerifyExcelIn = asyncComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyexcelin'))
@@ -622,7 +621,6 @@
           maskClosable={false}
           onCancel={this.editModalCancel}
           footer={[
-            <CreateFunc key="create" dict={dict} ref="btnCreatFunc" trigger={this.creatFunc}/>,
             <Button key="cancel" onClick={this.editModalCancel}>{dict['model.cancel']}</Button>,
             <Button key="confirm" type="primary" onClick={this.handleActionSubmit}>{dict['model.confirm']}</Button>
           ]}
diff --git a/src/menu/components/share/actioncomponent/index.jsx b/src/menu/components/share/actioncomponent/index.jsx
index 36e5f09..e208f94 100644
--- a/src/menu/components/share/actioncomponent/index.jsx
+++ b/src/menu/components/share/actioncomponent/index.jsx
@@ -4,8 +4,7 @@
 import { is, fromJS } from 'immutable'
 import { Modal, notification, Button } from 'antd'
 
-import Utils from '@/utils/utils.js'
-import DevUtils from '@/utils/devutils.js'
+import Utils, { FuncUtils } from '@/utils/utils.js'
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
 import { getActionForm } from './formconfig'
@@ -368,22 +367,22 @@
           fields: fields,
           menuNo: menu.MenuNo
         }
-        newLText = Utils.formatOptions(DevUtils.getfunc(_param, btn, menu, _config))
-        DelText = Utils.formatOptions(DevUtils.dropfunc(btn.innerFunc))
+        newLText = Utils.formatOptions(FuncUtils.getfunc(_param, btn, menu, _config))
+        DelText = Utils.formatOptions(FuncUtils.dropfunc(btn.innerFunc))
       } else if (btn.OpenType === 'excelIn') {
         let _param = {
           funcName: btn.innerFunc,
           menuNo: menu.MenuNo
         }
-        newLText = Utils.formatOptions(DevUtils.getexcelInfunc(_param, btn, menu))
-        DelText = Utils.formatOptions(DevUtils.dropfunc(btn.innerFunc))
+        newLText = Utils.formatOptions(FuncUtils.getexcelInfunc(_param, btn, menu))
+        DelText = Utils.formatOptions(FuncUtils.dropfunc(btn.innerFunc))
       } else if (btn.OpenType === 'excelOut') {
         let _param = {
           innerFunc: btn.innerFunc
         }
 
-        newLText = Utils.formatOptions(DevUtils.getTableFunc(_param, menu, _config)) // 鍒涘缓瀛樺偍杩囩▼sql
-        DelText = Utils.formatOptions(DevUtils.dropfunc(btn.innerFunc))
+        newLText = Utils.formatOptions(FuncUtils.getTableFunc(_param, menu, _config)) // 鍒涘缓瀛樺偍杩囩▼sql
+        DelText = Utils.formatOptions(FuncUtils.dropfunc(btn.innerFunc))
       } else {
         let _param = {
           funcName: btn.innerFunc,
@@ -391,8 +390,8 @@
           fields: '',
           menuNo: menu.MenuNo
         }
-        newLText = Utils.formatOptions(DevUtils.getfunc(_param, btn, menu, _config))
-        DelText = Utils.formatOptions(DevUtils.dropfunc(btn.innerFunc))
+        newLText = Utils.formatOptions(FuncUtils.getfunc(_param, btn, menu, _config))
+        DelText = Utils.formatOptions(FuncUtils.dropfunc(btn.innerFunc))
       }
 
       this.refs.btnCreatFunc.exec(btn.innerFunc, newLText, DelText)
diff --git a/src/router/index.js b/src/router/index.js
index e3d881c..bf66ba2 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -2,13 +2,14 @@
 import {HashRouter, Switch, Route, Redirect} from 'react-router-dom'
 import md5 from 'md5'
 import moment from 'moment'
-import options from '@/store/options.js'
+import { styles } from '@/store/options.js'
 import asyncComponent from '@/utils/asyncComponent'
 import asyncLoadComponent from '@/utils/asyncLoadComponent'
 
 const Pay = asyncLoadComponent(() => import('@/views/pay'))
 const Sso = asyncLoadComponent(() => import('@/views/sso'))
 const Main = asyncLoadComponent(() => import('@/views/main'))
+const Design = asyncLoadComponent(() => import('@/views/design'))
 const Login = asyncLoadComponent(() => import('@/views/login'))
 const NotFound = asyncComponent(() => import('@/views/404'))
 const MobManage = asyncLoadComponent(() => import('@/views/mobmanage'))
@@ -23,6 +24,7 @@
   {path: '/print/:param', name: 'print', component: PrintT, auth: false},
   {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: '/menudesign/:param', name: 'menudesign', component: MenuDesign, auth: true},
@@ -56,8 +58,8 @@
           if (_param.mainlogo) {
             window.GLOB.mainlogo = _param.mainlogo
           }
-          if (_param.mstyle && options.styles[_param.mstyle]) {
-            document.getElementById('root').className = options.styles[_param.mstyle]
+          if (_param.mstyle && styles[_param.mstyle]) {
+            document.body.className = styles[_param.mstyle]
           }
           if (_param.MainMenu) {
             sessionStorage.setItem('MainMenu', _param.MainMenu)
diff --git a/src/store/action-type.js b/src/store/action-type.js
index 5668a97..6db6bc7 100644
--- a/src/store/action-type.js
+++ b/src/store/action-type.js
@@ -13,14 +13,8 @@
 // 淇敼绐楀彛鏍峰紡锛屽尯鍒唅frame涓庢甯搁〉闈�
 export const TOGGLE_ISIFRAME = 'TOGGLE_ISIFRAME'
 
-// 閫�鍑虹郴缁熸椂鍙傛暟閲嶇疆
-export const RESET_STATE = 'RESET_STATE'
-
 // 鍒锋柊tab椤甸潰
 export const REFRESH_TABVIEW = 'REFRESH_TABVIEW'
-
-// 閲嶇疆缂栬緫鐘舵��
-export const RESET_EDITSTATE = 'RESET_EDITSTATE'
 
 // 閲嶇疆缂栬緫绾у埆
 export const RESET_EDITLEVEL = 'RESET_EDITLEVEL'
diff --git a/src/store/action.js b/src/store/action.js
index 7b0bcf7..c72bc06 100644
--- a/src/store/action.js
+++ b/src/store/action.js
@@ -40,21 +40,6 @@
   }
 }
 
-// 閫�鍑虹郴缁熸椂鍙傛暟閲嶇疆
-export const resetState = () => {
-  return {
-    type: user.RESET_STATE
-  }
-}
-
-// 閲嶇疆缂栬緫鐘舵��
-export const resetEditState = (editState) => {
-  return {
-    type: user.RESET_EDITSTATE,
-    editState
-  }
-}
-
 // 閲嶇疆缂栬緫绾у埆
 export const resetEditLevel = (editLevel) => {
   return {
diff --git a/src/store/options.js b/src/store/options.js
index 3d81630..6731ec3 100644
--- a/src/store/options.js
+++ b/src/store/options.js
@@ -1,37 +1,46 @@
-// 绯荤粺閰嶇疆
+/**
+ * @description 绯荤粺淇℃伅
+ * 1銆亂un ( Y2xv$mkdWQ= ) 銆� dandian ( U1$mkNP ) 銆� yewu ( bG9j$mkYWw= )
+ * 2銆亀indow.btoa('') 鍩熷悕 涓嶅甫 /
+ * 3銆乥aoshide ( aHR0cDovL2Nsb3VkLnBv$mkc2l0ZWNncm91cC5jb206ODA4MA== )
+ */
 export default {
-  sysType: 'bG9j$mkYWw=', // yun ( Y2xv$mkdWQ= ) 銆� dandian ( U1$mkNP ) 銆� yewu ( bG9j$mkYWw= )
+  sysType: 'bG9j$mkYWw=',
   caId: 'MjAyMDAxMTYxMjMzMzU1MDd$mkGQzkyMzI1Rjk4MDY0QUNGQjQ2Mg==',
   cakey: 'MjAyMDAxMTYxMjQwMDQ2NDM$mk2N0QzODE2MjExNUI0MTc4OTVDMQ==',
-  cdomain: 'aHR0cDovL2Nsb3V$mkkLm1rOWguY24=', // window.btoa('') 鍩熷悕 涓嶅甫 /; baoshide ( aHR0cDovL2Nsb3VkLnBv$mkc2l0ZWNncm91cC5jb206ODA4MA== )
-  styles: {
-    bg_black_style_blue: 'mk-blue-black',
-    bg_white_style_blue: 'mk-blue-white',
-    bg_black_style_red: 'mk-red-black',
-    bg_white_style_red: 'mk-red-white',
-    bg_black_style_orange_red: 'mk-orange-red-black',
-    bg_white_style_orange_red: 'mk-orange-red-white',
-    bg_black_style_orange: 'mk-orange-black',
-    bg_white_style_orange: 'mk-orange-white',
-    bg_black_style_orange_yellow: 'mk-orange-yellow-black',
-    bg_white_style_orange_yellow: 'mk-orange-yellow-white',
-    bg_black_style_yellow: 'mk-yellow-black',
-    bg_white_style_yellow: 'mk-yellow-white',
-    bg_black_style_yellow_green: 'mk-yellow-green-black',
-    bg_white_style_yellow_green: 'mk-yellow-green-white',
-    bg_black_style_green: 'mk-green-black',
-    bg_white_style_green: 'mk-green-white',
-    bg_black_style_cyan: 'mk-cyan-black',
-    bg_white_style_cyan: 'mk-cyan-white',
-    bg_black_style_blue_purple: 'mk-blue-purple-black',
-    bg_white_style_blue_purple: 'mk-blue-purple-white',
-    bg_black_style_purple: 'mk-purple-black',
-    bg_white_style_purple: 'mk-purple-white',
-    bg_black_style_magenta: 'mk-magenta-black',
-    bg_white_style_magenta: 'mk-magenta-white',
-    bg_black_style_grass_green: 'mk-grass-green-black',
-    bg_white_style_grass_green: 'mk-grass-green-white',
-    bg_black_style_deep_red: 'mk-deep-red-black',
-    bg_white_style_deep_red: 'mk-deep-red-white',
-  }
+  cdomain: 'aHR0cDovL2Nsb3V$mkkLm1rOWguY24='
+}
+
+/**
+ * @description 绯荤粺鏍峰紡搴�
+ */
+export const styles = {
+  bg_black_style_blue: 'mk-blue-black',
+  bg_white_style_blue: 'mk-blue-white',
+  bg_black_style_red: 'mk-red-black',
+  bg_white_style_red: 'mk-red-white',
+  bg_black_style_orange_red: 'mk-orange-red-black',
+  bg_white_style_orange_red: 'mk-orange-red-white',
+  bg_black_style_orange: 'mk-orange-black',
+  bg_white_style_orange: 'mk-orange-white',
+  bg_black_style_orange_yellow: 'mk-orange-yellow-black',
+  bg_white_style_orange_yellow: 'mk-orange-yellow-white',
+  bg_black_style_yellow: 'mk-yellow-black',
+  bg_white_style_yellow: 'mk-yellow-white',
+  bg_black_style_yellow_green: 'mk-yellow-green-black',
+  bg_white_style_yellow_green: 'mk-yellow-green-white',
+  bg_black_style_green: 'mk-green-black',
+  bg_white_style_green: 'mk-green-white',
+  bg_black_style_cyan: 'mk-cyan-black',
+  bg_white_style_cyan: 'mk-cyan-white',
+  bg_black_style_blue_purple: 'mk-blue-purple-black',
+  bg_white_style_blue_purple: 'mk-blue-purple-white',
+  bg_black_style_purple: 'mk-purple-black',
+  bg_white_style_purple: 'mk-purple-white',
+  bg_black_style_magenta: 'mk-magenta-black',
+  bg_white_style_magenta: 'mk-magenta-white',
+  bg_black_style_grass_green: 'mk-grass-green-black',
+  bg_white_style_grass_green: 'mk-grass-green-white',
+  bg_black_style_deep_red: 'mk-deep-red-black',
+  bg_white_style_deep_red: 'mk-deep-red-white',
 }
\ No newline at end of file
diff --git a/src/store/reducer.js b/src/store/reducer.js
index ba3511a..59c15ec 100644
--- a/src/store/reducer.js
+++ b/src/store/reducer.js
@@ -27,7 +27,6 @@
   tabviews: [],         // 瀵艰埅鏍�
   collapse: _collapse,  // 鏄惁鏀惰捣渚ц竟鏍忓鑸�
   isiframe: false,      // 鏄惁涓篿frame绐楀彛
-  editState: false,     // 鏄惁涓虹紪杈戠姸鎬侊紝鍊间负false銆乼rue
   editLevel: null,      // 缂栬緫鑿滃崟绾у埆锛屽�间负level1銆乴evel2銆乴evel3銆丠S
   permAction: {},       // 鐢ㄦ埛鎸夐挳鏉冮檺
   permMenus: [],        // 鐢ㄦ埛涓夌骇鑿滃崟鍒楄〃
@@ -68,31 +67,10 @@
         ...state,
         isiframe: action.isiframe
       }
-    case Type.RESET_STATE:
-    // 閲嶇疆榛樿鍙傛暟锛堥��鍑烘椂锛�
-      return {
-        ...state,
-        ...{
-          mainMenu: null,
-          tabviews: [],
-          collapse: false,
-          isiframe: false
-        }
-      }
-    case Type.RESET_EDITSTATE:
-    // 閲嶇疆缂栬緫鐘舵��
-      document.body.className = ''
-      return {
-        ...state,
-        tabviews: [],
-        editState: action.editState,
-        collapse: false
-      }
     case Type.RESET_EDITLEVEL:
     // 閲嶇疆缂栬緫绾у埆
       return {
         ...state,
-        editState: true,
         editLevel: action.editLevel
       }
     case Type.INIT_ACTIONPERMISSION:
@@ -126,7 +104,6 @@
         tabviews: [],
         collapse: localStorage.getItem('collapse') === 'true',
         isiframe: false,
-        editState: false,
         editLevel: null,
         permAction: {},
         permMenus: [],
diff --git a/src/tabviews/custom/components/share/normalTable/index.jsx b/src/tabviews/custom/components/share/normalTable/index.jsx
index ca764a7..255cfa3 100644
--- a/src/tabviews/custom/components/share/normalTable/index.jsx
+++ b/src/tabviews/custom/components/share/normalTable/index.jsx
@@ -577,7 +577,7 @@
       index = selectedRowKeys.slice(-1)[0]
     }
 
-    if (setting.tableType === 'checkbox') {
+    if (setting.tableType === 'checkbox' || setting.tableType === 'radio') {
       _activeIndex = index === '' ? null : index
     }
 
@@ -603,7 +603,7 @@
     if (setting.tableType === 'radio') {
       newkeys = [index]
       this.changedata(index)
-      this.setState({ selectedRowKeys: newkeys })
+      this.setState({ selectedRowKeys: newkeys, activeIndex: index })
     } else {
       let _index = ''
       if (newkeys.includes(index)) {
diff --git a/src/tabviews/zshare/normalTable/index.jsx b/src/tabviews/zshare/normalTable/index.jsx
index 77e74d5..7d44e4d 100644
--- a/src/tabviews/zshare/normalTable/index.jsx
+++ b/src/tabviews/zshare/normalTable/index.jsx
@@ -922,7 +922,7 @@
       index = selectedRowKeys.slice(-1)[0]
     }
 
-    if (setting.tableType === 'checkbox') {
+    if (setting.tableType === 'checkbox' || setting.tableType === 'radio') {
       _activeIndex = index === '' ? null : index
     }
 
@@ -946,7 +946,7 @@
     if (this.props.setting.tableType === 'radio') {
       newkeys = [index]
       this.changedata(index)
-      this.setState({ selectedRowKeys: newkeys })
+      this.setState({ selectedRowKeys: newkeys, activeIndex: index })
     } else {
       let _index = ''
       if (newkeys.includes(index)) {
@@ -1155,7 +1155,7 @@
           dataSource={_data}
           rowClassName={(record) => {
             let className = ''
-            if (setting.tableType === 'checkbox' && record.key === activeIndex) {
+            if ((setting.tableType === 'checkbox' || setting.tableType === 'radio') && record.key === activeIndex) {
               className = 'mk-row-active '
             }
 
diff --git a/src/templates/formtabconfig/index.jsx b/src/templates/formtabconfig/index.jsx
index abd4a79..38b589d 100644
--- a/src/templates/formtabconfig/index.jsx
+++ b/src/templates/formtabconfig/index.jsx
@@ -10,8 +10,7 @@
 import Api from '@/api'
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
-import Utils from '@/utils/utils.js'
-import DevUtils from '@/utils/devutils.js'
+import Utils, { FuncUtils } from '@/utils/utils.js'
 import { getModalForm, getActionForm } from '@/templates/zshare/formconfig'
 import { queryTableSql } from '@/utils/option.js'
 
@@ -731,8 +730,8 @@
         menuNo: menu.MenuNo
       }
 
-      newLText = Utils.formatOptions(DevUtils.getfunc(_param, btn, menu, _config))
-      DelText = Utils.formatOptions(DevUtils.dropfunc(_param.funcName))
+      newLText = Utils.formatOptions(FuncUtils.getfunc(_param, btn, menu, _config))
+      DelText = Utils.formatOptions(FuncUtils.dropfunc(_param.funcName))
 
       this.refs.btnCreatFunc.exec(btn.innerFunc, newLText, DelText)
     })
@@ -771,8 +770,8 @@
       }
 
       let _config = {...config, setting: setting}
-      let newLText = Utils.formatOptions(DevUtils.getTableFunc(setting, menu, _config)) // 鍒涘缓瀛樺偍杩囩▼sql
-      let DelText = Utils.formatOptions(DevUtils.dropfunc(setting.innerFunc))          // 鍒犻櫎瀛樺偍杩囩▼sql
+      let newLText = Utils.formatOptions(FuncUtils.getTableFunc(setting, menu, _config)) // 鍒涘缓瀛樺偍杩囩▼sql
+      let DelText = Utils.formatOptions(FuncUtils.dropfunc(setting.innerFunc))          // 鍒犻櫎瀛樺偍杩囩▼sql
 
       this.refs.tableCreatFunc.exec(setting.innerFunc, newLText, DelText).then(result => {
         if (result === 'success') {
diff --git a/src/templates/menuconfig/editfirstmenu/index.scss b/src/templates/menuconfig/editfirstmenu/index.scss
index b38e001..bbf49ea 100644
--- a/src/templates/menuconfig/editfirstmenu/index.scss
+++ b/src/templates/menuconfig/editfirstmenu/index.scss
@@ -12,7 +12,7 @@
       border-radius: 6px;
       background-size: 100% 100%;
       background-repeat: no-repeat;
-      padding: 15px;  
+      padding: 15px;
     }
     .card1 {
       left: 30%;
diff --git a/src/templates/menuconfig/editsecmenu/index.scss b/src/templates/menuconfig/editsecmenu/index.scss
index 43866ca..7a6519b 100644
--- a/src/templates/menuconfig/editsecmenu/index.scss
+++ b/src/templates/menuconfig/editsecmenu/index.scss
@@ -1,6 +1,6 @@
 .second-edit-box {
   position: relative;
-  z-index: 1060;
+  z-index: 10;
   .mask {
     position: fixed;
     top: 0px;
diff --git a/src/templates/menuconfig/editthdmenu/index.scss b/src/templates/menuconfig/editthdmenu/index.scss
index 1172444..da4bd83 100644
--- a/src/templates/menuconfig/editthdmenu/index.scss
+++ b/src/templates/menuconfig/editthdmenu/index.scss
@@ -1,6 +1,6 @@
 .third-edit-box {
   position: relative;
-  z-index: 1060;
+  z-index: 10;
   .mask {
     position: fixed;
     top: 0px;
diff --git a/src/templates/sharecomponent/actioncomponent/index.jsx b/src/templates/sharecomponent/actioncomponent/index.jsx
index 4392c36..72ff755 100644
--- a/src/templates/sharecomponent/actioncomponent/index.jsx
+++ b/src/templates/sharecomponent/actioncomponent/index.jsx
@@ -5,8 +5,7 @@
 import moment from 'moment'
 
 import Api from '@/api'
-import Utils from '@/utils/utils.js'
-import DevUtils from '@/utils/devutils.js'
+import Utils, { FuncUtils } from '@/utils/utils.js'
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
 import { getActionForm } from '@/templates/zshare/formconfig'
@@ -760,8 +759,8 @@
                 fields: fields,
                 menuNo: menu.MenuNo
               }
-              newLText = Utils.formatOptions(DevUtils.getfunc(_param, btn, menu, _config))
-              DelText = Utils.formatOptions(DevUtils.dropfunc(btn.innerFunc))
+              newLText = Utils.formatOptions(FuncUtils.getfunc(_param, btn, menu, _config))
+              DelText = Utils.formatOptions(FuncUtils.dropfunc(btn.innerFunc))
               resolve(true)
             } else {
               notification.warning({
@@ -778,8 +777,8 @@
               funcName: btn.innerFunc,
               menuNo: menu.MenuNo
             }
-            newLText = Utils.formatOptions(DevUtils.getexcelInfunc(_param, btn, menu))
-            DelText = Utils.formatOptions(DevUtils.dropfunc(btn.innerFunc))
+            newLText = Utils.formatOptions(FuncUtils.getexcelInfunc(_param, btn, menu))
+            DelText = Utils.formatOptions(FuncUtils.dropfunc(btn.innerFunc))
             resolve(true)
           } else {
             notification.warning({
@@ -794,8 +793,8 @@
             innerFunc: btn.innerFunc
           }
 
-          newLText = Utils.formatOptions(DevUtils.getTableFunc(_param, menu, _config)) // 鍒涘缓瀛樺偍杩囩▼sql
-          DelText = Utils.formatOptions(DevUtils.dropfunc(btn.innerFunc))
+          newLText = Utils.formatOptions(FuncUtils.getTableFunc(_param, menu, _config)) // 鍒涘缓瀛樺偍杩囩▼sql
+          DelText = Utils.formatOptions(FuncUtils.dropfunc(btn.innerFunc))
 
           resolve(true)
         } else {
@@ -805,8 +804,8 @@
             fields: '',
             menuNo: menu.MenuNo
           }
-          newLText = Utils.formatOptions(DevUtils.getfunc(_param, btn, menu, _config))
-          DelText = Utils.formatOptions(DevUtils.dropfunc(btn.innerFunc))
+          newLText = Utils.formatOptions(FuncUtils.getfunc(_param, btn, menu, _config))
+          DelText = Utils.formatOptions(FuncUtils.dropfunc(btn.innerFunc))
           resolve(true)
         }
       }).then(res => {
diff --git a/src/templates/sharecomponent/settingcomponent/index.jsx b/src/templates/sharecomponent/settingcomponent/index.jsx
index c96f5c3..291a3c6 100644
--- a/src/templates/sharecomponent/settingcomponent/index.jsx
+++ b/src/templates/sharecomponent/settingcomponent/index.jsx
@@ -3,8 +3,7 @@
 import { is, fromJS } from 'immutable'
 import { Icon, Modal, Button } from 'antd'
 
-import Utils from '@/utils/utils.js'
-import DevUtils from '@/utils/devutils.js'
+import Utils, { FuncUtils } from '@/utils/utils.js'
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
 
@@ -85,8 +84,8 @@
 
     this.settingRef.handleConfirm('func').then(setting => {
       let _config = {...config, setting: setting}
-      let newLText = Utils.formatOptions(DevUtils.getTableFunc(setting, menu, _config)) // 鍒涘缓瀛樺偍杩囩▼sql
-      let DelText = Utils.formatOptions(DevUtils.dropfunc(setting.innerFunc))          // 鍒犻櫎瀛樺偍杩囩▼sql
+      let newLText = Utils.formatOptions(FuncUtils.getTableFunc(setting, menu, _config)) // 鍒涘缓瀛樺偍杩囩▼sql
+      let DelText = Utils.formatOptions(FuncUtils.dropfunc(setting.innerFunc))          // 鍒犻櫎瀛樺偍杩囩▼sql
 
       this.refs.funcCreatComponent.exec(setting.innerFunc, newLText, DelText).then(result => {
         if (result === 'success') {
diff --git a/src/utils/devutils.js b/src/utils/devutils.js
deleted file mode 100644
index b314e29..0000000
--- a/src/utils/devutils.js
+++ /dev/null
@@ -1,459 +0,0 @@
-export default class Utils {
-  /**
-   * @description 鍒犻櫎瀛樺偍杩囩▼sql
-   * @return {String} name 瀛樺偍杩囩▼鍚嶇О
-   */
-  static dropfunc (name) {
-    return `IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('${name}') AND type in (N'P', N'PC'))  mdrpk PROCEDURE ${name}`
-  }
-
-  /**
-   * @description 鍒涘缓椤甸潰瀛樺偍杩囩▼
-   * @return {String}
-   */
-  static getTableFunc (param, menu, config) {
-    let form = ''
-    let formParam = ''
-    let _vars = ['bid', 'pageindex', 'pagesize', 'ordercol', 'ordertype', 'exceltype', 'septmenuno', 'lang', 'debug', 'loginuid', 'sessionuid', 'userid', 'errorcode', 'retmsg']
-    let _columns = []
-    let primaryKey = config.setting.primaryKey || 'ID'
-
-    if (!_vars.includes(primaryKey.toLowerCase())) {
-      _vars.push(primaryKey.toLowerCase())
-      formParam = `mchr13k@${primaryKey} nvarchar(50)='',`
-    }
-
-    if (config.search && config.search.length > 0) {
-      let _fields = new Map()
-      config.search.forEach(item => {
-        if (item.field) {
-          let type = ''
-
-          if (item.type.match(/date/ig)) {
-            type = 'datetime=null'
-          } else {
-            type = 'nvarchar(50)=\'\''
-          }
-
-          item.field.split(',').forEach(cell => {
-            let _f = cell
-            if (_fields.has(cell)) {
-              _f = _f + '1'
-            }
-  
-            _fields.set(cell, true)
-
-            if (!_vars.includes(_f.toLowerCase())) {
-              _vars.push(_f.toLowerCase())
-              formParam = formParam + `mchr13k@${_f} ${type},`
-            }
-          })
-        }
-      })
-    }
-
-    if (config.columns && config.columns.length > 0) {
-      config.columns.forEach(item => {
-        if (item.field) {
-          _columns.push(`${item.field} as ${item.label}`)
-        }
-      })
-
-      form = `
-        declare @dc table (${_columns.join(',')})
-        
-        @tableid ='${menu.MenuID}'
-      `
-    }
-
-    let Ltext = `create proc ${param.innerFunc}
-    ( /*${menu.MenuName}*/
-    @appkey nvarchar(50)='',
-    @BID nvarchar(50)='',${formParam}
-    @PageIndex nvarchar(50)='',
-    @PageSize nvarchar(50)='',
-    @OrderCol nvarchar(50)='',
-    @OrderType nvarchar(50)='',
-    @exceltype nvarchar(50)='',
-    @sEPTMenuNo nvarchar(50)='${menu.MenuNo}',
-    @lang nvarchar(50)='',
-    @debug nvarchar(50)='',
-    @LoginUID nvarchar(50)='',
-    @SessionUid nvarchar(50)='',
-    @UserID nvarchar(50),
-    @ErrorCode nvarchar(50) out,
-    @retmsg nvarchar(4000) out
-    )
-    as
-    begin
-    declare  @BegindateTest datetime,@EnddateTest datetime
-    select  @BegindateTest=getdate()
-    set @ErrorCode=''
-    set @retmsg=''
-    BEGIN TRY
-      /*浜嬪姟鎿嶄綔*/
-      BEGIN TRAN
-        /*鍏蜂綋涓氬姟鎿嶄綔*/
-        
-        /* 
-        select top 10 * from sProcExcep order by id desc
-        
-        declare @UserName  nvarchar(50),@FullName nvarchar(50)
-        
-        select @UserName=UserName,@FullName=FullName from SUsers where UID=@UserID
-        ${form}
-        if 1=2
-        begin
-          set @ErrorCode='E'
-          set @retmsg='鍦ㄦ鍐欐姤閿�'
-          goto GOTO_RETURN
-        end
-        
-        insert into sNote (remark,createuserid,CreateUser,CreateStaff)
-        select '鍦ㄦ鍐欐棩蹇�',@UserID,@UserName,@FullName
-        */
-        
-      COMMIT TRAN
-      SET NOCOUNT ON
-      RETURN
-    END TRY
-    BEGIN CATCH
-      /*閿欒澶勭悊*/
-      ROLLBACK TRAN
-      DECLARE @ErrorMessage NVARCHAR(4000);
-      DECLARE @ErrorSeverity INT;
-      DECLARE @ErrorState INT;
-      
-      /*鎶婅嚜瀹氫箟鐨勫弸濂界殑閿欒淇℃伅鎻愮ず鍔犱笂*/
-      set @ErrorCode=cast(ERROR_NUMBER() as nvarchar(50))
-      SET @retmsg=ERROR_MESSAGE();
-      SELECT @ErrorMessage=ERROR_MESSAGE(),
-        @ErrorSeverity=ERROR_SEVERITY(),
-        @ErrorState=ERROR_STATE();
-        
-      RAISERROR(@ErrorMessage, /*-- Message text.*/
-        @ErrorSeverity, /*-- Severity.*/
-        @ErrorState  /*-- State.*/
-      );
-    END CATCH
-    
-    GOTO_RETURN:
-      ROLLBACK TRAN
-      
-    END`
-
-    Ltext = Ltext.replace(/\n\s{4}/ig, 'mchr13k')
-
-    return Ltext
-  }
-
-  /**
-   * @description 鍒涘缓瀛樺偍杩囩▼
-   * @return {String}
-   */
-  static getfunc (param, btn, menu, config) {
-    let form = ''
-    let formParam = ''
-    let _vars = ['bid', 'septmenuno', 'lang', 'debug', 'loginuid', 'sessionuid', 'userid', 'errorcode', 'retmsg']
-    let columns = config.columns
-    let primaryKey = config.setting.primaryKey || 'ID'
-
-    if (!_vars.includes(primaryKey.toLowerCase())) {
-      _vars.push(primaryKey.toLowerCase())
-      let _type = '50'
-      if (btn.Ot === 'requiredOnce') { // 澶氳鎷兼帴鏃讹紝涓婚敭璁句负max
-        _type = 'max'
-      }
-      formParam = `mchr13k@${primaryKey} nvarchar(${_type})='',`
-    }
-
-    if (param.fields && param.fields.length > 0) {
-      let _fields = []
-      param.fields.forEach(item => {
-        if (item.field) {
-          let type = ''
-          if (item.type.match(/date/ig)) {
-            type = 'datetime=null'
-          } else if (item.type === 'number') {
-            type = `decimal(18,${item.decimal})=0`
-          } else {
-            type = 'nvarchar(50)=\'\''
-          }
-
-          if (!_vars.includes(item.field.toLowerCase())) {
-            _vars.push(item.field.toLowerCase())
-            formParam = formParam + `mchr13k@${item.field} ${type},`
-          }
-
-          _fields.push(item.field)
-        }
-      })
-
-      let field1 = _fields.join(',')
-      let field2 = _fields.join(',@')
-      let field3 = _fields.map(cell => {
-        return cell + '=@' + cell
-      })
-
-      field2 = field2 ? '@' + field2 : ''
-      field3 = field3.join(',')
-
-      form = `
-        insert into ${param.name} (${field1},createuserid) select ${field2},@UserID
-        
-        update ${param.name} set ${field3},modifydate=getdate(),modifyuserid=@UserID
-      `
-    } else if (btn.OpenType === 'prompt' || btn.OpenType === 'exec') {
-      form = `
-        update ${param.name} set ModifyDate=getdate(),ModifyUserID=@UserID where ${primaryKey}=@${primaryKey}
-      `
-    }
-
-    if (columns) {
-      let _col = []
-      let _field = []
-      columns.forEach(col => {
-        if (col.field) {
-          if (col.type === 'number') {
-            _col.push(col.field + ' decimal(18,2)')
-          } else {
-            _col.push(col.field + ' nvarchar(50)')
-          }
-          _field.push(col.field)
-        }
-      })
-      _col = _col.join(',')
-      _field = _field.join(',')
-
-      form = form + `
-        declare @dc table (${_col})
-        
-        insert into @dc (${_field})
-
-        @tableid ='${menu.MenuID}'
-      `
-    }
-
-    // 鎵撳嵃鑷畾涔夋ā鏉垮瓧娈垫彁绀�
-    let _printRemark = ''
-    if (btn.funcType === 'print') {
-      _printRemark = '/* 鑷畾涔夋暟鎹墦鍗版ā鏉挎椂锛岃浣跨敤TemplateID瀛楁 */'
-    }
-
-    let Ltext = `create proc ${param.funcName}
-    ( /*${menu.MenuName}  ${btn.label}*/
-    @appkey nvarchar(50)='',
-    @BID nvarchar(50)='',${formParam}
-    @sEPTMenuNo nvarchar(50)='${param.menuNo}',
-    @lang nvarchar(50)='',
-    @debug nvarchar(50)='',
-    @LoginUID nvarchar(50)='',
-    @SessionUid nvarchar(50)='',
-    @UserID nvarchar(50),
-    @ErrorCode nvarchar(50) out,
-    @retmsg nvarchar(4000) out
-    )
-    as
-    begin
-    declare  @BegindateTest datetime,@EnddateTest datetime
-    select  @BegindateTest=getdate()
-    set @ErrorCode=''
-    set @retmsg=''
-    BEGIN TRY
-      /*浜嬪姟鎿嶄綔*/
-      BEGIN TRAN
-        /*鍏蜂綋涓氬姟鎿嶄綔*/
-        ${_printRemark}
-        /* 
-        select top 10 * from sProcExcep order by id desc
-        
-        declare @UserName  nvarchar(50),@FullName nvarchar(50)
-        
-        select @UserName=UserName,@FullName=FullName from SUsers where UID=@UserID
-        ${form}
-        if 1=2
-        begin
-          set @ErrorCode='E'
-          set @retmsg='鍦ㄦ鍐欐姤閿�'
-          goto GOTO_RETURN
-        end
-        
-        insert into sNote (remark,createuserid,CreateUser,CreateStaff)
-        select '鍦ㄦ鍐欐棩蹇�',@UserID,@UserName,@FullName
-        */
-        
-      COMMIT TRAN
-      SET NOCOUNT ON
-      RETURN
-    END TRY
-    BEGIN CATCH
-      /*閿欒澶勭悊*/
-      ROLLBACK TRAN
-      DECLARE @ErrorMessage NVARCHAR(4000);
-      DECLARE @ErrorSeverity INT;
-      DECLARE @ErrorState INT;
-      
-      /*鎶婅嚜瀹氫箟鐨勫弸濂界殑閿欒淇℃伅鎻愮ず鍔犱笂*/
-      set @ErrorCode=cast(ERROR_NUMBER() as nvarchar(50))
-      SET @retmsg=ERROR_MESSAGE();
-      SELECT @ErrorMessage=ERROR_MESSAGE(),
-        @ErrorSeverity=ERROR_SEVERITY(),
-        @ErrorState=ERROR_STATE();
-        
-      RAISERROR(@ErrorMessage, /*-- Message text.*/
-        @ErrorSeverity, /*-- Severity.*/
-        @ErrorState  /*-- State.*/
-      );
-    END CATCH
-    
-    GOTO_RETURN:
-      ROLLBACK TRAN
-      
-    END`
-
-    Ltext = Ltext.replace(/\n\s{4}/ig, 'mchr13k')
-
-    return Ltext
-  }
-
-  /**
-   * @description 鍒涘缓瀵煎叆瀛樺偍杩囩▼
-   * @return {String}
-   */
-  static getexcelInfunc (param, btn, menu) {
-    let _verify = btn.verify
-
-    let _uniquesql = ''
-    if (_verify.uniques && _verify.uniques.length > 0) {
-      _verify.uniques.forEach(unique => {
-        if (unique.status === 'false') return
-
-        let _fields = unique.field.split(',')
-        let _fields_ = _fields.map(_field => {
-          return `a.${_field}=b.${_field}`
-        })
-        _fields_ = _fields_.join(' and ')
-
-        if (unique.verifyType !== 'physical') {
-          _fields_ += ' and b.deleted=0'
-        }
-
-        _uniquesql += `
-        Set @tbid=''
-        Select top 1 @tbid=${_fields.join('+\' \'+')} from (select 1 as n,${unique.field} from @${btn.sheet} ) a group by ${unique.field} having sum(n)>1
-
-        If @tbid!=''
-        Begin
-          select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 閲嶅'
-          goto aaa
-        end
-
-        Set @tbid=''
-        Select top 1 @tbid=${_fields.join('+\' \'+')} from  @${btn.sheet} a
-        Inner join ${btn.sheet} b on ${_fields_}
-
-        If @tbid!=''
-        Begin
-          select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 涓庡凡鏈夋暟鎹噸澶�'
-          goto aaa
-        end
-        `
-      })
-
-      if (_uniquesql) {
-        _uniquesql = `
-        Declare @tbid Nvarchar(512)
-        ${_uniquesql}`
-      }
-    }
-
-    let declarefields = []
-    let fields = []
-
-    _verify.columns.forEach(col => {
-      declarefields.push(`${col.Column} ${col.type}`)
-      fields.push(col.Column)
-    })
-
-    fields = fields.join(',')
-
-    let _sql = `declare @${btn.sheet} table (${declarefields.join(',')},jskey nvarchar(50))
-      Declare @UserName nvarchar(50),@FullName nvarchar(50)
-      
-      select @UserName=UserName,@FullName=FullName from SUsers where UID=@UserID
-      
-      Insert into @${btn.sheet} (${fields},jskey)
-
-      exec s_KeyWords_Replace
-      @LText=@LText, @BID=@BID,@LoginUID=@LoginUID,@SessionUid=@SessionUid,@UserID=@UserID,@ID=@ID
-      ${_uniquesql}
-      Insert into ${btn.sheet} (${fields},createuserid,createuser,createstaff,bid) 
-      Select ${fields},@userid,@username,@fullname,@BID From @${btn.sheet}
-
-      Delete @${btn.sheet}`
-
-    let Ltext = `create proc ${param.funcName}
-    ( /*${menu.MenuName}  ${btn.label}*/
-      @appkey nvarchar(50)='',
-      @ID nvarchar(50)='',
-      @BID nvarchar(50)='',
-      @Ltext nvarchar(max)='',
-      @sEPTMenuNo nvarchar(50)='${param.menuNo}', 
-      @secretkey nvarchar(50)='',
-      @timestamp nvarchar(50)='',
-      @lang nvarchar(50)='',
-      @LoginUID nvarchar(50)='',
-      @SessionUid nvarchar(50)='',
-      @UserID nvarchar(50), 
-      @ErrorCode nvarchar(50) out,
-      @retmsg nvarchar(4000) out
-    )
-    as
-    begin
-    declare @BegindateTest datetime,@EnddateTest datetime 
-    select @BegindateTest=getdate() 
-    set @ErrorCode=''
-    set @retmsg=''
-    BEGIN TRY
-      /*浜嬪姟鎿嶄綔*/
-      BEGIN TRAN
-        /*鍏蜂綋涓氬姟鎿嶄綔*/
-
-        /* 
-        ${_sql}
-        */
-        
-      COMMIT TRAN
-      SET NOCOUNT ON
-      RETURN
-    END TRY
-    BEGIN CATCH
-      /*閿欒澶勭悊*/
-      ROLLBACK TRAN
-      DECLARE @ErrorMessage NVARCHAR(4000);
-      DECLARE @ErrorSeverity INT;
-      DECLARE @ErrorState INT;
-      
-      /*鎶婅嚜瀹氫箟鐨勫弸濂界殑閿欒淇℃伅鎻愮ず鍔犱笂*/
-      set @ErrorCode=cast(ERROR_NUMBER() as nvarchar(50))
-      SET @retmsg=ERROR_MESSAGE();
-      SELECT @ErrorMessage=ERROR_MESSAGE(),
-        @ErrorSeverity=ERROR_SEVERITY(),
-        @ErrorState=ERROR_STATE();
-        
-      RAISERROR(@ErrorMessage, /*-- Message text.*/
-        @ErrorSeverity, /*-- Severity.*/
-        @ErrorState  /*-- State.*/
-      );
-    END CATCH
-    
-    GOTO_RETURN:
-      ROLLBACK TRAN
-      
-    END`
-
-    Ltext = Ltext.replace(/\n\s{4}/ig, 'mchr13k')
-
-    return Ltext
-  }
-}
\ No newline at end of file
diff --git a/src/utils/utils.js b/src/utils/utils.js
index ce58c46..b1d5fcd 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -727,8 +727,10 @@
 
 /**
  * @description 鑾峰彇excel瀵煎叆鍙傛暟
- * @return {String} btn   鎸夐挳
- * @return {String} data  excel鏁版嵁
+ * @return {Object} item   鎸夐挳淇℃伅
+ * @return {Array}  data   excel鏁版嵁
+ * @return {Object} dict   瀛楀吀椤�
+ * @return {String} BID    涓婄骇Id
  */
 export function getExcelInSql (item, data, dict, BID) {
   let btn = item.verify
@@ -1025,8 +1027,14 @@
 
 /**
  * @description 浣跨敤绯荤粺鍑芥暟鏃讹紙sPC_TableData_InUpDe 锛夛紝鐢熸垚sql璇彞
- * @return {String} type   鎵ц绫诲瀷
- * @return {String} table  琛ㄥ悕
+ * @return {Object}  btn       鎸夐挳淇℃伅
+ * @return {Object}  setting   鑿滃崟鎴栫粍浠舵暟鎹簮璁剧疆
+ * @return {Array}   formdata  琛ㄥ崟
+ * @return {Object}  param     璇锋眰鍙傛暟
+ * @return {Array}   data      鍒楄〃琛屾暟鎹�
+ * @return {Array}   columns   鏄剧ず鍒�
+ * @return {Object}  tab       鏍囩淇℃伅
+ * @return {Boolean} retmsg    鏄惁闇�瑕佹暟鎹繑鍥�
  */
 export function getSysDefaultSql (btn, setting, formdata, param, data, columns, tab, retmsg = false) {
   let primaryId = param.ID
@@ -1681,4 +1689,467 @@
   } else {
     return _sql
   }
+}
+
+/**
+ * @description 鍒涘缓瀛樺偍杩囩▼绫�
+ */
+export class FuncUtils {
+  /**
+   * @description 鍒犻櫎瀛樺偍杩囩▼sql
+   * @return {String} name 瀛樺偍杩囩▼鍚嶇О
+   */
+  static dropfunc (name) {
+    return `IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('${name}') AND type in (N'P', N'PC'))  mdrpk PROCEDURE ${name}`
+  }
+
+  /**
+   * @description 鍒涘缓椤甸潰瀛樺偍杩囩▼
+   * @return {String}
+   */
+  static getTableFunc (param, menu, config) {
+    let form = ''
+    let formParam = ''
+    let _vars = ['bid', 'pageindex', 'pagesize', 'ordercol', 'ordertype', 'exceltype', 'septmenuno', 'lang', 'debug', 'loginuid', 'sessionuid', 'userid', 'errorcode', 'retmsg']
+    let _columns = []
+    let primaryKey = config.setting.primaryKey || 'ID'
+
+    if (!_vars.includes(primaryKey.toLowerCase())) {
+      _vars.push(primaryKey.toLowerCase())
+      formParam = `mchr13k@${primaryKey} nvarchar(50)='',`
+    }
+
+    if (config.search && config.search.length > 0) {
+      let _fields = new Map()
+      config.search.forEach(item => {
+        if (item.field) {
+          let type = ''
+
+          if (item.type.match(/date/ig)) {
+            type = 'datetime=null'
+          } else {
+            type = 'nvarchar(50)=\'\''
+          }
+
+          item.field.split(',').forEach(cell => {
+            let _f = cell
+            if (_fields.has(cell)) {
+              _f = _f + '1'
+            }
+  
+            _fields.set(cell, true)
+
+            if (!_vars.includes(_f.toLowerCase())) {
+              _vars.push(_f.toLowerCase())
+              formParam = formParam + `mchr13k@${_f} ${type},`
+            }
+          })
+        }
+      })
+    }
+
+    if (config.columns && config.columns.length > 0) {
+      config.columns.forEach(item => {
+        if (item.field) {
+          _columns.push(`${item.field} as ${item.label}`)
+        }
+      })
+
+      form = `
+        declare @dc table (${_columns.join(',')})
+        
+        @tableid ='${menu.MenuID}'
+      `
+    }
+
+    let Ltext = `create proc ${param.innerFunc}
+    ( /*${menu.MenuName}*/
+    @appkey nvarchar(50)='',
+    @BID nvarchar(50)='',${formParam}
+    @PageIndex nvarchar(50)='',
+    @PageSize nvarchar(50)='',
+    @OrderCol nvarchar(50)='',
+    @OrderType nvarchar(50)='',
+    @exceltype nvarchar(50)='',
+    @sEPTMenuNo nvarchar(50)='${menu.MenuNo}',
+    @lang nvarchar(50)='',
+    @debug nvarchar(50)='',
+    @LoginUID nvarchar(50)='',
+    @SessionUid nvarchar(50)='',
+    @UserID nvarchar(50),
+    @ErrorCode nvarchar(50) out,
+    @retmsg nvarchar(4000) out
+    )
+    as
+    begin
+    declare  @BegindateTest datetime,@EnddateTest datetime
+    select  @BegindateTest=getdate()
+    set @ErrorCode=''
+    set @retmsg=''
+    BEGIN TRY
+      /*浜嬪姟鎿嶄綔*/
+      BEGIN TRAN
+        /*鍏蜂綋涓氬姟鎿嶄綔*/
+        
+        /* 
+        select top 10 * from sProcExcep order by id desc
+        
+        declare @UserName  nvarchar(50),@FullName nvarchar(50)
+        
+        select @UserName=UserName,@FullName=FullName from SUsers where UID=@UserID
+        ${form}
+        if 1=2
+        begin
+          set @ErrorCode='E'
+          set @retmsg='鍦ㄦ鍐欐姤閿�'
+          goto GOTO_RETURN
+        end
+        
+        insert into sNote (remark,createuserid,CreateUser,CreateStaff)
+        select '鍦ㄦ鍐欐棩蹇�',@UserID,@UserName,@FullName
+        */
+        
+      COMMIT TRAN
+      SET NOCOUNT ON
+      RETURN
+    END TRY
+    BEGIN CATCH
+      /*閿欒澶勭悊*/
+      ROLLBACK TRAN
+      DECLARE @ErrorMessage NVARCHAR(4000);
+      DECLARE @ErrorSeverity INT;
+      DECLARE @ErrorState INT;
+      
+      /*鎶婅嚜瀹氫箟鐨勫弸濂界殑閿欒淇℃伅鎻愮ず鍔犱笂*/
+      set @ErrorCode=cast(ERROR_NUMBER() as nvarchar(50))
+      SET @retmsg=ERROR_MESSAGE();
+      SELECT @ErrorMessage=ERROR_MESSAGE(),
+        @ErrorSeverity=ERROR_SEVERITY(),
+        @ErrorState=ERROR_STATE();
+        
+      RAISERROR(@ErrorMessage, /*-- Message text.*/
+        @ErrorSeverity, /*-- Severity.*/
+        @ErrorState  /*-- State.*/
+      );
+    END CATCH
+    
+    GOTO_RETURN:
+      ROLLBACK TRAN
+      
+    END`
+
+    Ltext = Ltext.replace(/\n\s{4}/ig, 'mchr13k')
+
+    return Ltext
+  }
+
+  /**
+   * @description 鍒涘缓瀛樺偍杩囩▼
+   * @return {String}
+   */
+  static getfunc (param, btn, menu, config) {
+    let form = ''
+    let formParam = ''
+    let _vars = ['bid', 'septmenuno', 'lang', 'debug', 'loginuid', 'sessionuid', 'userid', 'errorcode', 'retmsg']
+    let columns = config.columns
+    let primaryKey = config.setting.primaryKey || 'ID'
+
+    if (!_vars.includes(primaryKey.toLowerCase())) {
+      _vars.push(primaryKey.toLowerCase())
+      let _type = '50'
+      if (btn.Ot === 'requiredOnce') { // 澶氳鎷兼帴鏃讹紝涓婚敭璁句负max
+        _type = 'max'
+      }
+      formParam = `mchr13k@${primaryKey} nvarchar(${_type})='',`
+    }
+
+    if (param.fields && param.fields.length > 0) {
+      let _fields = []
+      param.fields.forEach(item => {
+        if (item.field) {
+          let type = ''
+          if (item.type.match(/date/ig)) {
+            type = 'datetime=null'
+          } else if (item.type === 'number') {
+            type = `decimal(18,${item.decimal})=0`
+          } else {
+            type = 'nvarchar(50)=\'\''
+          }
+
+          if (!_vars.includes(item.field.toLowerCase())) {
+            _vars.push(item.field.toLowerCase())
+            formParam = formParam + `mchr13k@${item.field} ${type},`
+          }
+
+          _fields.push(item.field)
+        }
+      })
+
+      let field1 = _fields.join(',')
+      let field2 = _fields.join(',@')
+      let field3 = _fields.map(cell => {
+        return cell + '=@' + cell
+      })
+
+      field2 = field2 ? '@' + field2 : ''
+      field3 = field3.join(',')
+
+      form = `
+        insert into ${param.name} (${field1},createuserid) select ${field2},@UserID
+        
+        update ${param.name} set ${field3},modifydate=getdate(),modifyuserid=@UserID
+      `
+    } else if (btn.OpenType === 'prompt' || btn.OpenType === 'exec') {
+      form = `
+        update ${param.name} set ModifyDate=getdate(),ModifyUserID=@UserID where ${primaryKey}=@${primaryKey}
+      `
+    }
+
+    if (columns) {
+      let _col = []
+      let _field = []
+      columns.forEach(col => {
+        if (col.field) {
+          if (col.type === 'number') {
+            _col.push(col.field + ' decimal(18,2)')
+          } else {
+            _col.push(col.field + ' nvarchar(50)')
+          }
+          _field.push(col.field)
+        }
+      })
+      _col = _col.join(',')
+      _field = _field.join(',')
+
+      form = form + `
+        declare @dc table (${_col})
+        
+        insert into @dc (${_field})
+
+        @tableid ='${menu.MenuID}'
+      `
+    }
+
+    // 鎵撳嵃鑷畾涔夋ā鏉垮瓧娈垫彁绀�
+    let _printRemark = ''
+    if (btn.funcType === 'print') {
+      _printRemark = '/* 鑷畾涔夋暟鎹墦鍗版ā鏉挎椂锛岃浣跨敤TemplateID瀛楁 */'
+    }
+
+    let Ltext = `create proc ${param.funcName}
+    ( /*${menu.MenuName}  ${btn.label}*/
+    @appkey nvarchar(50)='',
+    @BID nvarchar(50)='',${formParam}
+    @sEPTMenuNo nvarchar(50)='${param.menuNo}',
+    @lang nvarchar(50)='',
+    @debug nvarchar(50)='',
+    @LoginUID nvarchar(50)='',
+    @SessionUid nvarchar(50)='',
+    @UserID nvarchar(50),
+    @ErrorCode nvarchar(50) out,
+    @retmsg nvarchar(4000) out
+    )
+    as
+    begin
+    declare  @BegindateTest datetime,@EnddateTest datetime
+    select  @BegindateTest=getdate()
+    set @ErrorCode=''
+    set @retmsg=''
+    BEGIN TRY
+      /*浜嬪姟鎿嶄綔*/
+      BEGIN TRAN
+        /*鍏蜂綋涓氬姟鎿嶄綔*/
+        ${_printRemark}
+        /* 
+        select top 10 * from sProcExcep order by id desc
+        
+        declare @UserName  nvarchar(50),@FullName nvarchar(50)
+        
+        select @UserName=UserName,@FullName=FullName from SUsers where UID=@UserID
+        ${form}
+        if 1=2
+        begin
+          set @ErrorCode='E'
+          set @retmsg='鍦ㄦ鍐欐姤閿�'
+          goto GOTO_RETURN
+        end
+        
+        insert into sNote (remark,createuserid,CreateUser,CreateStaff)
+        select '鍦ㄦ鍐欐棩蹇�',@UserID,@UserName,@FullName
+        */
+        
+      COMMIT TRAN
+      SET NOCOUNT ON
+      RETURN
+    END TRY
+    BEGIN CATCH
+      /*閿欒澶勭悊*/
+      ROLLBACK TRAN
+      DECLARE @ErrorMessage NVARCHAR(4000);
+      DECLARE @ErrorSeverity INT;
+      DECLARE @ErrorState INT;
+      
+      /*鎶婅嚜瀹氫箟鐨勫弸濂界殑閿欒淇℃伅鎻愮ず鍔犱笂*/
+      set @ErrorCode=cast(ERROR_NUMBER() as nvarchar(50))
+      SET @retmsg=ERROR_MESSAGE();
+      SELECT @ErrorMessage=ERROR_MESSAGE(),
+        @ErrorSeverity=ERROR_SEVERITY(),
+        @ErrorState=ERROR_STATE();
+        
+      RAISERROR(@ErrorMessage, /*-- Message text.*/
+        @ErrorSeverity, /*-- Severity.*/
+        @ErrorState  /*-- State.*/
+      );
+    END CATCH
+    
+    GOTO_RETURN:
+      ROLLBACK TRAN
+      
+    END`
+
+    Ltext = Ltext.replace(/\n\s{4}/ig, 'mchr13k')
+
+    return Ltext
+  }
+
+  /**
+   * @description 鍒涘缓瀵煎叆瀛樺偍杩囩▼
+   * @return {String}
+   */
+  static getexcelInfunc (param, btn, menu) {
+    let _verify = btn.verify
+
+    let _uniquesql = ''
+    if (_verify.uniques && _verify.uniques.length > 0) {
+      _verify.uniques.forEach(unique => {
+        if (unique.status === 'false') return
+
+        let _fields = unique.field.split(',')
+        let _fields_ = _fields.map(_field => {
+          return `a.${_field}=b.${_field}`
+        })
+        _fields_ = _fields_.join(' and ')
+
+        if (unique.verifyType !== 'physical') {
+          _fields_ += ' and b.deleted=0'
+        }
+
+        _uniquesql += `
+        Set @tbid=''
+        Select top 1 @tbid=${_fields.join('+\' \'+')} from (select 1 as n,${unique.field} from @${btn.sheet} ) a group by ${unique.field} having sum(n)>1
+
+        If @tbid!=''
+        Begin
+          select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 閲嶅'
+          goto aaa
+        end
+
+        Set @tbid=''
+        Select top 1 @tbid=${_fields.join('+\' \'+')} from  @${btn.sheet} a
+        Inner join ${btn.sheet} b on ${_fields_}
+
+        If @tbid!=''
+        Begin
+          select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 涓庡凡鏈夋暟鎹噸澶�'
+          goto aaa
+        end
+        `
+      })
+
+      if (_uniquesql) {
+        _uniquesql = `
+        Declare @tbid Nvarchar(512)
+        ${_uniquesql}`
+      }
+    }
+
+    let declarefields = []
+    let fields = []
+
+    _verify.columns.forEach(col => {
+      declarefields.push(`${col.Column} ${col.type}`)
+      fields.push(col.Column)
+    })
+
+    fields = fields.join(',')
+
+    let _sql = `declare @${btn.sheet} table (${declarefields.join(',')},jskey nvarchar(50))
+      Declare @UserName nvarchar(50),@FullName nvarchar(50)
+      
+      select @UserName=UserName,@FullName=FullName from SUsers where UID=@UserID
+      
+      Insert into @${btn.sheet} (${fields},jskey)
+
+      exec s_KeyWords_Replace
+      @LText=@LText, @BID=@BID,@LoginUID=@LoginUID,@SessionUid=@SessionUid,@UserID=@UserID,@ID=@ID
+      ${_uniquesql}
+      Insert into ${btn.sheet} (${fields},createuserid,createuser,createstaff,bid) 
+      Select ${fields},@userid,@username,@fullname,@BID From @${btn.sheet}
+
+      Delete @${btn.sheet}`
+
+    let Ltext = `create proc ${param.funcName}
+    ( /*${menu.MenuName}  ${btn.label}*/
+      @appkey nvarchar(50)='',
+      @ID nvarchar(50)='',
+      @BID nvarchar(50)='',
+      @Ltext nvarchar(max)='',
+      @sEPTMenuNo nvarchar(50)='${param.menuNo}', 
+      @secretkey nvarchar(50)='',
+      @timestamp nvarchar(50)='',
+      @lang nvarchar(50)='',
+      @LoginUID nvarchar(50)='',
+      @SessionUid nvarchar(50)='',
+      @UserID nvarchar(50), 
+      @ErrorCode nvarchar(50) out,
+      @retmsg nvarchar(4000) out
+    )
+    as
+    begin
+    declare @BegindateTest datetime,@EnddateTest datetime 
+    select @BegindateTest=getdate() 
+    set @ErrorCode=''
+    set @retmsg=''
+    BEGIN TRY
+      /*浜嬪姟鎿嶄綔*/
+      BEGIN TRAN
+        /*鍏蜂綋涓氬姟鎿嶄綔*/
+
+        /* 
+        ${_sql}
+        */
+        
+      COMMIT TRAN
+      SET NOCOUNT ON
+      RETURN
+    END TRY
+    BEGIN CATCH
+      /*閿欒澶勭悊*/
+      ROLLBACK TRAN
+      DECLARE @ErrorMessage NVARCHAR(4000);
+      DECLARE @ErrorSeverity INT;
+      DECLARE @ErrorState INT;
+      
+      /*鎶婅嚜瀹氫箟鐨勫弸濂界殑閿欒淇℃伅鎻愮ず鍔犱笂*/
+      set @ErrorCode=cast(ERROR_NUMBER() as nvarchar(50))
+      SET @retmsg=ERROR_MESSAGE();
+      SELECT @ErrorMessage=ERROR_MESSAGE(),
+        @ErrorSeverity=ERROR_SEVERITY(),
+        @ErrorState=ERROR_STATE();
+        
+      RAISERROR(@ErrorMessage, /*-- Message text.*/
+        @ErrorSeverity, /*-- Severity.*/
+        @ErrorState  /*-- State.*/
+      );
+    END CATCH
+    
+    GOTO_RETURN:
+      ROLLBACK TRAN
+      
+    END`
+
+    Ltext = Ltext.replace(/\n\s{4}/ig, 'mchr13k')
+
+    return Ltext
+  }
 }
\ No newline at end of file
diff --git a/src/views/design/header/index.jsx b/src/views/design/header/index.jsx
new file mode 100644
index 0000000..ddc65dd
--- /dev/null
+++ b/src/views/design/header/index.jsx
@@ -0,0 +1,388 @@
+import React, {Component} from 'react'
+import { withRouter } from 'react-router-dom'
+import {connect} from 'react-redux'
+import { is, fromJS } from 'immutable'
+import { Dropdown, Menu, Icon, Modal, Form, notification, Switch, Button } from 'antd'
+
+import asyncComponent from '@/utils/asyncComponent'
+import {
+  modifyMenuTree,
+  modifyMainMenu,
+  modifyTabview,
+  resetEditLevel,
+  logout
+} from '@/store/action'
+import Api from '@/api'
+import options from '@/store/options.js'
+import zhCN from '@/locales/zh-CN/main.js'
+import enUS from '@/locales/en-US/main.js'
+import Utils from '@/utils/utils.js'
+import avatar from '@/assets/img/avatar.jpg'
+import MainLogo from '@/assets/img/main-logo.png'
+import './index.scss'
+
+const EditMenu = asyncComponent(() => import('@/templates/menuconfig/editfirstmenu'))
+const { confirm } = Modal
+
+class Header extends Component {
+  state = {
+    menulist: null, // 涓�绾ц彍鍗�
+    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
+    userName: sessionStorage.getItem('CloudUserName'),
+    avatar: Utils.getrealurl(sessionStorage.getItem('CloudAvatar')),
+  }
+
+  logout = () => {
+    // 閫�鍑虹櫥褰�
+    let _this = this
+    confirm({
+      title: this.state.dict['main.logout.hint'],
+      content: '',
+      onOk() {
+        sessionStorage.clear()
+        _this.props.logout()
+        _this.props.history.replace('/login')
+      },
+      onCancel() {}
+    })
+  }
+
+  changeMenu (value) {
+    // 涓昏彍鍗曞垏鎹�
+    if (this.props.editLevel) {
+      // 缂栬緫鐘舵�佷笅锛屼笉鍙垏鎹㈣彍鍗�
+      return
+    }
+    if (value.PageParam.OpenType === 'menu') {
+      this.props.modifyMainMenu(value)
+    } else if (value.PageParam.OpenType === 'outpage') {
+      window.open(value.PageParam.linkUrl)
+    }
+  }
+
+  async loadmenu () {
+    // 鑾峰彇涓昏彍鍗�
+    let _param = {func: 's_get_pc_menus', systemType: options.sysType, debug: 'Y'}
+
+    if (options.sysType !== 'cloud' && window.GLOB.systemType !== 'production') {
+      _param.linkurl = window.GLOB.linkurl
+    }
+    _param.pro_sys = window.GLOB.systemType === 'production' ? 'Y' : ''
+
+    let result = await Api.getSystemConfig(_param)
+
+    // 鐧诲綍瓒呮椂
+    if (!result) return
+
+    if (result.status) {
+      const { menulist } = this.getMenulist(result)
+
+      this.setState({ menulist })
+
+      this.props.modifyMenuTree(menulist)
+      if (window.GLOB.systemType !== 'production') { // 闈炴寮忕郴缁熼�夋嫨绗竴椤�
+        this.props.modifyMainMenu(menulist[0] || null)
+      }
+    } else {
+      notification.error({
+        top: 92,
+        message: result.message,
+        duration: 10
+      })
+    }
+  }
+
+  getMenulist = (result) => {
+    let iframes = ['Main/Index', 'bda/rdt', 'Home/rdt']
+    let menulist = []
+    result.fst_menu && result.fst_menu.forEach(fst => {
+      let fstItem = {
+        MenuID: fst.MenuID,
+        MenuName: fst.MenuName,
+        PageParam: {OpenType: 'menu', linkUrl: ''},
+        children: []
+      }
+      if (fst.PageParam) {
+        try {
+          fstItem.PageParam = JSON.parse(fst.PageParam)
+        } catch (e) {
+          fstItem.PageParam = {OpenType: 'menu', linkUrl: ''}
+        }
+      }
+
+      if (fst.snd_menu) {
+        fstItem.children = fst.snd_menu.map(snd => {
+          let sndItem = {
+            ParentId: fst.MenuID,
+            MenuID: snd.MenuID,
+            MenuName: snd.MenuName,
+            PageParam: {Icon: 'folder'},
+            children: []
+          }
+
+          if (snd.PageParam) {
+            try {
+              sndItem.PageParam = JSON.parse(snd.PageParam)
+            } catch (e) {
+              sndItem.PageParam = {Icon: 'folder'}
+            }
+          }
+
+          if (snd.trd_menu) {
+            sndItem.children = snd.trd_menu.map(trd => {
+              let trdItem = {
+                FstId: fst.MenuID,
+                ParentId: snd.MenuID,
+                MenuID: trd.MenuID,
+                MenuName: trd.MenuName,
+                MenuNo: trd.MenuNo,
+                EasyCode: trd.EasyCode,
+                type: 'CommonTable',            // 榛樿鍊间负甯哥敤琛�
+                OpenType: 'newtab'              // 鎵撳紑鏂瑰紡
+              }
+  
+              if (trd.LinkUrl && iframes.includes(trd.LinkUrl.split('?')[0])) {
+                trdItem.type = 'iframe'
+                trdItem.LinkUrl = trd.LinkUrl
+                trdItem.forbidden = true
+              } else {
+                try {
+                  trdItem.PageParam = trd.PageParam ? JSON.parse(trd.PageParam) : {OpenType: 'newtab'}
+                } catch (e) {
+                  trdItem.PageParam = {OpenType: 'newtab'}
+                }
+
+                trdItem.type = trdItem.PageParam.Template || trdItem.type
+                trdItem.OpenType = trdItem.PageParam.OpenType || trdItem.OpenType
+
+                if (trdItem.type === 'CustomPage' && this.props.memberLevel < 20) { // 浼氬憳绛夌骇澶т簬绛変簬20鏃讹紝鏈夌紪杈戞潈闄�
+                  trdItem.forbidden = true
+                }
+              }
+
+              return trdItem
+            })
+          }
+
+          return sndItem
+        })
+      }
+
+      menulist.push(fstItem)
+    })
+
+    return { menulist }
+  }
+
+  reload = () => {
+    this.loadmenu()
+  }
+
+  changeEditState = () => {
+    this.props.history.replace('/main')
+    window.location.reload()
+  }
+
+  enterEdit = () => {
+    // 杩涘叆缂栬緫鐘舵��
+    this.props.resetEditLevel('level1')
+  }
+
+  enterEditManage = () => {
+    const { editLevel } = this.props
+
+    if (editLevel === 'HS')  return
+
+    this.props.resetEditLevel('HS')
+    this.props.modifyMainMenu({
+      MenuID: 'systemManageView'
+    })
+  }
+
+  /**
+   * @description 閫�鍑虹鐞嗙晫闈㈣彍鍗�
+   */
+  exitManage = () => {
+    const { menulist } = this.state
+
+    if (window.GLOB.systemType === 'production') { // 姝e紡绯荤粺鐗堟湰鍗囩骇鍚庯紝椤甸潰鍒锋柊
+      this.props.history.replace('/main')
+      window.location.reload()
+      return
+    }
+
+    this.props.modifyMainMenu(menulist[0] || null)
+    this.props.resetEditLevel(false)
+    this.props.modifyTabview([])
+  }
+  
+  exitEdit = () => {
+    // 閫�鍑虹紪杈戠姸鎬�
+    this.props.resetEditLevel(false)
+  }
+  
+  UNSAFE_componentWillMount () {
+    sessionStorage.setItem('isEditState', 'true')
+    document.body.className = ''
+    
+    // 缁勪欢鍔犺浇鏃讹紝鑾峰彇鑿滃崟鏁版嵁
+    this.loadmenu()
+  }
+
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    if (!is(fromJS(this.props.menuTree), fromJS(nextProps.menuTree)) && !is(fromJS(this.state.menulist), fromJS(nextProps.menuTree))) {
+      this.setState({
+        menulist: nextProps.menuTree
+      })
+    }
+  }
+
+  componentDidMount () {
+    if (window.GLOB.systemType !== 'production') {
+      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))
+        }
+      })
+    } else if (window.GLOB.systemType === 'production') {
+      this.props.resetEditLevel('HS')
+      this.props.modifyMainMenu({
+        MenuID: 'systemManageView'
+      })
+    }
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  gotoDoc = () => {
+    if (options.sysType === 'local' && window.GLOB.mainSystemApi) {
+      let ssodomain = window.GLOB.mainSystemApi.replace('/webapi/dostars', '')
+      let url = `${ssodomain}/doc/index.html#?appkey=${window.GLOB.appkey}&LoginUID=${sessionStorage.getItem('LoginUID')}`
+      window.open(url)
+    } else if (options.sysType === 'SSO' || options.sysType === 'cloud') {
+      window.open(`${window.location.href.replace(/\/index.html(.*)|\/#(.*)/ig, '')}/doc/index.html#?appkey=${window.GLOB.appkey}&LoginUID=${sessionStorage.getItem('LoginUID')}`)
+    }
+  }
+
+  render () {
+    const { mainMenu } = this.props
+    const { menulist } = this.state
+
+    const menu = (
+      <Menu className="header-dropdown">
+        <Menu.Item key="switch">
+          {this.state.dict['main.edit']}
+          <Switch size="small" style={{marginLeft: '7px'}} disabled={!!this.props.editLevel} checked={true} onChange={this.changeEditState} />
+        </Menu.Item>
+        <Menu.Item key="doc" onClick={this.gotoDoc}>{this.state.dict['main.doc']}</Menu.Item>
+        <Menu.Item key="logout" onClick={this.logout}>{this.state.dict['main.logout']}</Menu.Item>
+      </Menu>
+    )
+
+    return (
+      <header className={'sys-header-container ant-menu-dark ' + (this.props.editLevel === 'level2' || this.props.editLevel === 'level3' ? 'mask' : '')} id="main-header-container">
+        <div className="header-logo"><img src={MainLogo} alt=""/></div>
+        <div className="header-collapse">
+          <Icon type="menu-fold"/>
+        </div>
+        {/* 姝e父鑿滃崟 */}
+        {this.props.editLevel !== 'level1' && menulist ?
+          <ul className={'header-menu ' + this.props.editLevel}>{
+            menulist.map(item => {
+              return (
+                <li key={item.MenuID} onClick={() => {this.changeMenu(item)}} className={mainMenu && mainMenu.MenuID === item.MenuID ? 'active' : ''}>
+                  <span>{item.MenuName}</span>
+                </li>
+              )
+            })}
+            {!this.props.editLevel || this.props.editLevel === 'HS' ?
+              <li key="HS" onClick={this.enterEditManage} className={this.props.editLevel === 'HS' ? 'active' : ''}>
+                <span>HS</span>
+              </li> : null
+            }
+          </ul> : null
+        }
+        {this.props.editLevel === 'HS' ? <Button className="level4-close" type="primary" onClick={this.exitManage}>閫�鍑�</Button> : null}
+        {/* 杩涘叆缂栬緫鎸夐挳 */}
+        {!this.props.editLevel ? <Icon onClick={this.enterEdit} className="edit-check" type="edit" /> : null}
+        {/* {!this.props.editLevel && options.sysType === 'local' && window.GLOB.systemType !== 'production' ?
+          <a href="#/mobmanage" 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: '棣栭〉' }))) */}
+        {!this.props.editLevel && window.GLOB.systemType !== 'production' && this.props.memberLevel >= 20 ?
+          <a className="home-edit" href={`#/menudesign/JTdCJTIyTWVudVR5cGUlMjIlM0ElMjJob21lJTIyJTJDJTIyTWVudUlkJTIyJTNBJTIyaG9tZV9wYWdlX2lkJTIyJTJDJTIyTWVudU5hbWUlMjIlM0ElMjIlRTklQTYlOTYlRTklQTElQjUlMjIlN0Q=`} target="_blank" rel="noopener noreferrer">
+            棣栭〉 <Icon type="arrow-right" />
+          </a> : null
+        }
+        {/* 缂栬緫鑿滃崟 */}
+        {this.props.editLevel === 'level1' ? <EditMenu menulist={this.state.menulist} reload={this.reload} exitEdit={this.exitEdit}/> : null}
+        {/* 澶村儚銆佺敤鎴峰悕 */}
+        <Dropdown className="header-setting" overlay={menu}>
+          <div>
+            <img src={this.state.avatar || avatar} alt=""/>
+            <span>
+              <span className="username">{this.state.userName}</span> <Icon type="down" />
+            </span>
+          </div>
+        </Dropdown>
+      </header>
+    )
+  }
+}
+
+const mapStateToProps = (state) => {
+  return {
+    tabviews: state.tabviews,
+    menuTree: state.menuTree,
+    mainMenu: state.mainMenu,
+    editLevel: state.editLevel,
+    permAction: state.permAction,
+    memberLevel: state.memberLevel
+  }
+}
+
+const mapDispatchToProps = (dispatch) => {
+  return {
+    modifyTabview: (tabviews) => dispatch(modifyTabview(tabviews)),
+    modifyMenuTree: (menuTree) => dispatch(modifyMenuTree(menuTree)),
+    modifyMainMenu: (mainMenu) => dispatch(modifyMainMenu(mainMenu)),
+    resetEditLevel: (level) => dispatch(resetEditLevel(level)),
+    logout: () => dispatch(logout())
+  }
+}
+
+export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Form.create()(Header)))
\ No newline at end of file
diff --git a/src/views/design/header/index.scss b/src/views/design/header/index.scss
new file mode 100644
index 0000000..f26213a
--- /dev/null
+++ b/src/views/design/header/index.scss
@@ -0,0 +1,207 @@
+.sys-header-container {
+  position: fixed;
+  z-index: 20;
+  left: 0;
+  top: 0;
+  font-weight: bold!important;
+  width: 100%;
+  height: 48px;
+
+  .header-logo {
+    float: left;
+    width: 180px;
+    line-height: 48px;
+    text-align: center;
+    padding-left: 5px;
+    box-sizing: border-box;
+    opacity: 1;
+    transition: width 0.2s, opacity 0.15s;
+    img {
+      max-width: 100%;
+      max-height: 40px;
+    }
+  }
+
+  .header-collapse {
+    float: left;
+    width: 35px;
+    min-height: 48px;
+    line-height: 48px;
+    padding-left: 10px;
+    margin: 0 10px;
+    transition: padding-left 0.15s;
+    i {
+      cursor: pointer;
+      position: relative;
+      top: 3px;
+      font-size: 20px;
+      color: #ffffff;
+    }
+  }
+  .header-menu {
+    float: left;
+    margin: 0;
+    line-height: 48px;
+    li {
+      float: left;
+      font-size: 1.3rem;
+      cursor: pointer;
+      span {
+        padding: 0 10px;
+        height: 42px;
+        display: inline-block;
+      }
+
+      &:hover {
+        color: #eeeeee;
+        span {
+          border-bottom: 4px solid #fafcfb;
+        }
+      }
+      &.active {
+        color: #ffffff;
+        span {
+          border-bottom: 4px solid #1890ff;
+        }
+      }
+    }
+  }
+
+  .header-menu.level4 {
+    li {
+      cursor: default;
+      &:hover {
+        span {
+          cursor: default;
+          color: rgba(255, 255, 255, 0.65);
+          border-bottom: none;
+        }
+      }
+      &.active {
+        span {
+          color: #ffffff;
+          border-bottom: 4px solid #1890ff;
+        }
+      }
+    }
+  }
+
+  .header-setting {
+    float: right;
+    line-height: 48px;
+    margin-right: 10px;
+    img {
+      width: 29px;
+      height: 29px;
+      border-radius: 30px;
+      margin-right: 7px;
+    }
+    span {
+      color: #ffffff;
+      font-size: 0.95rem;
+      .username {
+        display: inline-block;
+        height: 30px;
+        max-width: 95px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+    }
+  }
+  .edit-check {
+    font-size: 18px;
+    margin-top: 14px;
+    margin-left: 10px;
+    cursor: pointer;
+  }
+  .search-menu {
+    float: right;
+    font-size: 18px;
+    margin-top: 17px;
+    margin-right: 20px;
+    cursor: pointer;
+  }
+  .level4-close {
+    position: relative;
+    top: 13px;
+    left: 20px;
+    height: 26px;
+    padding: 0 10px;
+  }
+  .menu-select-dropdown {
+    top: 48px!important;
+    box-shadow: 0px 0px 2px #cdcdcd;
+    border-radius: 0 0 4px 4px;
+    background: #ffffff;
+    .ant-input-affix-wrapper {
+      margin-top: 2px;
+    }
+    .menu-select-box {
+      max-height: 200px;
+      min-height: 50px;
+      overflow-y: auto;
+      background: #ffffff;
+      margin-bottom: 3px;
+      .ant-menu {
+        border-radius: 0 0 4px 4px;
+      }
+      .ant-menu-item {
+        padding: 0px 25px;
+        height: 26px;
+        line-height: 26px;
+        color: rgba(0, 0, 0, 0.85);
+        cursor: pointer;
+      }
+      .ant-menu-item:hover {
+        background-color: #e6f7ff;
+      }
+    }
+    .menu-select-box::-webkit-scrollbar {
+      width: 7px;
+    }
+    .menu-select-box::-webkit-scrollbar-thumb {
+      border-radius: 5px;
+      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
+      background: rgba(0, 0, 0, 0.13);
+    }
+    .menu-select-box::-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);
+    }
+  }
+  .mobile {
+    position: absolute;
+    top: 135px;
+    right: 50px;
+    color: #1890ff;
+  }
+  .home-edit {
+    position: absolute;
+    top: 100px;
+    right: 50px;
+    color: #1890ff;
+  }
+}
+.sys-header-container.mask::after {
+  content: ' ';
+  display: block;
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+}
+.header-dropdown {
+  >li {
+    padding: 5px 25px;
+  }
+  >li.ant-dropdown-menu-submenu {
+    padding: 0px;
+    .ant-dropdown-menu-submenu-title {
+      padding: 5px 25px;
+    }
+  }
+}
diff --git a/src/views/design/index.jsx b/src/views/design/index.jsx
new file mode 100644
index 0000000..3f4b752
--- /dev/null
+++ b/src/views/design/index.jsx
@@ -0,0 +1,29 @@
+import React, {Component} from 'react'
+import { ConfigProvider } from 'antd'
+import enUS from 'antd/es/locale/en_US'
+import zhCN from 'antd/es/locale/zh_CN'
+
+import asyncComponent from '@/utils/asyncComponent'
+import Header from './header'
+import Sidemenu from './sidemenu'
+
+import './index.scss'
+
+const Tabview = asyncComponent(() => import('@/components/tabview'))
+const _locale = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
+
+class Design extends Component {
+  render () {
+    return (
+      <div className="mk-main-view">
+        <ConfigProvider locale={_locale}>
+          <Header key="header"/>
+          <Sidemenu key="sidemenu"/>
+          <Tabview key="tabview"/>
+        </ConfigProvider>
+      </div>
+    )
+  }
+}
+
+export default Design
\ No newline at end of file
diff --git a/src/views/design/index.scss b/src/views/design/index.scss
new file mode 100644
index 0000000..c14dc8e
--- /dev/null
+++ b/src/views/design/index.scss
@@ -0,0 +1,5 @@
+.mk-main-view {
+  display: flex;
+  flex: auto;
+  min-height: 100%;
+}
\ No newline at end of file
diff --git a/src/components/sidemenu/config.jsx b/src/views/design/sidemenu/config.jsx
similarity index 96%
rename from src/components/sidemenu/config.jsx
rename to src/views/design/sidemenu/config.jsx
index c7b95af..1ec2bae 100644
--- a/src/components/sidemenu/config.jsx
+++ b/src/views/design/sidemenu/config.jsx
@@ -90,13 +90,13 @@
     MenuID: '1602315375262ikd33ii0nii34pt861o',
     MenuNo: 's_worksflow_roleM',
     MenuName: '鍏抽敭瑙掕壊绠$悊',
-  }, {
-    src: '',
-    PageParam: {OpenType: 'newtab', Template: 'ManageTable'},
-    type: 'ManageTable',
-    MenuID: '1606794243739c5ihs58lucpskp3r4s2',
-    MenuNo: 's_custom_componentsM',
-    MenuName: '鑷畾涔夌粍浠�',
+  // }, {
+  //   src: '',
+  //   PageParam: {OpenType: 'newtab', Template: 'ManageTable'},
+  //   type: 'ManageTable',
+  //   MenuID: '1606794243739c5ihs58lucpskp3r4s2',
+  //   MenuNo: 's_custom_componentsM',
+  //   MenuName: '鑷畾涔夌粍浠�',
   }]
 }, {
   MenuID: 'systemManageViewInterface',
diff --git a/src/views/design/sidemenu/index.jsx b/src/views/design/sidemenu/index.jsx
new file mode 100644
index 0000000..925abe2
--- /dev/null
+++ b/src/views/design/sidemenu/index.jsx
@@ -0,0 +1,326 @@
+import React, {Component} from 'react'
+import { connect } from 'react-redux'
+import { is, fromJS } from 'immutable'
+import { Menu, Icon, notification } from 'antd'
+
+import asyncComponent from '@/utils/asyncComponent'
+import { modifyTabview, resetEditLevel, modifyMenuTree, modifyMainMenu } from '@/store/action'
+import { SySMenuList } from './config'
+import options from '@/store/options.js'
+import zhCN from '@/locales/zh-CN/main.js'
+import enUS from '@/locales/en-US/main.js'
+import Api from '@/api'
+import './index.scss'
+
+const EditSecMenu = asyncComponent(() => import('@/templates/menuconfig/editsecmenu'))
+const EditThdMenu = asyncComponent(() => import('@/templates/menuconfig/editthdmenu'))
+const { SubMenu } = Menu
+
+class Sidemenu extends Component {
+  state = {
+    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
+    subMenulist: [],         // 浜岀骇鑿滃崟
+    editMenu: null,          // 缂栬緫涓夌骇鑿滃崟鏃惰缃�
+    rootSubmenuKeys: null,
+    openKeys: null,
+    preview: null
+  }
+
+  async loadsubmenu (menu) {
+    if (!menu || !menu.MenuID) { // 娌℃湁涓昏彍鍗曟椂锛屾竻绌轰笅绾ц彍鍗�
+      this.setState({
+        subMenulist: [],
+        rootSubmenuKeys: [],
+        openKeys: [],
+        editMenu: null
+      })
+      return
+    }
+
+    menu = fromJS(menu).toJS()
+    let openKey = ''
+
+    if (menu.children[0]) {
+      openKey = menu.openId || menu.children[0].MenuID
+    }
+
+    this.setState({
+      subMenulist: menu.children,
+      rootSubmenuKeys: menu.children.map(item => item.MenuID),
+      openKeys: openKey ? [openKey] : [],
+      editMenu: this.props.editLevel === 'level3' ? menu.children.filter(_menu => _menu.MenuID === this.state.editMenu.MenuID)[0] : null
+    })
+  }
+
+  enterManageView = () => {
+    let menulist = SySMenuList
+
+    if (window.GLOB.systemType === 'production') {
+      menulist.forEach(menu => {
+        menu.children = menu.children.filter(item => item.systems && item.systems.includes(window.GLOB.systemType))
+      })
+
+      menulist = menulist.filter(menu => menu.children.length > 0)
+    } else {
+      menulist.forEach(menu => {
+        menu.children = menu.children.filter(item => !item.systems || item.systems.includes(options.sysType))
+      })
+
+      menulist = menulist.filter(menu => menu.children.length > 0)
+    }
+
+    this.setState({
+      subMenulist: menulist,
+      rootSubmenuKeys: menulist.map(item => item.MenuID),
+      openKeys: [menulist[0].MenuID]
+    })
+  }
+
+  changemenu(e, menu) {
+    e.preventDefault()
+    if (this.props.editLevel !== 'HS') {
+      return
+    }
+
+    let tabs = fromJS(this.props.tabviews).toJS()
+    tabs = tabs.filter(tab => {
+      tab.selected = false
+      return tab.MenuID !== menu.MenuID
+    })
+
+    if (this.props.tabviews.length !== tabs.length) {
+      this.props.modifyTabview(fromJS(tabs).toJS())
+    }
+
+    this.setState({}, () => {
+      menu.selected = true
+      tabs.push(menu)
+      this.props.modifyTabview(tabs)
+    })
+  }
+
+  UNSAFE_componentWillReceiveProps (nextProps) {
+    if (!is(fromJS(this.props.mainMenu), fromJS(nextProps.mainMenu)) && nextProps.mainMenu && nextProps.mainMenu.MenuID === 'systemManageView') {
+      this.enterManageView()
+    } else if (!is(fromJS(this.props.mainMenu), fromJS(nextProps.mainMenu))) {
+      // 涓昏彍鍗曞垏鎹紝璇锋眰2銆�3绾ц彍鍗曟暟鎹�
+      this.loadsubmenu(nextProps.mainMenu)
+    }
+  }
+
+  shouldComponentUpdate(nextProps, nextState) {
+    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  onOpenChange = openKeys => {
+    const latestOpenKey = openKeys.find(key => this.state.openKeys.indexOf(key) === -1)
+    if (this.state.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
+      this.setState({ openKeys })
+    } else {
+      this.setState({
+        openKeys: latestOpenKey ? [latestOpenKey] : []
+      })
+    }
+  }
+
+  enterSubEdit = (e) => {
+    // 缂栬緫浜岀骇鑿滃崟
+    e.stopPropagation()
+    this.props.resetEditLevel('level2')
+  }
+
+  enterThrEdit = (e, menu) => {
+    // 缂栬緫涓夌骇鑿滃崟
+    e.stopPropagation()
+    this.props.resetEditLevel('level3')
+    this.setState({editMenu: menu})
+  }
+
+  reload = () => {
+    const { mainMenu } = this.props
+    let _param = {func: 's_get_pc_menus', systemType: options.sysType, debug: 'Y'}
+    if (options.sysType !== 'cloud' && window.GLOB.systemType !== 'production') {
+      _param.linkurl = window.GLOB.linkurl
+    }
+    _param.pro_sys = window.GLOB.systemType === 'production' ? 'Y' : ''
+
+    Api.getSystemConfig(_param).then(result => {
+      // 鐧诲綍瓒呮椂
+      if (!result) return
+  
+      if (result.status) {
+        let res = this.getMenulist(result)
+        let _mainMenu = res.menulist.filter(item => item.MenuID === mainMenu.MenuID)[0]
+  
+        this.props.modifyMenuTree(res.menulist)
+        this.props.modifyMainMenu(_mainMenu || null)
+      } else {
+        notification.error({
+          top: 92,
+          message: result.message,
+          duration: 10
+        })
+      }
+      this.loadsubmenu(this.props.mainMenu)
+    })
+  }
+
+  getMenulist = (result) => {
+    let iframes = ['Main/Index', 'bda/rdt', 'Home/rdt']
+    let menulist = result.fst_menu.map(fst => {
+      let fstItem = {
+        MenuID: fst.MenuID,
+        MenuName: fst.MenuName,
+        PageParam: {OpenType: 'menu', linkUrl: ''},
+        children: []
+      }
+      if (fst.PageParam) {
+        try {
+          fstItem.PageParam = JSON.parse(fst.PageParam)
+        } catch (e) {
+          fstItem.PageParam = {OpenType: 'menu', linkUrl: ''}
+        }
+      }
+
+      if (fst.snd_menu) {
+        fstItem.children = fst.snd_menu.map(snd => {
+          let sndItem = {
+            ParentId: fst.MenuID,
+            MenuID: snd.MenuID,
+            MenuName: snd.MenuName,
+            PageParam: {Icon: 'folder'},
+            children: []
+          }
+
+          if (snd.PageParam) {
+            try {
+              sndItem.PageParam = JSON.parse(snd.PageParam)
+            } catch (e) {
+              sndItem.PageParam = {Icon: 'folder'}
+            }
+          }
+
+          if (snd.trd_menu) {
+            sndItem.children = snd.trd_menu.map(trd => {
+              let trdItem = {
+                FstId: fst.MenuID,
+                ParentId: snd.MenuID,
+                MenuID: trd.MenuID,
+                MenuName: trd.MenuName,
+                MenuNo: trd.MenuNo,
+                EasyCode: trd.EasyCode,
+                type: 'CommonTable',            // 榛樿鍊间负甯哥敤琛�
+                OpenType: 'newtab'              // 鎵撳紑鏂瑰紡
+              }
+  
+              if (trd.LinkUrl && iframes.includes(trd.LinkUrl.split('?')[0])) {
+                trdItem.type = 'iframe'
+                trdItem.LinkUrl = trd.LinkUrl
+                trdItem.forbidden = true
+              } else {
+                try {
+                  trdItem.PageParam = trd.PageParam ? JSON.parse(trd.PageParam) : {OpenType: 'newtab'}
+                } catch (e) {
+                  trdItem.PageParam = {OpenType: 'newtab'}
+                }
+
+                trdItem.type = trdItem.PageParam.Template || trdItem.type
+                trdItem.OpenType = trdItem.PageParam.OpenType || trdItem.OpenType
+
+                if (trdItem.type === 'CustomPage' && this.props.memberLevel < 20) { // 浼氬憳绛夌骇澶т簬绛変簬20鏃讹紝鏈夌紪杈戞潈闄�
+                  trdItem.forbidden = true
+                }
+              }
+              return trdItem
+            })
+          }
+          return sndItem
+        })
+      }
+      return fstItem
+    })
+
+    return { menulist }
+  }
+
+  exitEdit = () => {
+    if (this.props.editLevel === 'level3') {
+      this.setState({editMenu: null})
+    }
+    this.props.resetEditLevel(false)
+  }
+
+  render () {
+    return (
+      <aside id="mk-sidemenu-wrap" className="mk-sys-side-menu ant-menu-dark mk-edit">
+        {!(this.props.editLevel === 'level2' || this.props.editLevel === 'level3') &&
+          <Menu openKeys={this.state.openKeys} onOpenChange={this.onOpenChange} mode="inline" theme="dark">
+          {!this.props.editLevel && <li className="sup-menu"><Icon onClick={this.enterSubEdit} className="edit-check" type="edit" /></li>}
+          {this.state.subMenulist && this.state.subMenulist.map((item, index) => {
+            return (
+              <SubMenu
+                key={item.MenuID}
+                title={
+                  <span className={!this.props.editLevel && index === 0 ? 'edit-control' : ''}>
+                    <Icon type={item.PageParam.Icon} />
+                    <span>{item.MenuName}</span>
+                  </span>
+                }
+              >
+                {!this.props.editLevel ? <li className={'ant-menu-item ' + (item.children.length > 0 ? 'sub-menu' : '')}>
+                  <Icon onClick={(e) => {this.enterThrEdit(e, item)}} className="edit-check" type="edit" />
+                </li> : null}
+                {item.children.map(cell => {
+                  return (
+                    <Menu.Item key={cell.MenuID}>
+                      <a href={cell.src} id={cell.MenuID} onClick={(e) => this.changemenu(e, cell)}>{cell.MenuName}</a>
+                    </Menu.Item>
+                  )
+                })}
+              </SubMenu>
+            )
+          })}
+        </Menu>}
+        {this.props.editLevel === 'level2' ?
+          <EditSecMenu
+            menulist={this.state.subMenulist}
+            menuTree={this.props.menuTree}
+            supMenu={this.props.mainMenu}
+            reload={this.reload}
+            exitEdit={this.exitEdit}
+          /> : null
+        }
+        {this.props.editLevel === 'level3' && this.state.editMenu ?
+          <EditThdMenu
+            menulist={this.state.editMenu.children}
+            supMenuList={this.state.subMenulist}
+            supMenu={this.state.editMenu}
+            reload={this.reload}
+            exitEdit={this.exitEdit}
+          /> : null
+        }
+      </aside>
+    )
+  }
+}
+
+const mapStateToProps = (state) => {
+  return {
+    tabviews: state.tabviews,
+    mainMenu: state.mainMenu,
+    menuTree: state.menuTree,
+    memberLevel: state.memberLevel,
+    editLevel: state.editLevel
+  }
+}
+
+const mapDispatchToProps = (dispatch) => {
+  return {
+    modifyMenuTree: (menuTree) => dispatch(modifyMenuTree(menuTree)),
+    modifyMainMenu: (mainMenu) => dispatch(modifyMainMenu(mainMenu)),
+    modifyTabview: (tabviews) => dispatch(modifyTabview(tabviews)),
+    resetEditLevel: (level) => dispatch(resetEditLevel(level))
+  }
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(Sidemenu)
\ No newline at end of file
diff --git a/src/views/design/sidemenu/index.scss b/src/views/design/sidemenu/index.scss
new file mode 100644
index 0000000..c3e8ff7
--- /dev/null
+++ b/src/views/design/sidemenu/index.scss
@@ -0,0 +1,119 @@
+@import '../../../assets/css/iconfont.css';
+
+.mk-sys-side-menu {
+  flex: 0 0 235px;
+  width: 235px;
+  padding: 48px 0 40px;
+  transition: width 0.2s, flex 0.2s;
+  .ant-menu-item {
+    padding-left: 0!important;
+    cursor: default;
+    a {
+      padding-left: 48px;
+    }
+  }
+  .ant-menu-sub.ant-menu-inline {
+    position: relative;
+  }
+  .ant-menu-sub.ant-menu-inline > .ant-menu-item {
+    height: 38px;
+    line-height: 38px;
+    margin: 0px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    a {
+      display: inline-block;
+    }
+    .edit-check {
+      top: -5px;
+    }
+  }
+  .ant-menu-sub.ant-menu-inline > .ant-menu-item.ant-menu-item-active {
+    background: #06b4f7;
+  }
+  .ant-menu-sub.ant-menu-inline > .ant-menu-item.ant-menu-item-selected {
+    background: #06b4f7;
+  }
+  .ant-menu-inline .ant-menu-item {
+    font-size: 1.1rem;
+  }
+  .ant-menu-dark.ant-menu-inline .ant-menu-submenu-title {
+    margin: 0;
+    height: 48px;
+    line-height: 48px;
+  }
+  .ant-menu-dark.ant-menu-inline .ant-menu-submenu-open .ant-menu-submenu-title {
+    background: #364150;
+  }
+  .edit-check {
+    font-size: 18px;
+    position: absolute;
+    cursor: pointer;
+    padding: 10px 15px;
+    margin-right: 0px;
+    right: 0px;
+    top: 0px;
+    :hover {
+      color: #ffffff;
+    }
+  }
+  .edit-control + .ant-menu-submenu-arrow {
+    display: none;
+  }
+  .menu-add {
+    position: relative;
+    border: 1px dashed gray;
+    margin: 8px 0px;
+    height: 40px;
+    line-height: 40px;
+    width: 98%;
+    clear: both;
+    text-align: center;
+    cursor: pointer;
+    .anticon {
+      font-size: 20px;
+    }
+  }
+  .menu-btn {
+    .ant-btn {
+      padding: 0 10px;
+      margin-left: 5px;
+    }
+  }
+  .sup-menu {
+    position: relative;
+    z-index: 1;
+  }
+  .ant-menu-sub.ant-menu-inline .sub-menu {
+    position: absolute;
+    z-index: 1;
+    width: 48px;
+    left: 187px;
+  }
+}
+.mk-sys-side-menu.mk-edit { // 缂栬緫鏃舵帶鍒惰彍鍗曞簳鑹�
+  .ant-menu-sub.ant-menu-inline {
+    > .ant-menu-item.ant-menu-item-selected {
+      background: unset;
+    }
+    > .ant-menu-item.ant-menu-item-active {
+      background: unset;
+    }
+  }
+}
+.ant-menu-submenu.ant-menu-submenu-popup {
+  max-height: 80vh;
+  overflow-y: scroll;
+  &::-webkit-scrollbar {
+    display: none;
+  }
+}
+.ant-menu-vertical .ant-menu-item {
+  cursor: default;
+  height: 30px;
+  line-height: 30px;
+  a {
+    cursor: pointer;
+  }
+}
\ No newline at end of file
diff --git a/src/views/login/index.jsx b/src/views/login/index.jsx
index 96650e8..1c2ad1c 100644
--- a/src/views/login/index.jsx
+++ b/src/views/login/index.jsx
@@ -6,7 +6,7 @@
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js' 
-import options from '@/store/options.js'
+import options, { styles } from '@/store/options.js'
 import zhCN from '@/locales/zh-CN/login.js'
 import enUS from '@/locales/en-US/login.js'
 import asyncLoadComponent from '@/utils/asyncLoadComponent'
@@ -345,8 +345,8 @@
             window.GLOB.mainlogo = systemMsg.mainlogo
             window.GLOB.style = systemMsg.style
         
-            if (window.GLOB.style && options.styles[window.GLOB.style]) {
-              document.body.className = options.styles[window.GLOB.style] + ' ' + (res.split_line_show === 'false' ? 'hidden-split-line' : '')
+            if (window.GLOB.style && styles[window.GLOB.style]) {
+              document.body.className = styles[window.GLOB.style] + ' ' + (res.split_line_show === 'false' ? 'hidden-split-line' : '')
             }
 
             if (res.titlelogo && window.GLOB.favicon !== res.titlelogo) {
diff --git a/src/views/main/index.jsx b/src/views/main/index.jsx
index 718f936..93ec841 100644
--- a/src/views/main/index.jsx
+++ b/src/views/main/index.jsx
@@ -3,13 +3,14 @@
 import enUS from 'antd/es/locale/en_US'
 import zhCN from 'antd/es/locale/zh_CN'
 
+import asyncComponent from '@/utils/asyncComponent'
 import Header from '@/components/header'
 import Sidemenu from '@/components/sidemenu'
-import Tabview from '@/components/tabview'
 import QueryLog from '@/components/querylog'
 
 import './index.scss'
 
+const Tabview = asyncComponent(() => import('@/components/tabview'))
 const _locale = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
 
 class Main extends Component {
diff --git a/src/views/sso/index.jsx b/src/views/sso/index.jsx
index 077a30b..7af3a65 100644
--- a/src/views/sso/index.jsx
+++ b/src/views/sso/index.jsx
@@ -6,7 +6,7 @@
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js' 
-import options from '@/store/options.js'
+import { styles } from '@/store/options.js'
 import { modifyMemberLevel } from '@/store/action'
 import './index.scss'
 
@@ -105,8 +105,8 @@
         window.GLOB.mainlogo = systemMsg.mainlogo
         window.GLOB.style = systemMsg.style
     
-        if (window.GLOB.style && options.styles[window.GLOB.style]) {
-          document.getElementById('root').className = options.styles[window.GLOB.style]
+        if (window.GLOB.style && styles[window.GLOB.style]) {
+          document.body.className = styles[window.GLOB.style]
         }
 
         if (res.titlelogo && window.GLOB.favicon !== res.titlelogo) {

--
Gitblit v1.8.0