From 9b6ce1a5778c6e1a813237e87588c0052aae1bbb Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期三, 29 四月 2020 17:26:15 +0800
Subject: [PATCH] 2020-04-29

---
 src/templates/comtableconfig/index.jsx | 1578 +++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 966 insertions(+), 612 deletions(-)

diff --git a/src/templates/comtableconfig/index.jsx b/src/templates/comtableconfig/index.jsx
index c150227..c3135c9 100644
--- a/src/templates/comtableconfig/index.jsx
+++ b/src/templates/comtableconfig/index.jsx
@@ -4,31 +4,36 @@
 import { is, fromJS } from 'immutable'
 import { DndProvider } from 'react-dnd'
 import HTML5Backend from 'react-dnd-html5-backend'
-import { Button, Card, Modal, Collapse, notification, Spin, Select, List, Icon, Empty, Switch, Tooltip } from 'antd'
+import { Button, Card, Modal, Collapse, notification, Spin, Select, List, Icon, Empty, Switch, Tooltip, message } from 'antd'
 import moment from 'moment'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
-import zhCN from '@/locales/zh-CN/comtable.js'
-import enUS from '@/locales/en-US/comtable.js'
-import { getSearchForm, getActionForm, getColumnForm } from '@/templates/tableshare/formconfig'
+import options from '@/store/options.js'
+import zhCN from '@/locales/zh-CN/model.js'
+import enUS from '@/locales/en-US/model.js'
+import { getSearchForm, getActionForm, getColumnForm } from '@/templates/zshare/formconfig'
 import { queryTableSql } from '@/utils/option.js'
 
 import ActionForm from './actionform'
 import SettingForm from './settingform'
-import TabForm from '@/templates/tableshare/tabform'
-import SearchForm from '@/templates/tableshare/searchform'
-import ColumnForm from '@/templates/tableshare/columnform'
-import DragElement from '@/templates/tableshare/dragelement'
-import ColspanForm from '@/templates/tableshare/colspanform'
-import GridBtnForm from '@/templates/tableshare/gridbtnform'
-import EditCard from '@/templates/tableshare/editcard'
-import VerifyCard from '@/templates/tableshare/verifycard'
-import VerifyCardExcelIn from '@/templates/tableshare/verifycardexcelin'
-import VerifyCardExcelOut from '@/templates/tableshare/verifycardexcelout'
-import MenuForm from '@/templates/tableshare/menuform'
-import TabDragElement from '@/templates/tableshare/tabdragelement'
-import SourceElement from '@/templates/tableshare/dragelement/source'
+import TabForm from '@/templates/zshare/tabform'
+import SearchForm from '@/templates/zshare/searchform'
+import ColumnForm from '@/templates/zshare/columnform'
+import DragElement from '@/templates/zshare/dragelement'
+import ColspanForm from '@/templates/zshare/colspanform'
+import GridBtnForm from '@/templates/zshare/gridbtnform'
+import EditCard from '@/templates/zshare/editcard'
+import VerifyCard from '@/templates/zshare/verifycard'
+import VerifyCardExcelIn from '@/templates/zshare/verifycardexcelin'
+import VerifyCardExcelOut from '@/templates/zshare/verifycardexcelout'
+import VerifyCardPrint from '@/templates/zshare/verifycardprint'
+import MenuForm from '@/templates/zshare/menuform'
+import TabDragElement from '@/templates/zshare/tabdragelement'
+import EditComponent from '@/templates/zshare/editcomponent'
+import SourceElement from '@/templates/zshare/dragelement/source'
+import CreateFunc from '@/templates/zshare/createfunc'
+import CreateInterface from '@/templates/zshare/createinterface'
 import Source from './source'
 import './index.scss'
 
@@ -40,7 +45,7 @@
 class ComTableConfig extends Component {
   static propTpyes = {
     menu: PropTypes.any,
-    supMenuList: PropTypes.array,
+    optionLibs: PropTypes.any,
     reloadmenu: PropTypes.func,
     handleView: PropTypes.func
   }
@@ -67,10 +72,13 @@
     originActions: null,     // 鍘熷鎸夐挳淇℃伅锛屼娇鐢ㄥ凡鏈夌敤鎴锋ā鏉�
     delActions: [],          // 鍒犻櫎鎸夐挳鍒楄〃
     copyActions: [],         // 澶嶅埗鎸夐挳缁�
-    funcLoading: false,      // 瀛樺偍杩囩▼鍒涘缓涓�
     showColumnName: false,   // 鏄剧ず鍒楀瓧娈靛悕鎺у埗
     tabviews: [],            // 鎵�鏈夋爣绛鹃〉
-    profileVisible: false    // 楠岃瘉淇℃伅妯℃�佹
+    profileVisible: false,   // 楠岃瘉淇℃伅妯℃�佹
+    optionLibs: null,        // 鑷畾涔変笅鎷夐�夐」搴�
+    thawButtons: [],         // 宸查�夋嫨瑕佽В鍐荤殑鎸夐挳
+    activeKey: '0',          // 榛樿灞曞紑鍩烘湰淇℃伅
+    sqlVerifing: false       // sql楠岃瘉
   }
 
   /**
@@ -79,7 +87,7 @@
    * 2銆佽缃搷浣滅被鍨嬨�佸師濮嬭彍鍗曚俊鎭紙姣忔淇濆瓨鍚庨噸缃級銆佸凡浣跨敤琛ㄥ強鍩烘湰淇℃伅琛ㄥ崟
    */
   UNSAFE_componentWillMount () {
-    const { menu } = this.props
+    const { menu, optionLibs } = this.props
 
     let _LongParam = menu.LongParam
     let _config = ''
@@ -92,6 +100,21 @@
       _config.isAdd = true
     } else {
       _config = _LongParam
+      _config.search.forEach(item => {
+        if (
+          (item.type === 'select' || item.type === 'multiselect' || item.type === 'link') &&
+          item.resourceType === '0' &&
+          item.options && item.options.length > 0
+        ) {
+          optionLibs.set(menu.MenuID + item.uuid, {
+            uuid: menu.MenuID + item.uuid,
+            label: item.label,
+            parname: menu.MenuName,
+            type: 'search',
+            options: item.options
+          })
+        }
+      })
     }
 
     // 閰嶇疆榛樿鍊硷紝鍏煎
@@ -99,17 +122,28 @@
     _config.tabgroups = _config.tabgroups || ['tabs']
     _config.setting.subtabs = _config.setting.subtabs || []
     _config.Template = 'CommonTable'
+    _config.easyCode = _config.easyCode || ''
     
     let _oriActions = []
     if (_config.type === 'user') {
       _config.action = _config.action.map(item => {
         let uuid = Utils.getuuid()
 
-        if (item.OpenType === 'pop') { // 鍚湁瀛愰厤缃」鐨勬寜閽�傘�傘��
+        if (item.linkTab) {
+          item.linkTab = ''
+        }
+
+        if (item.OpenType === 'pop') { // 鍚湁瀛愰厤缃」鐨勬寜閽�(琛ㄥ崟)
           _oriActions.push({
             prebtn: JSON.parse(JSON.stringify(item)),
             curuuid: uuid,
             Template: 'Modal'
+          })
+        } else if (item.OpenType === 'tab' || item.OpenType === 'blank') { // 鍚湁瀛愰厤缃」鐨勬寜閽�(鏍囩鍚庡綋鍓嶉〉鎵撳紑)
+          _oriActions.push({
+            prebtn: JSON.parse(JSON.stringify(item)),
+            curuuid: uuid,
+            Template: item.tabTemplate
           })
         }
 
@@ -122,6 +156,10 @@
         _config[group] = _config[group].map(tab => {
           tab.uuid = Utils.getuuid()
           
+          if (tab.linkTab) {
+            tab.linkTab = ''
+          }
+
           return tab
         })
       })
@@ -129,18 +167,29 @@
 
     this.setState({
       config: _config,
+      activeKey: menu.activeKey || '0',
+      optionLibs: optionLibs,
       originActions: _oriActions,
       originMenu: JSON.parse(JSON.stringify(menu)),
       selectedTables: _config.tables || [],
       menuformlist: [
         {
           type: 'select',
+          key: 'fstMenuId',
+          label: '涓�绾ц彍鍗�',
+          initVal: menu.fstMenuId,
+          required: true,
+          readonly: false,
+          options: menu.fstMenuList
+        },
+        {
+          type: 'select',
           key: 'parentId',
-          label: this.state.dict['header.menu.supMenu'],
+          label: '浜岀骇鑿滃崟',
           initVal: menu.ParentID,
           required: true,
           readonly: false,
-          options: this.props.supMenuList
+          options: menu.supMenuList
         },
         {
           type: 'text',
@@ -174,6 +223,14 @@
             MenuID: 'currenttab',
             text: this.state.dict['header.form.currenttab']
           }]
+        },
+        {
+          type: 'text',
+          key: 'easyCode',
+          label: this.state.dict['header.form.easyCode'],
+          initVal: _config.easyCode,
+          required: false,
+          readonly: false
         }
       ]
     })
@@ -206,7 +263,7 @@
         notification.warning({
           top: 92,
           message: res.message,
-          duration: 10
+          duration: 5
         })
       }
     })
@@ -268,7 +325,7 @@
           notification.warning({
             top: 92,
             message: res.message,
-            duration: 10
+            duration: 5
           })
         }
       })
@@ -291,6 +348,12 @@
             }
           })
         })
+      } else {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
       }
     })
   }
@@ -302,6 +365,46 @@
     this.setState = () => {
       return
     }
+  }
+
+  /**
+   * @description 鍔犺浇鎴栧埛鏂版爣绛句俊鎭�
+   */
+  reloadTab = () => {
+    this.setState({
+      loading: true,
+      tabviews: []
+    })
+    Api.getSystemConfig({func: 'sPC_Get_UserTemp', TypeCharTwo: 'tab'}).then(res => {
+      if (res.status) {
+        this.setState({
+          loading: false,
+          tabviews: res.UserTemp.map(temp => {
+            return {
+              uuid: temp.MenuID,
+              value: temp.MenuID,
+              text: temp.MenuName,
+              type: temp.Template,
+              MenuNo: temp.MenuNo
+            }
+          })
+        })
+        notification.success({
+          top: 92,
+          message: '鍒锋柊鎴愬姛銆�',
+          duration: 2
+        })
+      } else {
+        this.setState({
+          loading: false
+        })
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 5
+        })
+      }
+    })
   }
 
   /**
@@ -342,7 +445,7 @@
     this.setState({
       modaltype: 'search',
       card: card,
-      formlist: getSearchForm(card)
+      formlist: getSearchForm(card, this.props.sysRoles)
     })
   }
 
@@ -352,8 +455,8 @@
   handleAction = (card, type) => {
     let ableField = this.props.permFuncField.join(', ')
     let functip = <div>
-      <p style={{marginBottom: '5px'}}>{this.state.dict['header.modal.func.innerface'].replace('@ableField', ableField)}</p>
-      <p>{this.state.dict['header.modal.func.outface']}</p>
+      <p style={{marginBottom: '5px'}}>{this.state.dict['model.tooltip.func.innerface'].replace('@ableField', ableField)}</p>
+      <p>{this.state.dict['model.tooltip.func.outface']}</p>
     </div>
 
     this.setState({
@@ -367,12 +470,79 @@
    * @description 鏄剧ず鍒椾笌鍚堝苟鍒楃紪杈戯紝鑾峰彇琛ㄥ崟淇℃伅
    */
   handleColumn = (card) => {
+    const { menu } = this.props
+
     if (card.type !== 'colspan') {
-      this.setState({
-        modaltype: 'columns',
-        card: card,
-        formlist: getColumnForm(card)
+      let menulist = menu.fstMenuList.map(item => {
+        return {
+          value: item.MenuID,
+          label: item.text,
+          isLeaf: false
+        }
       })
+
+      if ((card.type === 'text' || card.type === 'number') && card.linkmenu && card.linkmenu.length > 0) {
+        let _param = {
+          func: 'sPC_Get_FunMenu',
+          ParentID: card.linkmenu[0],
+          systemType: options.systemType,
+          debug: 'Y'
+        }
+
+        this.setState({
+          loading: true
+        })
+    
+        Api.getSystemConfig(_param).then(result => {
+          if (result.status) {
+            menulist = menulist.map(item => {
+              if (item.value === card.linkmenu[0]) {
+                item.children = result.data.map(item => {
+                  let submenu = {
+                    value: item.ParentID,
+                    label: item.MenuNameP,
+                    children: item.FunMenu.map(cell => {
+                      return {
+                        value: cell.MenuID,
+                        label: cell.MenuName,
+                        MenuID: cell.MenuID,
+                        MenuName: cell.MenuName,
+                        MenuNo: cell.MenuNo,
+                        Ot: cell.Ot,
+                        PageParam: cell.PageParam,
+                        LinkUrl: cell.LinkUrl,
+                        disabled: cell.MenuID === menu.MenuID
+                      }
+                    })
+                  }
+
+                  return submenu
+                })
+              }
+              return item
+            })
+          } else {
+            notification.warning({
+              top: 92,
+              message: result.message,
+              duration: 5
+            })
+          }
+
+          this.setState({
+            loading: false,
+            modaltype: 'columns',
+            card: card,
+            formlist: getColumnForm(card, this.props.sysRoles, menulist)
+          })
+        })
+      } else {
+        this.setState({
+          modaltype: 'columns',
+          card: card,
+          formlist: getColumnForm(card, this.props.sysRoles, menulist)
+        })
+      }
     } else {
       this.setState({
         modaltype: 'colspan',
@@ -490,9 +660,33 @@
           type: 'mutilselect',
           key: 'equalTab',
           label: this.state.dict['header.form.equalTab'],
+          tooltip: '濡傛灉瀛愭爣绛句腑鍚湁鍒锋柊鍚岀骇鏍囩鐨勬寜閽紝鍦ㄦ澶勬坊鍔犻渶瑕佸埛鏂扮殑鏍囩銆�',
           initVal: equalTab,
           required: false,
           options: equalTabs
+        },
+        {
+          type: 'text',
+          key: 'foreignKey',
+          label: '澶栭敭',
+          tooltip: '澶栭敭鏃ㄥ湪鏍囩椤典腑鎵ц榛樿鍑芥暟锛堟坊鍔狅級鏃讹紝鏇挎崲BID瀛楁',
+          initVal: card.foreignKey || '',
+          required: false
+        },
+        {
+          type: 'radio',
+          key: 'searchPass',
+          label: '涓昏〃鎼滅储',
+          initVal: card.searchPass || 'false',
+          tooltip: '浣跨敤涓昏〃鎼滅储鏉′欢鏃讹紝涓昏〃鐨勬悳绱㈡潯浠朵細浼犲叆瀛愯〃涓��',
+          required: false,
+          options: [{
+            value: 'true',
+            text: '浣跨敤'
+          }, {
+            value: 'false',
+            text: '涓嶄娇鐢�'
+          }]
         }
       ]
     })
@@ -515,23 +709,101 @@
    */
   handleSubmit = () => {
     const { menu } = this.props
-    const { config, card, modaltype } = this.state
+    const { config, card, modaltype, optionLibs } = this.state
 
     if (modaltype === 'search') {
       this.searchFormRef.handleConfirm().then(res => {
+        if ( // 鏇存柊涓嬫媺瀛楀吀
+          (res.type === 'select' || res.type === 'multiselect' || res.type === 'link') &&
+          res.resourceType === '0' &&
+          res.options && res.options.length > 0
+        ) {
+          optionLibs.set(menu.MenuID + res.uuid, {
+            uuid: menu.MenuID + res.uuid,
+            label: res.label,
+            parname: menu.MenuName,
+            type: 'search',
+            options: res.options
+          })
+        }
+
+        let fieldrepet = false // 瀛楁閲嶅
+        let labelrepet = false // 鎻愮ず鏂囧瓧閲嶅
+
         let _search = config.search.map(item => {
+          if (item.uuid !== res.uuid && res.field && item.field) {
+            if (item.field === res.field) {
+              fieldrepet = true
+            } else if (item.label === res.label) {
+              labelrepet = true
+            }
+          }
+
           if (item.uuid === res.uuid) {
             return res
           } else {
             return item
           }
         })
+
+        if (fieldrepet) {
+          notification.warning({
+            top: 92,
+            message: '瀛楁宸插瓨鍦紒',
+            duration: 5
+          })
+          return
+        } else if (labelrepet) {
+          notification.warning({
+            top: 92,
+            message: '鍚嶇О宸插瓨鍦紒',
+            duration: 5
+          })
+          return
+        }
+
         _search = _search.filter(item => !item.origin)
 
-        this.setState({
-          config: {...config, search: _search},
-          modaltype: ''
-        })
+        if ((res.type === 'select' || res.type === 'multiselect' || res.type === 'link') && res.resourceType === '1' && /\s/.test(res.dataSource)) {
+          this.setState({
+            sqlVerifing: true
+          })
+  
+          let param = {
+            func: 's_debug_sql',
+            LText: res.dataSource
+          }
+          param.LText = Utils.formatOptions(param.LText)
+          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
+          param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+  
+          if (window.GLOB.mainSystemApi && res.database === 'sso') {
+            param.rduri = window.GLOB.mainSystemApi
+          }
+          
+          Api.getLocalConfig(param).then(result => {
+            if (result.status) {
+              this.setState({
+                sqlVerifing: false,
+                config: {...config, search: _search},
+                optionLibs: optionLibs,
+                modaltype: ''
+              })
+            } else {
+              this.setState({sqlVerifing: false})
+              
+              Modal.error({
+                title: result.message
+              })
+            }
+          })
+        } else {
+          this.setState({
+            config: {...config, search: _search},
+            optionLibs: optionLibs,
+            modaltype: ''
+          })
+        }
       })
     } else if (modaltype === 'actionEdit' || modaltype === 'actionCopy') {
       this.actionFormRef.handleConfirm().then(res => {
@@ -560,9 +832,9 @@
               // 瑙f瀽閰嶇疆锛屼慨鏀规ā鎬佹鏍囬鍚嶇О
               if (result.LongParam) {
                 try {
-                  _LongParam = window.decodeURIComponent(window.atob(result.LongParam))
-                  _LongParam = JSON.parse(_LongParam)
+                  _LongParam = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
                 } catch (e) {
+                  console.warn('Parse Failure')
                   _LongParam = ''
                 }
               }
@@ -571,6 +843,7 @@
                   _LongParam.setting.title = res.label
                   _LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(_LongParam)))
                 } catch {
+                  console.warn('Stringify Failure')
                   _LongParam = ''
                 }
               } else {
@@ -592,7 +865,7 @@
                   notification.warning({
                     top: 92,
                     message: response.message,
-                    duration: 10
+                    duration: 5
                   })
                 } else {
                   this.setState({
@@ -617,9 +890,9 @@
               // 瑙f瀽閰嶇疆锛屼慨鏀规ā鎬佹鏍囬鍚嶇О
               if (result.LongParam) {
                 try {
-                  _LongParam = window.decodeURIComponent(window.atob(result.LongParam))
-                  _LongParam = JSON.parse(_LongParam)
+                  _LongParam = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
                 } catch (e) {
+                  console.warn('Parse Failure')
                   _LongParam = ''
                 }
               }
@@ -642,6 +915,7 @@
                   _LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(_LongParam)))
                   _temp = 'FormTab'
                 } catch {
+                  console.warn('Stringify Failure')
                   _LongParam = ''
                 }
               } else {
@@ -666,7 +940,7 @@
                   notification.warning({
                     top: 92,
                     message: response.message,
-                    duration: 10
+                    duration: 5
                   })
                 } else {
                   this.setState({
@@ -705,13 +979,41 @@
       })
     } else if (modaltype === 'columns' || modaltype === 'colspan') {
       this.columnFormRef.handleConfirm().then(res => {
+        let fieldrepet = false // 瀛楁閲嶅
+        let labelrepet = false // 鎻愮ず鏂囧瓧閲嶅
+
         let _columns = config.columns.map(item => {
+          if (item.uuid !== res.uuid && res.field && item.field) {
+            if (item.field === res.field) {
+              fieldrepet = true
+            } else if (item.label === res.label) {
+              labelrepet = true
+            }
+          }
+
           if (item.uuid === res.uuid) {
             return res
           } else {
             return item
           }
         })
+
+        if (fieldrepet) {
+          notification.warning({
+            top: 92,
+            message: '瀛楁宸插瓨鍦紒',
+            duration: 5
+          })
+          return
+        } else if (labelrepet) {
+          notification.warning({
+            top: 92,
+            message: '鍚嶇О宸插瓨鍦紒',
+            duration: 5
+          })
+          return
+        }
+        
         _columns = _columns.filter(item => !item.origin)
 
         this.setState({
@@ -751,7 +1053,7 @@
   editModalCancel = () => {
     const { config, card, modaltype } = this.state
 
-    if (card.focus) {
+    if (card && card.focus) {
       let _config = null
       if (modaltype === 'search') {
         let _search = config.search.filter(item => item.uuid !== card.uuid)
@@ -793,24 +1095,16 @@
       let btn = res         // 鎸夐挳淇℃伅
       let newLText = ''     // 鍒涘缓瀛樺偍杩囩▼sql
       let DelText = ''      // 鍒犻櫎瀛樺偍杩囩▼sql
-      let isExit = false    // 瀛樺偍杩囩▼鏄惁瀛樺湪
-      let sysTVPText = ''   // 宸叉湁鐨勫瓨鍌ㄨ繃绋嬭鍙�(浜戠)
-      let localTVPText = '' // 宸叉湁鐨勫瓨鍌ㄨ繃绋嬭鍙�(鏈湴)
 
       // 鍒涘缓瀛樺偍杩囩▼锛屽繀椤诲~鍐欏唴閮ㄥ嚱鏁板悕
       if (!btn.innerFunc) {
         notification.warning({
           top: 92,
           message: '璇峰~鍐欏唴閮ㄥ嚱鏁帮紒',
-          duration: 10
+          duration: 5
         })
         return
       }
-
-      // 鍒涘缓涓�
-      this.setState({
-        funcLoading: true
-      })
 
       new Promise(resolve => {
         // 寮圭獥锛堣〃鍗曪級绫绘寜閽紝鍏堣幏鍙栨寜閽厤缃俊鎭紝濡傛灉灏氭湭閰嶇疆鎸夐挳鍒欎細鎶ラ敊骞剁粓姝€��
@@ -822,10 +1116,10 @@
           }).then(res => {
             let _LongParam = ''
             if (res.status && res.LongParam) {
-              _LongParam = window.decodeURIComponent(window.atob(res.LongParam))
               try {
-                _LongParam = JSON.parse(_LongParam)
+                _LongParam = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
               } catch (e) {
+                console.warn('Parse Failure')
                 _LongParam = ''
               }
             }
@@ -850,12 +1144,12 @@
               DelText = Utils.formatOptions(Utils.dropfunc(_param.funcName))
               resolve(true)
             } else {
-              resolve(false)
               notification.warning({
                 top: 92,
                 message: '寮圭獥锛堣〃鍗曪級鎸夐挳锛岃鍏堥厤缃〃鍗曚俊鎭紒',
-                duration: 10
+                duration: 5
               })
+              resolve(false)
             }
           })
         } else if (btn.OpenType === 'excelIn') {
@@ -871,7 +1165,7 @@
             notification.warning({
               top: 92,
               message: '璇峰畬鍠勫鍏xcel楠岃瘉淇℃伅锛�',
-              duration: 10
+              duration: 5
             })
             resolve(false)
           }
@@ -895,208 +1189,43 @@
           resolve(true)
         }
       }).then(res => {
-        // 鑾峰彇浜戠鍙婃湰鍦帮紝鏄惁宸插瓨鍦ㄨ瀛樺偍杩囩▼鐨勪俊鎭�
-        if (res === false) return res
+        if (!res) return
 
-        let sysDefer = new Promise(resolve => {
-          Api.getSystemConfig({
-            func: 'sPC_Get_TVP', // 浜戠鑾峰彇瀛樺偍缁撴灉
-            TVPName: btn.innerFunc
-          }).then(result => {
-            resolve(result)
-          })
-        })
+        this.refs.btnCreatFunc.exec(btn.innerFunc, newLText, DelText).then(result => {
+          if (result !== 'success') return
 
-        let localDefer = new Promise(resolve => {
-          let _param = { // 鑾峰彇鏈湴瀛樺偍杩囩▼淇℃伅
-            func: 's_get_userproc',
-            LText: btn.innerFunc
-          }
-          _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
-          _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
-          
-          Api.getLocalConfig(_param).then(result => {
-            resolve(result)
-          })
-        })
-        
-        return Promise.all([sysDefer, localDefer])
-      }).then(res => {
-        // 浜戠缁撴灉涓庢柊璇彞涓嶅悓鏃讹紝鏇存柊浜戠淇℃伅
-        if (res === false) return res
-
-        let isError = false
-
-        res.forEach((result, index) => {
-          if (!result.status) {
-            notification.warning({
-              top: 92,
-              message: result.message,
-              duration: 10
-            })
-            isError = true
-          } else if (index === 0) {
-            sysTVPText = result.TVPText
-          } else {
-            if (result.Ltext) { // 鏈湴瀛樺偍杩囩▼鏄惁瀛樺湪
-              isExit = true
+          let _action = config.action.map(item => {
+            if (item.uuid === btn.uuid) {
+              return btn
+            } else {
+              return item
             }
-            localTVPText = Utils.formatOptions(result.Ltext)
-          }
-        })
-
-        if (isError) return false
-        
-        if ((newLText === localTVPText) && (newLText === sysTVPText)) {
-          return 'drop'
-        } else if (!localTVPText || (localTVPText === sysTVPText)) {
-          // 鏈湴瀛樺偍杩囩▼涓嶅瓨鍦紝灏嗘柊鐨勫瓨鍌ㄨ繃绋嬫洿鏂拌嚦浜戠
-          return Api.getSystemConfig({
-            func: 'sPC_TVP_InUp',
-            TVPName: btn.innerFunc,
-            TVPText: newLText,
-            TypeName: 'P'
           })
-        } else {
-          return new Promise(resolve => {
-            Api.getSystemConfig({ // 娣诲姞鐜版湁鐨勬湰鍦板瓨鍌ㄨ繃绋嬭嚦浜戠
-              func: 'sPC_TVP_InUp',
-              TVPName: btn.innerFunc,
-              TVPText: localTVPText,
-              TypeName: 'P'
-            }).then(result => {
-              if (result.status) {
-                Api.getSystemConfig({
-                  func: 'sPC_TVP_InUp', // 娣诲姞鏈�鏂扮殑瀛樺偍杩囩▼鑷充簯绔�
-                  TVPName: btn.innerFunc,
-                  TVPText: newLText,
-                  TypeName: 'P'
-                }).then(response => {
-                  resolve(response)
-                })
-              } else {
-                resolve(result)
-              }
-            })
-          })
-        }
-      }).then(res => {
-        // 浜戠淇℃伅鏇存柊鍚庯紝鍒ゆ柇鏄垹闄ゆ垨鏄洿鎺ユ柊寤哄瓨鍌ㄨ繃绋�
-        if (res === false || res === 'drop') return res
+          _action = _action.filter(item => !item.origin)
 
-        if (!res.status) {
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 10
-          })
-          return false
-        } else if (isExit) {
-          return 'drop'
-        } else {
-          return 'create'
-        }
-      }).then(res => {
-        // 鍒犻櫎瀛樺偍杩囩▼
-        if (res === false || res === 'create') return res
+          // 鍒ゆ柇鏄惁瀛樺湪鎿嶄綔鍒�
+          let _hasGridbtn = _action.filter(act => act.position === 'grid').length > 0
+          let _gridBtn = config.gridBtn
 
-        let _param = {
-          func: 'sPC_TableData_InUpDe',
-          LText: DelText,
-          TypeCharOne: 'proc' // 鍒犻櫎鎴栧垱寤哄瓨鍌ㄨ繃绋�
-        }
-
-        _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
-        _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
-
-        return Api.getLocalConfig(_param)
-      }).then(res => {
-        // 鏍规嵁涓婅堪鎿嶄綔缁撴灉锛屽垽鏂槸鍚︽柊寤哄瓨鍌ㄨ繃绋�
-        if (res === false || res === 'create') return res
-
-        if (!res.status) {
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 10
-          })
-          return false
-        } else {
-          return 'create'
-        }
-      }).then(res => {
-        // 鏂板缓瀛樺偍杩囩▼
-        if (res === false) return res
-
-        let _param = {
-          func: 'sPC_TableData_InUpDe',
-          LText: newLText,
-          TypeCharOne: 'proc' // 鍒犻櫎鎴栧垱寤哄瓨鍌ㄨ繃绋�
-        }
-        _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
-        _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
-
-        return Api.getLocalConfig(_param)
-      }).then(res => {
-        // 澶勭悊鏂板缓缁撴灉
-        if (res === false) return res
-
-        if (!res.status) {
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 10
-          })
-          return false
-        } else {
-          notification.success({
-            top: 92,
-            message: '鍒涘缓鎴愬姛',
-            duration: 2
-          })
-          return true
-        }
-      }).then(res => {
-        // 鏂板缓鎴愬姛鍚庯紝鏇存柊椤甸潰鎸夐挳淇℃伅
-        if (res === false) {
-          this.setState({
-            funcLoading: false
-          })
-          return
-        }
-
-        let _action = config.action.map(item => {
-          if (item.uuid === btn.uuid) {
-            return btn
+          if (_gridBtn) {
+            _gridBtn.display = _hasGridbtn
           } else {
-            return item
+            _gridBtn = {
+              display: _hasGridbtn,
+              Align: 'center',
+              IsSort: 'false',
+              uuid: Utils.getuuid(),
+              label: this.state.dict['header.form.column.action'],
+              type: 'action',
+              style: 'button',
+              show: 'horizontal',
+              Width: 120
+            }
           }
-        })
-        _action = _action.filter(item => !item.origin)
 
-        // 鍒ゆ柇鏄惁瀛樺湪鎿嶄綔鍒�
-        let _hasGridbtn = _action.filter(act => act.position === 'grid').length > 0
-        let _gridBtn = config.gridBtn
-
-        if (_gridBtn) {
-          _gridBtn.display = _hasGridbtn
-        } else {
-          _gridBtn = {
-            display: _hasGridbtn,
-            Align: 'center',
-            IsSort: 'false',
-            uuid: Utils.getuuid(),
-            label: this.state.dict['header.form.column.action'],
-            type: 'action',
-            style: 'button',
-            show: 'horizontal',
-            Width: 120
-          }
-        }
-
-        this.setState({
-          config: {...config, action: _action, gridBtn: _gridBtn},
-          funcLoading: false
+          this.setState({
+            config: {...config, action: _action, gridBtn: _gridBtn}
+          })
         })
       })
     })
@@ -1107,229 +1236,92 @@
    */
   tableCreatFunc = () => {
     const { menu } = this.props
-    let config = JSON.parse(JSON.stringify(this.state.config))
+    const { config } = this.state
 
-    this.settingRef.handleConfirm().then(res => {
-      const setting = res
+    this.settingRef.handleConfirm().then(setting => {
+
       if (!(setting.interType === 'inner') || !setting.innerFunc) {
         notification.warning({
           top: 92,
           message: '鎺ュ彛绫诲瀷涓�-鍐呴儴锛屼笖瀛樺湪鍐呴儴鍑芥暟鏃讹紝鎵嶅彲浠ュ垱寤哄瓨鍌ㄨ繃绋嬶紒',
-          duration: 10
+          duration: 5
         })
         return
       }
 
-      if (setting.dataresource.length > 50 && config.setting.dataresource !== setting.dataresource) {
-        let param = {
-          func: 's_DataSrc_Save',
-          LText: setting.dataresource,
-          MenuID: menu.MenuID
-        }
-
-        param.LText = Utils.formatOptions(param.LText)
-        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
-        param.secretkey = Utils.encrypt(param.LText, param.timestamp)
-
-        Api.getLocalConfig(param)
-      }
-
-      this.setState({
-        funcLoading: true
-      })
-
-      let newLText = Utils.formatOptions(Utils.getTableFunc(setting, menu, config)) // 鍒涘缓瀛樺偍杩囩▼sql
+      let _config = {...config, setting: setting}
+      let newLText = Utils.formatOptions(Utils.getTableFunc(setting, menu, _config)) // 鍒涘缓瀛樺偍杩囩▼sql
       let DelText = Utils.formatOptions(Utils.dropfunc(setting.innerFunc))          // 鍒犻櫎瀛樺偍杩囩▼sql
 
-      new Promise(resolve => {
-        let sysDefer = new Promise(resolve => {
-          Api.getSystemConfig({
-            func: 'sPC_Get_TVP', // 浜戠鑾峰彇瀛樺偍缁撴灉
-            TVPName: setting.innerFunc
-          }).then(result => {
-            if (!result.status) {
-              notification.warning({
-                top: 92,
-                message: result.message,
-                duration: 10
-              })
-              resolve(false)
-            } else {
-              resolve(result)
-            }
-          })
-        })
-
-        let localDefer = new Promise(resolve => {
-          let _param = { // 鑾峰彇鏈湴瀛樺偍杩囩▼淇℃伅
-            func: 's_get_userproc',
-            LText: setting.innerFunc
-          }
-          _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
-          _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
-          
-          Api.getLocalConfig(_param).then(result => {
-            if (!result.status) {
-              notification.warning({
-                top: 92,
-                message: result.message,
-                duration: 10
-              })
-              resolve(false)
-            } else {
-              resolve(result)
-            }
-          })
-        })
-        
-        Promise.all([sysDefer, localDefer]).then(result => {
-          resolve(result)
-        })
-      }).then(res => {
-        // 鑾峰彇浜戠鍙婃湰鍦帮紝鏄惁宸插瓨鍦ㄨ瀛樺偍杩囩▼鐨勪俊鎭�
-        if (res === false) return res
-        if (res[0] === false || res[1] === false) return false
-
-        let cloudfunc = ''
-        let localfunc = ''
-        res.forEach((item, index) => {
-          if (index === 0 && item.TVPText) {
-            cloudfunc = item.TVPText
-          } else if (index === 1 && item.Ltext) {
-            localfunc = Utils.formatOptions(item.Ltext)
-          }
-        })
-
-        if ((newLText === localfunc) && (newLText === cloudfunc)) {
-          return 'drop'
-        } else if (!localfunc || (cloudfunc === localfunc)) {
-          // 鏈湴瀛樺偍杩囩▼涓嶅瓨鍦紝鎴栦簯绔拰鏈湴瀛樺偍杩囩▼涓�鑷存椂锛屽皢鏂扮殑瀛樺偍杩囩▼鏇存柊鑷充簯绔�
-          return Api.getSystemConfig({
-            func: 'sPC_TVP_InUp',
-            TVPName: setting.innerFunc,
-            TVPText: newLText,
-            TypeName: 'P'
-          })
-        } else {
-          return new Promise(resolve => {
-            Api.getSystemConfig({ // 娣诲姞鐜版湁鐨勬湰鍦板瓨鍌ㄨ繃绋嬭嚦浜戠
-              func: 'sPC_TVP_InUp',
-              TVPName: setting.innerFunc,
-              TVPText: localfunc,
-              TypeName: 'P'
-            }).then(result => {
-              if (result.status) {
-                Api.getSystemConfig({
-                  func: 'sPC_TVP_InUp', // 娣诲姞鏈�鏂扮殑瀛樺偍杩囩▼鑷充簯绔�
-                  TVPName: setting.innerFunc,
-                  TVPText: newLText,
-                  TypeName: 'P'
-                }).then(response => {
-                  resolve(response)
-                })
-              } else {
-                resolve(result)
-              }
-            })
-          })
-        }
-      }).then(res => {
-        // 浜戠淇℃伅鏇存柊鍚庯紝鍒ゆ柇鏄垹闄ゆ垨鏄洿鎺ユ柊寤哄瓨鍌ㄨ繃绋�
-        if (res === false || res === 'drop') return res
-
-        if (!res.status) {
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 10
-          })
-          return false
-        } else {
-          return 'create'
-        }
-      }).then(res => {
-        // 鍒犻櫎瀛樺偍杩囩▼
-        if (res === false || res === 'create') return res
-
-        let _param = {
-          func: 'sPC_TableData_InUpDe',
-          LText: DelText,
-          TypeCharOne: 'proc' // 鍒犻櫎鎴栧垱寤哄瓨鍌ㄨ繃绋�
-        }
-
-        _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
-        _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
-
-        return Api.getLocalConfig(_param)
-      }).then(res => {
-        // 鏍规嵁涓婅堪鎿嶄綔缁撴灉锛屽垽鏂槸鍚︽柊寤哄瓨鍌ㄨ繃绋�
-        if (res === false || res === 'create') return res
-
-        if (!res.status) {
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 10
-          })
-          return false
-        } else {
-          return 'create'
-        }
-      }).then(res => {
-        // 鏂板缓瀛樺偍杩囩▼
-        if (res === false) return res
-
-        let _param = {
-          func: 'sPC_TableData_InUpDe',
-          LText: newLText,
-          TypeCharOne: 'proc' // 鍒犻櫎鎴栧垱寤哄瓨鍌ㄨ繃绋�
-        }
-        _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
-        _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
-
-        return Api.getLocalConfig(_param)
-      }).then(res => {
-        // 澶勭悊鏂板缓缁撴灉
-        if (res === false) return res
-
-        if (!res.status) {
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 10
-          })
-          return false
-        } else {
-          notification.success({
-            top: 92,
-            message: '鍒涘缓鎴愬姛',
-            duration: 2
-          })
-          return true
-        }
-      }).then(res => {
-        // 鏂板缓鎴愬姛鍚庯紝鏇存柊椤甸潰鎸夐挳淇℃伅
-        if (res === false) {
+      this.refs.tableCreatFunc.exec(setting.innerFunc, newLText, DelText).then(result => {
+        if (result === 'success') {
           this.setState({
-            funcLoading: false
+            config: _config
+          })
+        }
+      })
+    })
+  }
+
+  /**
+   * @description 鍒涘缓鎸夐挳鎺ュ彛锛堝啓鍏ワ級
+   */
+  btnCreatInterface = () => {
+    const { menu } = this.props
+    const { config } = this.state
+
+    this.menuformRef.handleConfirm().then(res => {
+      this.actionFormRef.handleConfirm().then(result => {
+        let _menu = {
+          type: 'main',
+          MenuID: menu.MenuID,
+          menuName: res.menuName,
+          menuNo: res.menuNo
+        }
+
+        this.refs.btnCreatInterface.triggerInInterface(result, config, _menu)
+      })
+    })
+  }
+
+  /**
+   * @description 鍒涘缓琛ㄦ牸鎺ュ彛锛堣鍑猴級
+   */
+  tableCreatInterface = () => {
+    const { menu } = this.props
+    const { config } = this.state
+
+    this.menuformRef.handleConfirm().then(res => {
+      this.settingRef.handleConfirm().then(setting => {
+        if (setting.interType !== 'inner' || setting.innerFunc) {
+          notification.warning({
+            top: 92,
+            message: '鎺ュ彛绫诲瀷涓�-鍐呴儴锛屼笖涓嶅瓨鍦ㄥ唴閮ㄥ嚱鏁版椂锛屾墠鍙互鍒涘缓鎺ュ彛锛�',
+            duration: 5
           })
           return
         }
-
-        this.setState({
-          config: {...config, setting: setting}
-        })
+  
+        let _config = {...config, setting: setting}
+        let _menu = {
+          type: 'main',
+          MenuID: menu.MenuID,
+          menuName: res.menuName,
+          menuNo: res.menuNo
+        }
+  
+        this.refs.tableCreatInterface.triggerOutInterface(_menu, _config)
       })
     })
   }
 
   deleteElement = (element) => {
-    const { config } = this.state
+    const { config, thawButtons } = this.state
     let _this = this
 
     confirm({
       content: `纭畾鍒犻櫎<<${element.card.label}>>鍚楋紵`,
-      okText: this.state.dict['header.confirm'],
+      okText: this.state.dict['model.confirm'],
       cancelText: this.state.dict['header.cancel'],
       onOk() {
         let _config = null
@@ -1363,12 +1355,13 @@
         // 鍒犻櫎鎸夐挳鍏冪礌
         let _delActions = _this.state.delActions
         if (element.type === 'action' || element.type === 'tabs') {
-          _delActions.push(element.card.uuid)
+          _delActions.push(element)
         }
 
         _this.setState({
           config: _config,
-          delActions: _delActions
+          delActions: _delActions,
+          thawButtons: thawButtons.filter(key => key !== element.card.uuid)
         })
       },
       onCancel() {}
@@ -1386,44 +1379,31 @@
   }
 
   /**
+   * @description 鎸夐挳鍙屽嚮瑙﹀彂瀛愰厤缃�
+   */
+  btnDoubleClick = (element) => {
+    if (!element.origin && (element.OpenType === 'pop' || element.OpenType === 'popview' || element.OpenType === 'blank' || element.OpenType === 'tab')) {
+      this.setSubConfig(element, 'button')
+    } else {
+      notification.warning({
+        top: 92,
+        message: '姝ゆ寜閽棤瀛愰厤缃」锛�',
+        duration: 5
+      })
+    }
+  }
+
+  /**
    * @description 楠岃瘉淇℃伅淇濆瓨
    */
   verifySubmit = () => {
     const { card } = this.state
     let config = JSON.parse(JSON.stringify(this.state.config))
-    
-    if (card.OpenType === 'excelIn') {
-      this.verifyRef.handleConfirm().then(res => {
-        
-        config.action = config.action.map(item => {
-          if (item.uuid === card.uuid) {
-            item.verify = res
-          }
-    
-          return item
-        })
-    
-        this.setState({
-          profileVisible: false,
-          config: config,
-          card: '',
-        })
-      })
-    } else {
-      let _verify = this.verifyRef.state.verify
 
-      if (card.OpenType !== 'excelOut' && _verify.default === 'false' && _verify.scripts.length === 0) {
-        notification.warning({
-          top: 92,
-          message: '涓嶆墽琛岄粯璁ql鏃讹紝蹇呴』璁剧疆鑷畾涔夎剼鏈紒',
-          duration: 10
-        })
-        return
-      }
-
+    this.verifyRef.handleConfirm().then(res => {
       config.action = config.action.map(item => {
         if (item.uuid === card.uuid) {
-          item.verify = _verify
+          item.verify = res
         }
   
         return item
@@ -1432,9 +1412,9 @@
       this.setState({
         profileVisible: false,
         config: config,
-        card: '',
+        card: ''
       })
-    }
+    })
   }
 
   /**
@@ -1444,17 +1424,40 @@
     this.props.handleView({tabview: 'template'})
   }
 
+  getFuncNames = (data, funcNames, tableNames) => {
+    data.forEach(item => {
+      if (item.subfuncs) {
+        this.getFuncNames(item.subfuncs, funcNames, tableNames)
+      } else {
+        if (item.tableName) {
+          tableNames.push(item.tableName)
+        }
+        if (item.innerFunc) {
+          funcNames.push({func: item.innerFunc, label: item.label || ''})
+        }
+
+        if (item.callbackFunc) {
+          funcNames.push({func: item.callbackFunc, label: item.label || ''})
+        }
+      }
+    })
+
+    return {
+      func: funcNames,
+      table: tableNames
+    }
+  }
+
   /**
    * @description 涓夌骇鑿滃崟淇濆瓨
    */
   submitConfig = () => {
     const { menu } = this.props
-    const { originMenu, delActions } = this.state
+    const { originMenu, delActions, thawButtons } = this.state
 
     let config = JSON.parse(JSON.stringify(this.state.config))
 
     this.menuformRef.handleConfirm().then(res => {
-
       if (config.isAdd) {
         if (config.search[0] && config.search[0].origin) {
           config.search = config.search.filter(item => !item.origin)
@@ -1470,8 +1473,57 @@
         }
       }
 
+      let btnNames = config.action.map(item => item.label)
+      btnNames = Array.from(new Set(btnNames))
+      if (btnNames.length < config.action.length) {
+        notification.warning({
+          top: 92,
+          message: '鎸夐挳鍚嶇О涓嶅彲鐩稿悓锛�',
+          duration: 5
+        })
+        return
+      }
+
+      let tabNames = []
+      let tablength = 0
+      config.tabgroups.forEach(group => {
+        config[group].forEach(tab => {
+          tabNames.push(tab.label)
+        })
+        tablength += config[group].length
+      })
+      tabNames = Array.from(new Set(tabNames))
+
+      if (tabNames.length < tablength) {
+        notification.warning({
+          top: 92,
+          message: '鏍囩鍚嶇О涓嶅彲鐩稿悓锛�',
+          duration: 5
+        })
+        return
+      }
+
+      if (config.type === 'user') { // 浣跨敤宸叉湁鑿滃崟鏃讹紝榛樿娣诲姞鍏宠仈鏍囩id
+        config.action = config.action.map(item => {
+          if (item.OpenType === 'popview' && !item.linkTab) {
+            item.linkTab = Utils.getuuid()
+          }
+          return item
+        })
+    
+        config.tabgroups.forEach(group => {
+          config[group] = config[group].map(tab => {
+            if (!tab.linkTab) {
+              tab.linkTab = Utils.getuuid()
+            }
+  
+            return tab
+          })
+        })
+      }
+
       let _LongParam = ''
-      let _config = {...config, tables: this.state.selectedTables}
+      let _config = {...config, tables: this.state.selectedTables, easyCode: res.easyCode}
       let _pageParam = {...menu.PageParam, OpenType: res.opentype}
 
       // 鏈缃暟鎹簮鎴栨爣绛句笉鍚堟硶鏃讹紝鍚敤鐘舵�佷负false
@@ -1529,7 +1581,7 @@
             subtype: 'btn',
             uuid: item.uuid,
             label: item.label,
-            tablename: tablename,
+            tableName: tablename,
             intertype: item.intertype,
             interface: item.interface || '',
             innerFunc: item.innerFunc || '',
@@ -1577,9 +1629,9 @@
         
                   if (result.LongParam) {
                     try {
-                      _LongParam = window.decodeURIComponent(window.atob(result.LongParam))
-                      _LongParam = JSON.parse(_LongParam)
+                      _LongParam = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
                     } catch (e) {
+                      console.warn('Parse Failure')
                       _LongParam = ''
                     }
                   }
@@ -1615,7 +1667,7 @@
           notification.warning({
             top: 92,
             message: '缂栬瘧閿欒',
-            duration: 10
+            duration: 5
           })
           this.setState({
             menucloseloading: false,
@@ -1624,6 +1676,9 @@
           return
         }
   
+        let _sort = 0
+        let btntabs = []
+
         let btnParam = {             // 娣诲姞鑿滃崟鎸夐挳
           func: 'sPC_Button_AddUpt',
           Type: 40,                  // 娣诲姞鑿滃崟涓嬬殑鎸夐挳type涓�40锛屾寜閽笅鐨勬寜閽畉ype涓�60
@@ -1632,10 +1687,22 @@
           Template: menu.PageParam.Template || '',
           PageParam: '',
           LongParam: '',
-          LText: config.action.map((item, index) => {
-            return `select '${item.uuid}' as menuid, '${item.label}' as menuname, '${(index + 1) * 10}' as Sort`
-          })
+          LText: []
         }
+
+        _config.action.forEach(item => {
+          _sort++
+          if (item.OpenType === 'popview') {
+            btntabs.push({
+              uuid: item.uuid,
+              linkTab: item.linkTab,
+              label: item.label,
+              sort: _sort
+            })
+          }
+          
+          btnParam.LText.push(`select '${item.uuid}' as menuid, '${item.label}' as menuname, '${_sort * 10}' as Sort`)
+        })
   
         btnParam.LText = btnParam.LText.join(' union all ')
         btnParam.LText = Utils.formatOptions(btnParam.LText)
@@ -1644,28 +1711,57 @@
         
         let tabParam = { // 娣诲姞鑿滃崟tab椤�
           func: 'sPC_sMenusTab_AddUpt',
-          MenuID: menu.MenuID,
-          LText: config.tabs.map((item, index) => {
-            return `select '${menu.MenuID}' as MenuID ,'${item.linkTab}' as Tabid,'${item.label}' as TabName ,'${(index + 1) * 10}' as Sort`
-          })
+          MenuID: menu.MenuID
         }
-        tabParam.LText = tabParam.LText.join(' union all ')
-        tabParam.LText = Utils.formatOptions(tabParam.LText)
+
+        let _LText = []
+
+        btntabs.forEach(item => {
+          _LText.push(`select '${item.uuid}' as MenuID ,'${item.linkTab}' as Tabid,'${item.label}' as TabName ,'${item.sort * 10}' as Sort`)
+        })
+        _config.tabgroups.forEach(groupId => {
+          _config[groupId].forEach(item => {
+            _sort++
+            _LText.push(`select '${menu.MenuID}' as MenuID ,'${item.linkTab}' as Tabid,'${item.label}' as TabName ,'${_sort * 10}' as Sort`)
+          })
+        })
+
+        _LText = _LText.join(' union all ')
+
+        tabParam.LText = Utils.formatOptions(_LText)
         tabParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
         tabParam.secretkey = Utils.encrypt(tabParam.LText, tabParam.timestamp)
   
+        let _vals = this.getFuncNames(_config.funcs, [], [])
+        let _tables = Array.from(new Set(_vals.table))
+
         let param = {
           func: 'sPC_TrdMenu_AddUpt',
+          FstID: res.fstMenuId,
+          SndID: res.parentId,
           ParentID: res.parentId,
           MenuID: menu.MenuID,
           MenuNo: res.menuNo,
+          EasyCode: res.easyCode,
           Template: menu.PageParam.Template || '',
           MenuName: res.menuName,
-          Sort: (this.props.supMenuList.length + 1) * 10,
           PageParam: JSON.stringify(_pageParam),
-          LongParam: _LongParam
+          LongParam: _LongParam,
+          LText: _vals.func.map(item => `select '${menu.MenuID}' as MenuID,'${item.func}' as ProcName,'${item.label}' as MenuName`),
+          LTexttb: _tables.map(item => `select '${menu.MenuID}' as MenuID,'${item}' as tbName`)
         }
-  
+
+        if (menu.menuSort) { // 鑿滃崟鏂板缓鏃惰缃帓搴�
+          param.Sort = menu.menuSort
+        }
+
+        param.LText = param.LText.join(' union all ')
+        param.LText = Utils.formatOptions(param.LText)
+        param.LTexttb = param.LTexttb.join(' union all ')
+        param.LTexttb = Utils.formatOptions(param.LTexttb)
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
+        param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+
         // 鏈夋寜閽垨鏍囩鍒犻櫎鏃讹紝鍏堣繘琛屽垹闄ゆ搷浣�
         // 鍒犻櫎鎴愬姛鍚庯紝淇濆瓨椤甸潰閰嶇疆
         new Promise(resolve => {
@@ -1673,8 +1769,24 @@
             let deffers = delActions.map(item => {
               let _param = {
                 func: 'sPC_MainMenu_Del',
-                MenuID: item
+                MenuID: item.card.uuid
               }
+
+              if (item.type === 'action') {
+                let _ParentParam = null
+
+                try {
+                  _ParentParam = window.btoa(window.encodeURIComponent(JSON.stringify(item.card)))
+                } catch (e) {
+                  console.warn('Stringify Failure')
+                  _ParentParam = null
+                }
+
+                if (_ParentParam) { // 鍒犻櫎鎸夐挳鏃讹紝淇濆瓨鎸夐挳閰嶇疆淇℃伅锛岀敤浜庢仮澶嶆寜閽�
+                  _param.ParentParam = _ParentParam
+                }
+              }
+
               return new Promise(resolve => {
                 Api.getSystemConfig(_param).then(response => {
                   resolve(response)
@@ -1697,7 +1809,7 @@
                 notification.warning({
                   top: 92,
                   message: error.message,
-                  duration: 10
+                  duration: 5
                 })
                 resolve(false)
               } else {
@@ -1712,9 +1824,56 @@
           }
         }).then(resp => {
           if (resp === false) return
-    
+
+          if (thawButtons.length > 0) {
+            let defers = thawButtons.map(item => {
+              return new Promise((resolve) => {
+                Api.getSystemConfig({
+                  func: 'sPC_MainMenu_ReDel',
+                  MenuID: item
+                }).then(res => {
+                  if (res.status) {
+                    resolve('')
+                  } else {
+                    resolve(res.message)
+                  }
+                })
+              })
+            })
+
+            return Promise.all(defers)
+          } else {
+            return true
+          }
+        }).then(res => {
+          if (res === true || res === false) return res
+
+          let msg = res.filter(Boolean)[0]
+          if (msg) {
+            notification.warning({
+              top: 92,
+              message: msg,
+              duration: 5
+            })
+            return false
+          } else {
+            this.setState({
+              thawButtons: []
+            })
+            return true
+          }
+        }).then(resp => {
+          if (resp === false) return
+          let localParam = JSON.parse(JSON.stringify(param))
+
           Api.getSystemConfig(param).then(response => {
             if (response.status) {
+              let _FMenu = originMenu.fstMenuList.filter(fstM => fstM.MenuID === res.fstMenuId)[0]
+              let _supMenuList = []
+              if (_FMenu) {
+                _supMenuList = _FMenu.options
+              }
+
               this.setState({
                 config: _config,
                 originMenu: {
@@ -1723,13 +1882,23 @@
                   PageParam: _pageParam,
                   MenuName: res.menuName,
                   MenuNo: res.menuNo,
-                  ParentID: res.parentId
+                  ParentID: res.parentId,
+                  fstMenuId: res.fstMenuId,
+                  supMenuList: _supMenuList
                 }
               })
     
               this.props.reloadmenu()
               
               this.submitAction(btnParam, tabParam)
+
+              localParam.func = 'sPC_TrdMenu_AddUpt_For_Local'
+              delete localParam.LongParam
+              delete localParam.PageParam
+              delete localParam.Template
+              delete localParam.Sort
+
+              Api.getLocalConfig(localParam)
             } else {
               this.setState({
                 menuloading: false,
@@ -1738,7 +1907,7 @@
               notification.warning({
                 top: 92,
                 message: response.message,
-                duration: 10
+                duration: 5
               })
             }
           })
@@ -1748,7 +1917,7 @@
       notification.warning({
         top: 92,
         message: this.state.dict['header.menu.basemsg'],
-        duration: 10
+        duration: 5
       })
     })
   }
@@ -1800,7 +1969,7 @@
             notification.warning({
               top: 92,
               message: error.message,
-              duration: 10
+              duration: 5
             })
             resolve(false)
           } else {
@@ -1810,6 +1979,8 @@
       }
     }).then(response => {
       if (response === false) return response
+
+      if (!this.state.originActions || this.state.originActions.length === 0) return 'true'
 
       let oriActions = []
       this.state.originActions.forEach(item => {
@@ -1834,13 +2005,45 @@
         }).then(result => {
           if (result.status && result.LongParam) {
             let _LongParam = ''
-  
+            let _temp = ''
+
             if (result.LongParam) {
+              let _subconfig = ''
               try {
-                _LongParam = window.decodeURIComponent(window.atob(result.LongParam))
-                _LongParam = JSON.parse(_LongParam)
+                _subconfig = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
+                _temp = _subconfig.type
               } catch (e) {
-                _LongParam = ''
+                console.warn('Parse Failure')
+                _subconfig = ''
+              }
+
+              if (_temp === 'FormTab') {
+                try {
+                  _subconfig.action = _subconfig.action.map(_btn => {
+                    _btn.uuid = Utils.getuuid()
+
+                    return _btn
+                  })
+                  _subconfig.tabgroups.forEach(_groupId => {
+                    _subconfig[_groupId] = _subconfig[_groupId].map(_tab => {
+                      _tab.uuid = Utils.getuuid()
+  
+                      if (_tab.linkTab) {
+                        _tab.linkTab = ''
+                      }
+
+                      return _tab
+                    })
+                  })
+                  _subconfig = window.btoa(window.encodeURIComponent(JSON.stringify(_subconfig)))
+                } catch {
+                  console.warn('Stringify Failure')
+                  _subconfig = ''
+                }
+
+                _LongParam = _subconfig
+              } else if (_subconfig) {
+                _LongParam = result.LongParam
               }
             }
 
@@ -1850,10 +2053,10 @@
                 ParentID: this.props.menu.MenuID,
                 MenuID: action.curBtn.uuid,
                 MenuNo: this.props.menu.MenuNo,
-                Template: _LongParam.type,
+                Template: _temp,
                 MenuName: action.curBtn.label,
-                PageParam: JSON.stringify({Template: _LongParam.type}),
-                LongParam: result.LongParam
+                PageParam: JSON.stringify({Template: _temp}),
+                LongParam: _LongParam
               }
               Api.getSystemConfig(param).then(() => {})
             }
@@ -1872,6 +2075,7 @@
           this.props.handleView()
         } else {
           this.setState({
+            originActions: [],
             menuloading: false,
             menucloseloading: false
           })
@@ -1897,7 +2101,7 @@
     if (config.isAdd) {
       confirm({
         content: '鑿滃崟灏氭湭鎻愪氦锛岀‘瀹氭斁寮冧繚瀛樺悧锛�',
-        okText: this.state.dict['header.confirm'],
+        okText: this.state.dict['model.confirm'],
         cancelText: this.state.dict['header.cancel'],
         onOk() {
           _this.props.handleView()
@@ -1906,7 +2110,7 @@
       })
     } else {
       this.menuformRef.handleConfirm().then(res => {
-        let _config = {...config, tables: this.state.selectedTables}
+        let _config = {...config, tables: this.state.selectedTables, easyCode: res.easyCode}
         let _pageParam = {...menu.PageParam, OpenType: res.opentype}
         let _originMenu = {
           ...originMenu,
@@ -1914,7 +2118,8 @@
           PageParam: _pageParam,
           MenuName: res.menuName,
           MenuNo: res.menuNo,
-          ParentID: res.parentId
+          ParentID: res.parentId,
+          fstMenuId: res.fstMenuId
         }
 
         if (!is(fromJS(originMenu), fromJS(_originMenu))) {
@@ -1942,7 +2147,7 @@
       notification.warning({
         top: 92,
         message: '璇烽�夋嫨琛ㄥ悕锛�',
-        duration: 10
+        duration: 5
       })
       return
     }
@@ -1995,25 +2200,6 @@
       })
     }
 
-    const textmatch = { // 閫夋嫨text鏃跺尮閰嶈鍒�
-      text: 'like',
-      number: 'like',
-      datetime: 'like',
-      date: 'like'
-    }
-    const selectmatch = { // 閫夋嫨select鏃跺尮閰嶈鍒�
-      text: '=',
-      number: '=',
-      datetime: '=',
-      date: '='
-    }
-    const datematch = { // 閫夋嫨dateRange鏃跺尮閰嶈鍒�
-      text: 'between',
-      number: 'between',
-      datetime: 'between',
-      date: 'between'
-    }
-
     // 鑾峰彇宸查�夊瓧娈甸泦鍚�
     let cards = this.refs.searchcard.state.selectCards
 
@@ -2021,7 +2207,7 @@
       notification.warning({
         top: 92,
         message: '璇烽�夋嫨娣诲姞瀛楁',
-        duration: 10
+        duration: 5
       })
       return
     }
@@ -2041,12 +2227,12 @@
 
           if (cell.type !== item.type) { // 鏁版嵁绫诲瀷淇敼
             if (cell.type === 'select') {
-              item.match = selectmatch[cell.datatype]
+              item.match = '='
             } else if (cell.type === 'daterange') {
-              item.match = datematch[cell.datatype]
+              item.match = 'between'
             } else {
               cell.type = 'text'
-              item.match = textmatch[cell.datatype]
+              item.match = 'like'
             }
             
             item.type = cell.type
@@ -2063,11 +2249,11 @@
       _columns.forEach(item => {
         let _match = ''
         if (item.type === 'select') {
-          _match = selectmatch[item.datatype]
+          _match = '='
         } else if (item.type === 'daterange') {
-          _match = datematch[item.datatype]
+          _match = 'between'
         } else {
-          _match = textmatch[item.datatype]
+          _match = 'like'
         }
 
         let newcard = {
@@ -2188,7 +2374,7 @@
           notification.warning({
             top: 92,
             message: res.message,
-            duration: 10
+            duration: 5
           })
         }
       })
@@ -2227,7 +2413,7 @@
       if (
         res.interType === 'inner' &&
         !res.innerFunc &&
-        res.dataresource.length > 50 &&
+        /[^\s]+\s+[^\s]+/ig.test(res.dataresource) &&
         config.setting.dataresource !== res.dataresource
       ) {
         let param = {
@@ -2243,10 +2429,71 @@
         Api.getLocalConfig(param)
       }
 
-      this.setState({
-        config: {...config, setting: res},
-        settingVisible: false,
-      })
+      
+
+      if (res.interType === 'inner' && !res.innerFunc && /\s/.test(res.dataresource)) {
+        this.setState({
+          sqlVerifing: true
+        })
+
+        let _dataresource = res.dataresource
+
+        if (res.queryType === 'statistics') {
+          let fieldmap = new Map()
+          let options = config.search.map(item => {
+            let _field = item.key
+            let _val = ''
+
+            if (fieldmap.has(_field)) {
+              _field = _field + '1'
+            }
+
+            fieldmap.set(item.key, true)
+
+            if (/date/.test(item.type)) {
+              _val = '1900-01-01'
+            }
+
+            return {
+              reg: new RegExp('@' + _field + '@', 'ig'),
+              value: _val
+            }
+          })
+
+          options.forEach(item => {
+            _dataresource = _dataresource.replace(item.reg, `'${item.value}'`)
+          })
+        }
+
+        let param = {
+          func: 's_debug_sql',
+          LText: _dataresource
+        }
+        param.LText = Utils.formatOptions(param.LText)
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
+        param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+        
+        Api.getLocalConfig(param).then(result => {
+          if (result.status) {
+            this.setState({
+              sqlVerifing: false,
+              config: {...config, setting: res},
+              settingVisible: false
+            })
+          } else {
+            this.setState({sqlVerifing: false})
+            
+            Modal.error({
+              title: result.message
+            })
+          }
+        })
+      } else {
+        this.setState({
+          config: {...config, setting: res},
+          settingVisible: false
+        })
+      }
     })
   }
 
@@ -2255,17 +2502,17 @@
    */
   setSubConfig = (item, type) => {
     const { menu } = this.props
-    const { config, originMenu } = this.state
+    const { config, originMenu, optionLibs, activeKey } = this.state
 
     if (!originMenu.MenuID) { // menuID涓嶅瓨鍦ㄦ椂锛屼负鏂板缓鑿滃崟锛屾彁绀鸿彍鍗曞皻鏈繚瀛�
       notification.warning({
         top: 92,
         message: this.state.dict['header.menu.config.notsave'],
-        duration: 10
+        duration: 5
       })
     } else {
       this.menuformRef.handleConfirm().then(res => {
-        let _config = {...config, tables: this.state.selectedTables}
+        let _config = {...config, tables: this.state.selectedTables, easyCode: res.easyCode}
         let _pageParam = {...menu.PageParam, OpenType: res.opentype}
         let _originMenu = {
           ...originMenu,
@@ -2273,14 +2520,15 @@
           PageParam: _pageParam,
           MenuName: res.menuName,
           MenuNo: res.menuNo,
-          ParentID: res.parentId
+          ParentID: res.parentId,
+          fstMenuId: res.fstMenuId
         }
 
         if (!is(fromJS(originMenu), fromJS(_originMenu))) { // 鑿滃崟淇℃伅鍙樺寲鏃讹紝鎻愮ず淇濆瓨
           notification.warning({
             top: 92,
             message: this.state.dict['header.menu.config.update'],
-            duration: 10
+            duration: 5
           })
           return
         }
@@ -2306,7 +2554,11 @@
           isbutton = false
         }
 
+        // 淇濆瓨褰撳墠鎵撳紑椤电
+        _originMenu.activeKey = activeKey
+
         let param = {
+          optionLibs: optionLibs,
           editMenu: _originMenu,
           editTab: !isbutton ? item : '',
           tabConfig: null,
@@ -2333,10 +2585,10 @@
             })
             let _LongParam = ''
             if (res.LongParam) {
-              _LongParam = window.decodeURIComponent(window.atob(res.LongParam))
               try {
-                _LongParam = JSON.parse(_LongParam)
+                _LongParam = JSON.parse(window.decodeURIComponent(window.atob(res.LongParam)))
               } catch (e) {
+                console.warn('Parse Failure')
                 _LongParam = ''
               }
             }
@@ -2357,7 +2609,7 @@
             notification.warning({
               top: 92,
               message: res.message,
-              duration: 10
+              duration: 5
             })
           }
         })
@@ -2365,7 +2617,7 @@
         notification.warning({
           top: 92,
           message: this.state.dict['header.menu.config.update'],
-          duration: 10
+          duration: 5
         })
       })
     }
@@ -2390,19 +2642,19 @@
       notification.warning({
         top: 92,
         message: '鑿滃崟灏氭湭璁剧疆鏁版嵁婧愶紝涓嶅彲鍚敤锛�',
-        duration: 10
+        duration: 5
       })
     } else if (!config.setting.primaryKey) {
       notification.warning({
         top: 92,
         message: '鑿滃崟灏氭湭璁剧疆涓婚敭锛屼笉鍙惎鐢紒',
-        duration: 10
+        duration: 5
       })
     } else if (!tabinvalid) {
       notification.warning({
         top: 92,
         message: '鑿滃崟鏍囩椤佃缃敊璇紙澶氳鏍囩鍐咃紝琛屾爣绛句笉鍙负绌猴級锛屼笉鍙惎鐢紒',
-        duration: 10
+        duration: 5
       })
     } else {
       this.setState({
@@ -2454,7 +2706,7 @@
 
     confirm({
       content: `纭畾鏂板缓鏍囩缁勫悧锛焋,
-      okText: this.state.dict['header.confirm'],
+      okText: this.state.dict['model.confirm'],
       cancelText: this.state.dict['header.cancel'],
       onOk() {
         let newgroup = 'tabs' + Utils.getuuid()
@@ -2479,7 +2731,7 @@
 
     confirm({
       content: `纭畾鍒犻櫎鏍囩缁勫悧锛焋,
-      okText: this.state.dict['header.confirm'],
+      okText: this.state.dict['model.confirm'],
       cancelText: this.state.dict['header.cancel'],
       onOk() {
 
@@ -2492,6 +2744,47 @@
       },
       onCancel() {}
     })
+  }
+
+  handleGroup = (index, type) => {
+    let config = JSON.parse(JSON.stringify(this.state.config))
+    
+    if (type === 'up') {
+      config.tabgroups.splice(index, 0, config.tabgroups.splice(index - 1, 1)[0])
+    } else {
+      config.tabgroups.splice(index, 0, config.tabgroups.splice(index + 1, 1)[0])
+    }
+
+    this.setState({
+      config: config
+    })
+
+    notification.success({
+      top: 92,
+      message: '璋冩暣鎴愬姛',
+      duration: 2
+    })
+  }
+
+  copycolumn = () => {
+    const { config } = this.state
+
+    let oInput = document.createElement('input')
+    let val = {
+      copyType: 'columns',
+      columns: config.columns
+    }
+
+    oInput.value = window.btoa(window.encodeURIComponent(JSON.stringify(val)))
+    document.body.appendChild(oInput)
+    oInput.select()
+    document.execCommand('Copy')
+    oInput.className = 'oInput'
+    oInput.style.display = 'none'
+
+    message.success('澶嶅埗鎴愬姛銆�')
+
+    document.body.removeChild(oInput)
   }
 
   /**
@@ -2508,25 +2801,49 @@
     this.props.handleView()
   }
 
+  updateConfig = (res) => {
+    if (res.type === 'thaw') {
+      this.setState({
+        thawButtons: res.thawButtons,
+        config: res.config
+      })
+    } else if (res.type === 'paste') {
+      if (res.copyType === 'action') {
+        this.handleAction(res.content, 'copy')
+      } else if (res.copyType === 'columns') {
+        this.setState({
+          config: res.config
+        })
+      }
+    }
+  }
+
   render () {
-    const { modaltype } = this.state
-    const configAction = this.state.config.action.filter(_action =>
+    const { modaltype, activeKey, config } = this.state
+
+    const configAction = config.action.filter(_action =>
       !_action.origin && (_action.OpenType === 'pop' || _action.OpenType === 'popview' || _action.OpenType === 'blank' || _action.OpenType === 'tab')
     )
 
     let configTabs = []
-    this.state.config.tabgroups.forEach(group => {
-      configTabs.push(...this.state.config[group])
+    config.tabgroups.forEach(group => {
+      configTabs.push(...config[group])
     })
+
+    let hasbtncrtinter = false
+    if (modaltype === 'actionEdit' && config.setting.interType === 'inner' && !config.setting.innerFunc && config.setting.dataresource) {
+      hasbtncrtinter = true
+    }
 
     return (
       <div className="common-table-board">
+        {/* <div className="ant-modal-mask"></div> */}
         <DndProvider backend={HTML5Backend}>
           {/* 宸ュ叿鏍� */}
           <div className="tools">
-            <Collapse accordion defaultActiveKey="0" bordered={false}>
+            <Collapse accordion defaultActiveKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}>
               {/* 鍩烘湰淇℃伅 */}
-              <Panel header={this.state.dict['header.menu.basedata']} key="0" id="common-basedata">
+              <Panel forceRender={true} header={this.state.dict['header.menu.basedata']} key="0" id="common-basedata">
                 {/* 鑿滃崟淇℃伅 */}
                 <MenuForm
                   dict={this.state.dict}
@@ -2587,14 +2904,16 @@
                     return (<SourceElement key={index} content={item}/>)
                   })}
                 </div>
-                {configAction.length > 0 ?
-                  <p className="config-btn-title">
-                    <Tooltip placement="topLeft" title="鐐瑰嚮鎸夐挳锛屽彲瀹屾垚鎴栨煡鐪嬫寜閽厤缃俊鎭��">
-                      <Icon type="question-circle" />
-                    </Tooltip>
-                    {this.state.dict['header.menu.action.configurable']}
-                  </p> : null
-                }
+                <div className="config-btn">
+                  {configAction.length > 0 ?
+                    <p className="config-btn-title">
+                      <Tooltip placement="topLeft" title="鐐瑰嚮鎸夐挳锛屽彲瀹屾垚鎴栨煡鐪嬫寜閽厤缃俊鎭��">
+                        <Icon type="question-circle" />
+                      </Tooltip>
+                      {this.state.dict['header.menu.action.configurable']}
+                    </p> : null
+                  }
+                </div>
                 {configAction.map((item, index) => {
                   return (
                     <div key={index}>
@@ -2648,8 +2967,14 @@
             </Collapse>
           </div>
           <div className="setting">
-            <Card title={this.state.dict['header.menu.page.configurable']} bordered={false} extra={
+            <Card title={
               <div>
+                {this.state.dict['header.menu.page.configurable']} 
+                <Icon type="redo" style={{marginLeft: '10px'}} title="鍒锋柊鏍囩鍒楄〃" onClick={this.reloadTab} />
+              </div>
+            } bordered={false} extra={
+              <div>
+                <EditComponent dict={this.state.dict} type="maintable" config={this.state.config} MenuID={this.props.menu.MenuID} thawButtons={this.state.thawButtons} refresh={this.updateConfig}/>
                 <Switch className="big" checkedChildren="鍚�" unCheckedChildren="鍋�" checked={this.state.config.enabled} onChange={this.onEnabledChange} />
                 <Button type="primary" onClick={this.changeTemplate}>{this.state.dict['header.menu.template.change']}</Button>
                 <Button type="primary" onClick={this.submitConfig} loading={this.state.menuloading}>{this.state.dict['header.save']}</Button>
@@ -2663,26 +2988,27 @@
                 </Tooltip>
                 <DragElement
                   type="search"
-                  list={this.state.config.search}
+                  list={config.search}
                   handleList={this.handleList}
                   handleMenu={this.handleSearch}
                   deleteMenu={this.deleteElement}
                   placeholder={this.state.dict['header.form.search.placeholder']}
                 />
               </div>
-              <div className="action-list">
+              <div className="action-list" id="action-list">
                 <Tooltip placement="bottomLeft" overlayClassName="middle" title="鍦ㄥ乏渚у伐鍏锋爮銆婃寜閽�嬩腑锛岄�夋嫨瀵瑰簲绫诲瀷鐨勬寜閽嫋鑷虫澶勬坊鍔狅紝濡傞�夋嫨鎸夐挳绫诲瀷涓鸿〃鍗曘�佹柊鏍囩椤电瓑鍚湁閰嶇疆椤甸潰鐨勬寜閽紝鍙湪宸︿晶宸ュ叿鏍�-鎸夐挳-鍙厤缃寜閽锛岀偣鍑绘寜閽畬鎴愮浉鍏抽厤缃�傛敞锛氬綋璁剧疆鎸夐挳鏄剧ず浣嶇疆涓鸿〃鏍兼椂锛屾樉绀哄垪浼氬鍔犳搷浣滃垪銆�">
                   <Icon type="question-circle" />
                 </Tooltip>
                 <DragElement
                   type="action"
-                  list={this.state.config.action}
-                  setting={this.state.config.setting}
+                  list={config.action}
+                  setting={config.setting}
                   handleList={this.handleList}
                   handleMenu={this.handleAction}
                   copyElement={(val) => this.handleAction(val, 'copy')}
                   deleteMenu={this.deleteElement}
                   profileMenu={this.profileAction}
+                  doubleClickCard={this.btnDoubleClick}
                   placeholder={this.state.dict['header.form.action.placeholder']}
                 />
               </div>
@@ -2691,12 +3017,13 @@
                 <Tooltip placement="bottomLeft" overlayClassName="middle" title="鍦ㄥ乏渚у伐鍏锋爮銆婃樉绀哄垪銆嬩腑锛岄�夋嫨瀵瑰簲绫诲瀷鐨勬樉绀哄垪鎷栬嚦姝ゅ娣诲姞锛涙垨鐐瑰嚮銆婃坊鍔犳樉绀哄垪銆嬫寜閽壒閲忔坊鍔狅紝閫夋嫨鎵归噺娣诲姞鏃讹紝闇�鎻愬墠閫夋嫨浣跨敤琛ㄣ�傛敞锛氭坊鍔犲悎骞跺垪鏃讹紝闇�璁剧疆鍙�夊垪銆�">
                   <Icon type="question-circle" />
                 </Tooltip>
+                {config.columns && config.columns.length > 0 ? <Icon className="column-copy" title="copy" type="copy" onClick={this.copycolumn} /> : null}
                 <Switch checkedChildren="寮�" unCheckedChildren="鍏�" defaultChecked={this.state.showColumnName} onChange={this.onColumnNameChange} />
                 <DragElement
                   type="columns"
-                  list={this.state.config.columns}
-                  setting={this.state.config.setting}
-                  gridBtn={this.state.config.gridBtn}
+                  list={config.columns}
+                  setting={config.setting}
+                  gridBtn={config.gridBtn}
                   handleList={this.handleList}
                   handleMenu={this.handleColumn}
                   deleteMenu={this.deleteElement}
@@ -2706,21 +3033,26 @@
                 />
               </div>
               {/* 鏍囩缁� */}
-              {this.state.config.tabgroups.map((groupId, index) => {
+              {config.tabgroups.map((groupId, index) => {
                 return (
                   <div key={index} className="tab-list">
                     {index === 0 ? <Tooltip placement="bottomLeft" overlayClassName="middle" title="鍦ㄥ乏渚у伐鍏锋爮銆婃爣绛鹃〉銆嬩腑锛岄�夋嫨瀵瑰簲绫诲瀷鐨勬爣绛鹃〉鎷栬嚦姝ゅ娣诲姞銆�">
                       <Icon type="question-circle" />
                     </Tooltip> : null}
+                    {index !== (config.tabgroups.length - 1) ?
+                      <Icon type="arrow-down" onClick={() => {this.handleGroup(index, 'down')}} /> : null
+                    }
+                    {index !== 0 ? <Icon type="arrow-up" onClick={() => {this.handleGroup(index, 'up')}} /> : null}
                     {index === 0 ? <Icon type="plus" onClick={this.addTabGroup} /> : null}
                     {index !== 0 ? <Icon type="delete" onClick={() => {this.delTabGroup(groupId)}} /> : null}
                     <TabDragElement
                       type="tabs"
                       groupId={groupId}
-                      list={this.state.config[groupId]}
+                      list={config[groupId]}
                       handleList={this.handleList}
                       handleMenu={this.handleTab}
                       deleteMenu={this.deleteElement}
+                      doubleClickCard={(tab) => this.setSubConfig(tab, 'tab')}
                       placeholder={this.state.dict['header.form.tab.placeholder']}
                     />
                   </div>)
@@ -2732,15 +3064,18 @@
         <Modal
           title={this.state.dict['header.modal.search.edit']}
           visible={modaltype === 'search'}
-          width={700}
+          width={750}
           maskClosable={false}
           onOk={this.handleSubmit}
+          confirmLoading={this.state.sqlVerifing}
           onCancel={this.editModalCancel}
           destroyOnClose
         >
           <SearchForm
             dict={this.state.dict}
             card={this.state.card}
+            inputSubmit={this.handleSubmit}
+            optionLibs={this.state.optionLibs}
             formlist={this.state.formlist}
             wrappedComponentRef={(inst) => this.searchFormRef = inst}
           />
@@ -2753,9 +3088,10 @@
           maskClosable={false}
           onCancel={this.editModalCancel}
           footer={[
-            modaltype === 'actionEdit' ? <Button key="delete" className="mk-btn mk-purple" onClick={this.creatFunc} loading={this.state.funcLoading}>{this.state.dict['header.menu.func.create']}</Button> : null,
+            hasbtncrtinter ? <CreateInterface key="interface" dict={this.state.dict} ref="btnCreatInterface" trigger={this.btnCreatInterface}/> : null,
+            modaltype === 'actionEdit' ? <CreateFunc key="create" dict={this.state.dict} ref="btnCreatFunc" trigger={this.creatFunc}/> : null,
             <Button key="cancel" onClick={this.editModalCancel}>{this.state.dict['header.cancel']}</Button>,
-            <Button key="confirm" type="primary" onClick={this.handleSubmit}>{this.state.dict['header.confirm']}</Button>
+            <Button key="confirm" type="primary" onClick={this.handleSubmit}>{this.state.dict['model.confirm']}</Button>
           ]}
           destroyOnClose
         >
@@ -2764,7 +3100,8 @@
             card={this.state.card}
             tabs={this.state.tabviews}
             formlist={this.state.formlist}
-            setting={this.state.config.setting}
+            inputSubmit={this.handleSubmit}
+            setting={config.setting}
             wrappedComponentRef={(inst) => this.actionFormRef = inst}
           />
         </Modal>
@@ -2772,7 +3109,7 @@
         <Modal
           title={this.state.dict['header.modal.column.edit']}
           visible={modaltype === 'columns'}
-          width={700}
+          width={750}
           maskClosable={false}
           onOk={this.handleSubmit}
           onCancel={this.editModalCancel}
@@ -2781,6 +3118,8 @@
           <ColumnForm
             dict={this.state.dict}
             card={this.state.card}
+            MenuID={this.props.menu.MenuID}
+            inputSubmit={this.handleSubmit}
             formlist={this.state.formlist}
             wrappedComponentRef={(inst) => this.columnFormRef = inst}
           />
@@ -2798,7 +3137,8 @@
           <ColspanForm
             dict={this.state.dict}
             card={this.state.card}
-            columns={this.state.config.columns}
+            inputSubmit={this.handleSubmit}
+            columns={config.columns}
             wrappedComponentRef={(inst) => this.columnFormRef = inst}
           />
         </Modal>
@@ -2806,7 +3146,7 @@
         <Modal
           title={this.state.dict['header.modal.gridbtn.edit']}
           visible={modaltype === 'gridbtn'}
-          width={700}
+          width={750}
           maskClosable={false}
           onOk={this.handleSubmit}
           onCancel={this.editModalCancel}
@@ -2814,7 +3154,8 @@
         >
           <GridBtnForm
             dict={this.state.dict}
-            card={this.state.config.gridBtn}
+            inputSubmit={this.handleSubmit}
+            card={config.gridBtn}
             wrappedComponentRef={(inst) => this.gridBtnFormRef = inst}
           />
         </Modal>
@@ -2822,7 +3163,7 @@
         <Modal
           title={this.state.dict['header.modal.tabs.edit']}
           visible={modaltype === 'tabs'}
-          width={700}
+          width={750}
           maskClosable={false}
           onOk={this.handleSubmit}
           onCancel={this.editModalCancel}
@@ -2830,17 +3171,18 @@
         >
           <TabForm
             type="tabs"
-            tabs={this.state.tabviews}
             dict={this.state.dict}
             card={this.state.card}
+            tabs={this.state.tabviews}
             formlist={this.state.formlist}
+            inputSubmit={this.handleSubmit}
             wrappedComponentRef={(inst) => this.tabsFormRef = inst}
           />
         </Modal>
         {/* 鏍规嵁瀛楁鍚嶆坊鍔犳樉绀哄垪鍙婃悳绱㈡潯浠� */}
         <Modal
           wrapClassName="common-table-fields-modal"
-          title={this.state.dict['header.edit']}
+          title={this.state.dict['model.edit']}
           visible={this.state.tableVisible}
           width={'65vw'}
           maskClosable={false}
@@ -2870,15 +3212,24 @@
           visible={this.state.profileVisible}
           width={'75vw'}
           style={{minWidth: '900px', maxWidth: '1200px'}}
+          okText={this.state.dict['header.submit']}
           onOk={this.verifySubmit}
           onCancel={() => { this.setState({ profileVisible: false }) }}
           destroyOnClose
         >
-          {this.state.card && this.state.card.OpenType !== 'excelIn' && this.state.card.OpenType !== 'excelOut' ?
+          {this.state.card && !this.state.card.execMode && this.state.card.OpenType !== 'excelIn' && this.state.card.OpenType !== 'excelOut' ?
             <VerifyCard
               card={this.state.card}
               dict={this.state.dict}
-              columns={this.state.config.columns}
+              columns={config.columns}
+              wrappedComponentRef={(inst) => this.verifyRef = inst}
+            /> : null
+          }
+          {this.state.card && this.state.card.execMode ?
+            <VerifyCardPrint
+              card={this.state.card}
+              dict={this.state.dict}
+              columns={config.columns}
               wrappedComponentRef={(inst) => this.verifyRef = inst}
             /> : null
           }
@@ -2886,6 +3237,7 @@
             <VerifyCardExcelIn
               card={this.state.card}
               dict={this.state.dict}
+              columns={config.columns}
               wrappedComponentRef={(inst) => this.verifyRef = inst}
             /> : null
           }
@@ -2899,28 +3251,29 @@
         </Modal>
         {/* 璁剧疆鍏ㄥ眬閰嶇疆鍙婂垪琛ㄦ暟鎹簮 */}
         <Modal
-          title={this.state.dict['header.edit']}
+          title={this.state.dict['model.edit']}
           visible={this.state.settingVisible}
-          width={700}
+          width={750}
           maskClosable={false}
-          // onOk={this.settingSave}
           onCancel={() => { // 鍙栨秷淇敼
             this.setState({
               settingVisible: false
             })
           }}
           footer={[
-            <Button key="delete" className="mk-btn mk-purple" onClick={this.tableCreatFunc} loading={this.state.funcLoading}>{this.state.dict['header.menu.func.create']}</Button>,
+            <CreateInterface key="interface" dict={this.state.dict} ref="tableCreatInterface" trigger={this.tableCreatInterface}/>,
+            <CreateFunc key="create" dict={this.state.dict} ref="tableCreatFunc" trigger={this.tableCreatFunc}/>,
             <Button key="cancel" onClick={() => { this.setState({ settingVisible: false }) }}>{this.state.dict['header.cancel']}</Button>,
-            <Button key="confirm" type="primary" onClick={this.settingSave}>{this.state.dict['header.confirm']}</Button>
+            <Button key="confirm" type="primary" loading={this.state.sqlVerifing} onClick={this.settingSave}>{this.state.dict['model.confirm']}</Button>
           ]}
           destroyOnClose
         >
           <SettingForm
             dict={this.state.dict}
             menu={this.props.menu}
-            data={this.state.config.setting}
-            columns={this.state.config.columns}
+            inputSubmit={this.settingSave}
+            data={config.setting}
+            columns={config.columns}
             usefulFields={this.props.permFuncField}
             wrappedComponentRef={(inst) => this.settingRef = inst}
           />
@@ -2948,6 +3301,7 @@
 
 const mapStateToProps = (state) => {
   return {
+    sysRoles: state.sysRoles,
     permFuncField: state.permFuncField
   }
 }

--
Gitblit v1.8.0