From c0930736f5b5955efecdac4c0ca85957d4f7b574 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期一, 16 十二月 2019 22:55:17 +0800
Subject: [PATCH] 2019-12-16

---
 src/templates/comtableconfig/actionform/index.jsx |   26 +
 src/components/header/index.jsx                   |   33 +
 src/components/sidemenu/editsecmenu/index.jsx     |   20 +
 src/store/reducer.js                              |   27 +
 src/tabviews/commontable/mainAction/index.jsx     |  153 +++++--
 src/store/action-type.js                          |    3 
 src/components/sidemenu/editthdmenu/index.jsx     |   22 +
 src/templates/comtableconfig/index.jsx            |  181 +++++++--
 src/components/header/editmenu/index.jsx          |    2 
 src/tabviews/commontable/mutilform/index.jsx      |   54 ++
 src/templates/modalconfig/index.jsx               |   15 
 src/store/action.js                               |    9 
 src/api/index.js                                  |   18 
 src/components/sidemenu/editsecmenu/index.scss    |   83 ++++
 src/components/sidemenu/index.jsx                 |   79 ++-
 src/locales/zh-CN/comtable.js                     |    2 
 src/tabviews/commontable/index.jsx                |  204 +++++++++-
 src/components/sidemenu/editthdmenu/index.scss    |   81 ++++
 src/utils/utils.js                                |   72 +++
 src/assets/css/main.scss                          |    4 
 20 files changed, 903 insertions(+), 185 deletions(-)

diff --git a/src/api/index.js b/src/api/index.js
index c74c629..026eddc 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -137,6 +137,22 @@
   }
 
   /**
+   * @description 鑾峰彇鎴栦慨鏀规湰鍦伴厤缃紝澧炲姞appkey
+   */
+  getLocalConfig (param) {
+    param.userid = sessionStorage.getItem('UserID')
+    param.lang = localStorage.getItem('lang') || ''
+    param.SessionUid = sessionStorage.getItem('SessionUid') || ''
+    param.LoginUID = sessionStorage.getItem('LoginUID') || ''
+    param.appkey = window.GLOB.appkey || ''
+
+    return axios({
+      url: '/webapi/dostar',
+      data: param
+    })
+  }
+
+  /**
    * @description 鑾峰彇绯荤粺閰嶇疆锛屼紭鍏堜粠缂撳瓨涓彇鍊硷紝澧炲姞appkey
    */
   getSystemCacheConfig (param) {
@@ -178,7 +194,7 @@
     param.lang = localStorage.getItem('lang') || ''
     param.SessionUid = sessionStorage.getItem('SessionUid') || ''
     param.LoginUID = sessionStorage.getItem('LoginUID') || ''
-    param.appkey = window.GLOB.appkey || ''
+    // param.appkey = window.GLOB.appkey || ''
     
     return axios({
       url: '/webapi/dostar',
diff --git a/src/assets/css/main.scss b/src/assets/css/main.scss
index 3155d2c..2776c11 100644
--- a/src/assets/css/main.scss
+++ b/src/assets/css/main.scss
@@ -136,6 +136,10 @@
   z-index: 1100!important;
 }
 
+.ant-select-dropdown {
+  z-index: 1090!important;
+}
+
 // 纭鎻愮ず妗嗛珮搴�
 .ant-modal.ant-modal-confirm {
   top: 38vh;
diff --git a/src/components/header/editmenu/index.jsx b/src/components/header/editmenu/index.jsx
index ad4a74e..2443710 100644
--- a/src/components/header/editmenu/index.jsx
+++ b/src/components/header/editmenu/index.jsx
@@ -323,7 +323,7 @@
             鐐瑰嚮娣诲姞鍥炬爣锛屽彲鏂板涓�绾ц彍鍗曘��
           </div>
           <div className="tipcard card5">
-            <p>缂栬緫鐘舵�佷腑锛屼竴绾ц彍鍗曚箣澶栧尯鍩熶細閿佸畾锛屾煡鐪嬬郴缁熸暟鎹鐐瑰嚮銆�</p>
+            <p>缂栬緫鐘舵�佷腑锛岃彍鍗曚箣澶栧尯鍩熶細閿佸畾锛屾煡鐪嬬郴缁熸暟鎹鐐瑰嚮銆�</p>
             <div>
               <a target="blank" href="#/main" >鏂伴〉闈�</a>
             </div>
diff --git a/src/components/header/index.jsx b/src/components/header/index.jsx
index 752bfe3..539228e 100644
--- a/src/components/header/index.jsx
+++ b/src/components/header/index.jsx
@@ -6,7 +6,16 @@
 import moment from 'moment'
 import {Dropdown, Menu, Icon, Modal, Form, notification, Switch } from 'antd'
 import asyncComponent from '@/utils/asyncComponent'
-import {toggleCollapse, modifyMainMenu, resetState, resetDebug, resetEditState, resetEditLevel, logout} from '@/store/action'
+import {
+  toggleCollapse,
+  modifyMainMenu,
+  resetState,
+  resetDebug,
+  resetEditState,
+  resetEditLevel,
+  initPermission,
+  logout
+} from '@/store/action'
 import Api from '@/api'
 import zhCN from '@/locales/zh-CN/header.js'
 import enUS from '@/locales/en-US/header.js'
@@ -184,7 +193,24 @@
     // 鑾峰彇涓昏彍鍗�
     let result = await Api.getSystemConfig({func: 'sPC_Get_RolesMenu'})
     if (result.status) {
+      let _permAction = {}
+      let _permFuncField = []
+      if (result.UserRoles && result.UserRoles[0] && result.UserRoles[0].RoleMenu) {
+        result.UserRoles[0].RoleMenu.forEach(menu => {
+          _permAction[menu.MenuID] = true
+        })
+      }
 
+      if (result.sModular && result.sModular.length > 0) {
+        result.sModular.forEach(field => {
+          if (field.ModularNo) {
+            _permFuncField.push(field.ModularNo)
+          }
+        })
+        _permFuncField = _permFuncField.sort()
+      }
+
+      this.props.initPermission(_permAction, _permFuncField)
     }
   }
 
@@ -293,7 +319,9 @@
     selectmenu: state.selectedMainMenu,
     debug: state.debug,
     editState: state.editState,
-    editLevel: state.editLevel
+    editLevel: state.editLevel,
+    permAction: state.permAction,
+    permFuncField: state.permFuncField
   }
 }
 
@@ -303,6 +331,7 @@
     modifyMainMenu: (selectmenu) => dispatch(modifyMainMenu(selectmenu)),
     resetEditState: (state) => dispatch(resetEditState(state)),
     resetEditLevel: (level) => dispatch(resetEditLevel(level)),
+    initPermission: (permAction, permFuncField) => dispatch(initPermission(permAction, permFuncField)),
     resetState: () => dispatch(resetState()),
     resetDebug: () => dispatch(resetDebug()),
     logout: () => dispatch(logout())
diff --git a/src/components/sidemenu/editsecmenu/index.jsx b/src/components/sidemenu/editsecmenu/index.jsx
index 0b240e9..12d8c85 100644
--- a/src/components/sidemenu/editsecmenu/index.jsx
+++ b/src/components/sidemenu/editsecmenu/index.jsx
@@ -377,6 +377,26 @@
   render () {
     return (
       <div className="second-edit-box">
+        <div className="mask">
+          <div className="tipcard card1">
+            鎷栧姩浜岀骇鑿滃崟鍙皟鏁撮『搴忥紝椤哄簭璋冩暣鍚庯紝璇风偣鍑荤‘瀹氭寜閽繚瀛樸��
+          </div>
+          <div className="tipcard card2">
+            鐐瑰嚮缂栬緫鍥炬爣鍙慨鏀硅彍鍗曞睘鎬э紝鐐瑰嚮鍒犻櫎鍥炬爣鍙垹闄よ彍鍗曘��
+          </div>
+          <div className="tipcard card3">
+            鐐瑰嚮瑙i櫎鍐荤粨鎸夐挳锛屽彲杩樺師宸插垹闄ょ殑浜岀骇鑿滃崟銆�
+          </div>
+          <div className="tipcard card4">
+            鐐瑰嚮娣诲姞鍥炬爣锛屽彲鏂板浜岀骇鑿滃崟銆�
+          </div>
+          <div className="tipcard card5">
+            <p>缂栬緫鐘舵�佷腑锛岃彍鍗曚箣澶栧尯鍩熶細閿佸畾锛屾煡鐪嬬郴缁熸暟鎹鐐瑰嚮銆�</p>
+            <div>
+              <a target="blank" href="#/main" >鏂伴〉闈�</a>
+            </div>
+          </div>
+        </div>
         {this.state.show && <DndProvider backend={HTML5Backend}>
           <DragElement
             list={this.props.menulist}
diff --git a/src/components/sidemenu/editsecmenu/index.scss b/src/components/sidemenu/editsecmenu/index.scss
index e69de29..b97d11d 100644
--- a/src/components/sidemenu/editsecmenu/index.scss
+++ b/src/components/sidemenu/editsecmenu/index.scss
@@ -0,0 +1,83 @@
+.second-edit-box {
+  .mask {
+    position: fixed;
+    top: 0px;
+    left: 0px;
+    right: 0px;
+    bottom: 0px;
+    .tipcard {
+      position: absolute;
+      min-height: 100px;
+      font-size: 16px;
+      border-radius: 6px;
+      background-size: 100% 100%;
+      background-repeat: no-repeat;
+      padding: 15px;  
+    }
+    .card1 {
+      left: 30%;
+      top: 20vh;
+      width: 230px;
+      min-height: 100px;
+      background-image: url('../../../assets/img/card-bg2.jpg');
+      color: #000000;
+      font-style: oblique;
+    }
+    .card2 {
+      left: 60%;
+      top: 20vh;
+      width: 230px;
+      min-height: 100px;
+      background-image: url('../../../assets/img/card-bg5.jpg');
+      color: #000000;
+      padding: 20px 30px;
+      font-style: oblique;
+    }
+    .card3 {
+      left: 30%;
+      top: 50vh;
+      width: 230px;
+      min-height: 140px;
+      background-image: url('../../../assets/img/card-bg8.jpg');
+      color: #000000;
+      padding: 20px 30px;
+      font-style: oblique;
+    }
+    .card4 {
+      left: 60%;
+      top: 50vh;
+      width: 230px;
+      min-height: 140px;
+      background-image: url('../../../assets/img/card-bg7.jpg');
+      color: #000000;
+      padding: 20px 30px;
+      font-style: oblique;
+    }
+    .card5 {
+      right: 5%;
+      top: 20vh;
+      width: 130px;
+      min-height: 240px;
+      background-image: url('../../../assets/img/card-bg6.jpg');
+      color: #000000;
+      padding: 40px 15px 10px;
+      p {
+        margin: 0 0 5px;
+      }
+      div {
+        text-align: center;
+        a {
+          display: inline-block;
+          color: #fff;
+          padding: 2px 10px;
+          border-radius: 4px;
+          background-color: #1890ff;
+          border-color: #1890ff;
+          text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
+          -webkit-box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
+          box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/components/sidemenu/editthdmenu/index.jsx b/src/components/sidemenu/editthdmenu/index.jsx
index d38a258..2e91133 100644
--- a/src/components/sidemenu/editthdmenu/index.jsx
+++ b/src/components/sidemenu/editthdmenu/index.jsx
@@ -416,6 +416,28 @@
   render () {
     return (
       <div className="third-edit-box">
+        {!this.state.tabview ?
+          <div className="mask">
+            <div className="tipcard card1">
+              鎷栧姩涓夌骇鑿滃崟鍙皟鏁撮『搴忥紝椤哄簭璋冩暣鍚庯紝璇风偣鍑荤‘瀹氭寜閽繚瀛樸��
+            </div>
+            <div className="tipcard card2">
+              鐐瑰嚮缂栬緫鍥炬爣浼氭牴鎹彍鍗曟ā鏉匡紝杩涘叆鐩稿簲鐨勬ā鏉跨紪杈戦〉闈紝鐐瑰嚮鍒犻櫎鍥炬爣鍙垹闄よ彍鍗曘��
+            </div>
+            <div className="tipcard card3">
+              鐐瑰嚮瑙i櫎鍐荤粨鎸夐挳锛屽彲杩樺師宸插垹闄ょ殑涓夌骇鑿滃崟銆�
+            </div>
+            <div className="tipcard card4">
+              鐐瑰嚮娣诲姞鍥炬爣锛屼細鏄剧ず绯荤粺妯℃澘鍜屽凡浣跨敤妯℃澘锛岄�夋嫨宸蹭娇鐢ㄦā鏉挎椂锛屼細澶嶅埗宸叉坊鍔犺彍鍗曠殑閰嶇疆淇℃伅銆�
+            </div>
+            <div className="tipcard card5">
+              <p>缂栬緫鐘舵�佷腑锛岃彍鍗曚箣澶栧尯鍩熶細閿佸畾锛屾煡鐪嬬郴缁熸暟鎹鐐瑰嚮銆�</p>
+              <div>
+                <a target="blank" href="#/main" >鏂伴〉闈�</a>
+              </div>
+            </div>
+          </div> : null
+        }
         <div className="cus-submenu-title">
           <Icon type={this.props.supMenu.PageParam.Icon} />
           <span>{this.props.supMenu.text}</span>
diff --git a/src/components/sidemenu/editthdmenu/index.scss b/src/components/sidemenu/editthdmenu/index.scss
index 0ebba4f..832bbaf 100644
--- a/src/components/sidemenu/editthdmenu/index.scss
+++ b/src/components/sidemenu/editthdmenu/index.scss
@@ -1,4 +1,85 @@
 .third-edit-box {
+  .mask {
+    position: fixed;
+    top: 0px;
+    left: 0px;
+    right: 0px;
+    bottom: 0px;
+    .tipcard {
+      position: absolute;
+      min-height: 100px;
+      font-size: 16px;
+      border-radius: 6px;
+      background-size: 100% 100%;
+      background-repeat: no-repeat;
+      padding: 15px;  
+    }
+    .card1 {
+      left: 30%;
+      top: 20vh;
+      width: 250px;
+      min-height: 100px;
+      background-image: url('../../../assets/img/card-bg2.jpg');
+      color: #000000;
+      font-style: oblique;
+    }
+    .card2 {
+      left: 60%;
+      top: 20vh;
+      width: 250px;
+      min-height: 100px;
+      background-image: url('../../../assets/img/card-bg5.jpg');
+      color: #000000;
+      padding: 20px 30px;
+      font-style: oblique;
+    }
+    .card3 {
+      left: 30%;
+      top: 50vh;
+      width: 250px;
+      min-height: 150px;
+      background-image: url('../../../assets/img/card-bg8.jpg');
+      color: #000000;
+      padding: 20px 30px;
+      font-style: oblique;
+    }
+    .card4 {
+      left: 60%;
+      top: 50vh;
+      width: 250px;
+      min-height: 150px;
+      background-image: url('../../../assets/img/card-bg7.jpg');
+      color: #000000;
+      padding: 20px 30px;
+      font-style: oblique;
+    }
+    .card5 {
+      right: 5%;
+      top: 20vh;
+      width: 130px;
+      min-height: 240px;
+      background-image: url('../../../assets/img/card-bg6.jpg');
+      color: #000000;
+      padding: 40px 15px 10px;
+      p {
+        margin: 0 0 5px;
+      }
+      div {
+        text-align: center;
+        a {
+          display: inline-block;
+          color: #fff;
+          padding: 2px 10px;
+          border-radius: 4px;
+          background-color: #1890ff;
+          border-color: #1890ff;
+          text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
+          -webkit-box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
+          box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
+        }
+      }
+    }
+  }
   .cus-submenu-title {
     padding: 0px 24px;
     background: #364150;
diff --git a/src/components/sidemenu/index.jsx b/src/components/sidemenu/index.jsx
index 43397f7..d0b092b 100644
--- a/src/components/sidemenu/index.jsx
+++ b/src/components/sidemenu/index.jsx
@@ -3,7 +3,7 @@
 import PropTypes from 'prop-types'
 import {connect} from 'react-redux'
 import { is, fromJS } from 'immutable'
-import { Menu, Icon } from 'antd'
+import { Menu, Icon, notification } from 'antd'
 import asyncComponent from '@/utils/asyncComponent'
 import {modifyTabview, resetEditLevel} from '@/store/action'
 import zhCN from '@/locales/zh-CN/header.js'
@@ -25,12 +25,12 @@
   }
 
   state = {
-    mainMenuList: null, // 涓�绾ц彍鍗曪紝缂栬緫璋冩暣涓婄骇鑿滃崟鏃惰幏鍙�
-    subMenulist: null, // 浜岀骇鑿滃崟
-    editMenu: null, // 缂栬緫涓夌骇鑿滃崟鏃惰缃�
+    dict: (!localStorage.getItem('lang') || localStorage.getItem('lang') === 'zh-CN') ? zhCN : enUS,
+    mainMenuList: null,      // 涓�绾ц彍鍗曪紝缂栬緫璋冩暣涓婄骇鑿滃崟鏃惰幏鍙�
+    subMenulist: null,       // 浜岀骇鑿滃崟
+    editMenu: null,          // 缂栬緫涓夌骇鑿滃崟鏃惰缃�
     rootSubmenuKeys: null,
     createThirdMenu: false,
-    dict: (!localStorage.getItem('lang') || localStorage.getItem('lang') === 'zh-CN') ? zhCN : enUS,
     openKeys: null,
     preview: null
   }
@@ -38,17 +38,39 @@
   async loadsubmenu (menu) {
     let result = await Api.getSystemConfig({func: 'sPC_Get_FunMenu', ParentID: menu.MenuID})
     if (result.status) {
+      if (result.data.length === 0) { // 鏌ヨ鑿滃崟涓虹┖
+        this.setState({
+          subMenulist: [],
+          rootSubmenuKeys: [],
+          openKeys: [],
+          editMenu: null
+        })
+        return
+      }
+
       let param = sessionStorage.getItem('view_param') // 鏄惁涓烘墦寮�鏂伴〉闈�
       let msg = sessionStorage.getItem('UserID') + '&' + sessionStorage.getItem('SessionUid') + '&' + sessionStorage.getItem('LoginUID')
-      let submenuindex = 0 // 灞曞紑浜岀骇鑿滃崟绱㈠紩
-      let tabindex = null // 鎵撳紑鐨則ab椤�
+      let submenuId = '' // 灞曞紑浜岀骇鑿滃崟ID
+      let tabId = '' // 鎵撳紑鐨則ab椤礽d
+      
       if (param) {
         param = param.split('&')
-        submenuindex = parseInt(param[1])
-        tabindex = parseInt(param[2])
+        submenuId = param[1]
+        let submenu = result.data.filter(item => item.ParentID === submenuId)[0]
+
+        if (!submenu) {
+          submenuId = ''
+        } else {
+          tabId = param[2]
+          let tabmenu = submenu.FunMenu.filter(item => item.MenuID === tabId)[0]
+          if (!tabmenu) {
+            submenuId = ''
+            tabId = ''
+          }
+        }
         sessionStorage.removeItem('view_param')
       }
-      let parentID = result.data[submenuindex] ? result.data[submenuindex].ParentID : '' // 灞曞紑浜岀骇鑿滃崟ID
+      let parentID = submenuId ? submenuId : result.data[0].ParentID // 灞曞紑浜岀骇鑿滃崟ID
 
       let menulist = result.data.map((item, i) => {
         let _smenu = {}
@@ -63,7 +85,7 @@
         if (item.FunMenu) {
           _smenu.children = item.FunMenu.map((child, n) => {
             let _tmenu = {}
-            let _msg = window.btoa(menu.MenuID + '&' + i + '&' + n + '&' + msg) // 寰呭畬鍠�
+            let _msg = window.btoa(menu.MenuID + '&' + _smenu.MenuID + '&' + child.MenuID + '&' + msg) // 寰呭畬鍠�
             _tmenu.src = '#/main/' + _msg
             if (child.LinkUrl === 'CommonTable') {
               _tmenu.type = 'CommonTable'
@@ -100,30 +122,24 @@
       this.setState({
         subMenulist: menulist,
         rootSubmenuKeys: result.data.map(item => item.ParentID),
-        openKeys: (this.props.collapse || !parentID) ? [] : [parentID],
+        openKeys: this.props.collapse ? [] : [parentID],
         editMenu: this.props.editLevel === 'level3' && menulist.filter(menu => menu.MenuID === this.state.editMenu.MenuID)[0]
       })
+      if (tabId) {
+        let _menu = menulist.filter(menu => menu.MenuID === submenuId)[0]
+        let opentab = _menu && _menu.children.filter(tab => tab.MenuID === tabId)[0]
 
-      if (tabindex !== null) {
-        let opentab = result.data[submenuindex].children[tabindex]
-        opentab.selected = true
-        this.props.modifyTabview([opentab])
+        if (opentab) {
+          opentab.selected = true
+          this.props.modifyTabview([opentab])
+        }
       }
-
-      // this.props.modifyTabview([{
-      //   Action: 'Index',
-      //   Icon: 'Content/icons/L32X32/RoleM.png',
-      //   LinkUrl: 'bda/rdt?pageno=rolemenus&MenuNo=RoleMenuM',
-      //   MenuID: 'MMenu14002DBD0010',
-      //   MenuName: '瑙掕壊鏉冮檺鍒嗛厤',
-      //   MenuNo: 'RoleMenuM',
-      //   Ot: '绌�',
-      //   PageParam: '',
-      //   SortSub: '720',
-      //   id: 3,
-      //   selected: true,
-      //   type: 'RoleManage'
-      // }])
+    } else {
+      notification.warning({
+        top: 92,
+        message: result.message,
+        duration: 10
+      })
     }
   }
 
@@ -143,6 +159,7 @@
       })
       menu.selected = true
       tabs.push(menu)
+
       this.props.modifyTabview(tabs)
       e.preventDefault()
     }
diff --git a/src/locales/zh-CN/comtable.js b/src/locales/zh-CN/comtable.js
index 6eb9119..a065c53 100644
--- a/src/locales/zh-CN/comtable.js
+++ b/src/locales/zh-CN/comtable.js
@@ -123,7 +123,7 @@
   'header.form.custom': '鑷畾涔�',
   'header.form.datasource': '鏁版嵁婧�',
   'header.form.actionhelp.datasource': '浣跨敤绯荤粺鍑芥暟鏃讹紝璇峰~鍐欐暟鎹簮锛屼娇鐢ㄨ嚜瀹氫箟鍑芥暟鏃讹紝鍙拷鐣ャ��',
-  'header.form.actionhelp.sqlType': '浣跨敤绯荤粺鍑芥暟鏃讹紝璇烽�夋嫨绫诲瀷锛屼娇鐢ㄨ嚜瀹氫箟鍑芥暟鏃讹紝鍙拷鐣ャ��',
+  'header.form.actionhelp.sqlType': '浣跨敤绯荤粺鍑芥暟鏃讹紝璇烽�夋嫨鎿嶄綔绫诲瀷锛屼娇鐢ㄨ嚜瀹氫箟鍑芥暟鏃讹紝鍙拷鐣ャ��',
   'header.form.action.type': '鎿嶄綔绫诲瀷',
   'header.form.action.insert': '娣诲姞',
   'header.form.action.update': '淇敼',
diff --git a/src/store/action-type.js b/src/store/action-type.js
index 5666d95..cd2ee8c 100644
--- a/src/store/action-type.js
+++ b/src/store/action-type.js
@@ -25,5 +25,8 @@
 // 閲嶇疆缂栬緫绾у埆
 export const RESET_EDITLEVEL = 'RESET_EDITLEVEL'
 
+// 鍒濆鍖栨寜閽潈闄愬強鍒涘缓瀛樺偍杩囩▼鍙敤瀛楁
+export const INIT_PERMISSION = 'INIT_PERMISSION'
+
 // 閫�鍑�
 export const LOGOUT = 'LOGOUT'
\ No newline at end of file
diff --git a/src/store/action.js b/src/store/action.js
index 0453b80..ea3b57c 100644
--- a/src/store/action.js
+++ b/src/store/action.js
@@ -70,6 +70,15 @@
   }
 }
 
+// 鍒濆鍖栨寜閽潈闄愬強鍒涘缓瀛樺偍杩囩▼鍙敤瀛楁
+export const initPermission = (permAction, permFuncField) => {
+  return {
+    type: user.INIT_PERMISSION,
+    permAction: permAction,
+    permFuncField: permFuncField
+  }
+}
+
 // 閫�鍑洪噸缃�
 export const logout = () => {
   return {
diff --git a/src/store/reducer.js b/src/store/reducer.js
index 9b17627..ec5a293 100644
--- a/src/store/reducer.js
+++ b/src/store/reducer.js
@@ -2,13 +2,15 @@
 
 let defaultState = {
   selectedMainMenu: '', // 宸查�変富鑿滃崟
-  tabviews: [], // 瀵艰埅鏍�
-  collapse: false, // 鏄惁鏀惰捣渚ц竟鏍忓鑸�
-  isiframe: false, // 鏄惁涓篿frame绐楀彛
-  debug: false, // 鐭ュ惁鍙互澶嶅埗鑿滃崟鍙傛暟, 鏄惁鍙繘鍏ョ紪杈戞ā寮�
-  editState: false, // 鏄惁涓虹紪杈戠姸鎬侊紝鍊间负false銆乼rue
-  editLevel: null, // 缂栬緫鑿滃崟绾у埆锛屽�间负level1銆乴evel2銆乴evel3銆傘�傘��
-  refreshTab: null // 鍒锋柊tabview椤甸潰淇℃伅
+  tabviews: [],         // 瀵艰埅鏍�
+  collapse: false,      // 鏄惁鏀惰捣渚ц竟鏍忓鑸�
+  isiframe: false,      // 鏄惁涓篿frame绐楀彛
+  debug: false,         // 鐭ュ惁鍙互澶嶅埗鑿滃崟鍙傛暟, 鏄惁鍙繘鍏ョ紪杈戞ā寮�
+  editState: false,     // 鏄惁涓虹紪杈戠姸鎬侊紝鍊间负false銆乼rue
+  editLevel: null,      // 缂栬緫鑿滃崟绾у埆锛屽�间负level1銆乴evel2銆乴evel3銆傘�傘��
+  refreshTab: null,     // 鍒锋柊tabview椤甸潰淇℃伅
+  permAction: {},
+  permFuncField: []
 }
 
 // 鐢ㄦ埛娑堟伅
@@ -75,6 +77,13 @@
         editLevel: action.editLevel,
         tabviews: []
       }
+    case Type.INIT_PERMISSION:
+    // 鍒濆鍖栨寜閽潈闄愬強鍒涘缓瀛樺偍杩囩▼鍙敤瀛楁
+      return {
+        ...state,
+        permAction: action.permAction,
+        permFuncField: action.permFuncField
+      }
     case Type.LOGOUT:
       return {
         selectedMainMenu: '',
@@ -84,7 +93,9 @@
         debug: false,
         editState: false,
         editLevel: null,
-        refreshTab: null
+        refreshTab: null,
+        permAction: {},
+        permFuncField: []
       }
     default:
       return state
diff --git a/src/tabviews/commontable/index.jsx b/src/tabviews/commontable/index.jsx
index 893367c..00cccd9 100644
--- a/src/tabviews/commontable/index.jsx
+++ b/src/tabviews/commontable/index.jsx
@@ -162,7 +162,6 @@
     let deffers = []
     searchlist.forEach(item => {
       if (item.type !== 'select' && item.type !== 'link') return
-
       if (item.setAll === 'true') {
         item.options.unshift({
           key: Utils.getuuid(),
@@ -172,11 +171,15 @@
       }
 
       if (item.resourceType === '1' && item.dataSource) {
+        let arrfield = item.valueField + ',' + item.valueText
+        if (item.type === 'link') {
+          arrfield = arrfield + ',' + item.linkField
+        }
         let param = {
           func: 'sPC_Get_SelectedList',
           LText: item.dataSourceSql,
           obj_name: 'data',
-          arr_field: item.valueField + ',' + item.valueText
+          arr_field: arrfield
         }
 
         param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
@@ -231,35 +234,138 @@
 
   improveAction = () => {
     const { config } = this.state
-    config.action.forEach(item => {
-      if (item.OpenType !== 'pop' && item.OpenType !== 'tab' && item.OpenType !== 'blank') return
 
-      Api.getSystemCacheConfig({
-        func: 'sPC_Get_LongParam',
-        MenuID: item.uuid
-      }).then(res => {
-        if (res.status) {
-          let _LongParam = ''
-          if (res.LongParam) {
-            _LongParam = window.decodeURIComponent(window.atob(res.LongParam))
-            try {
-              _LongParam = JSON.parse(_LongParam)
-            } catch (e) {
-              _LongParam = ''
-            }
-          }
-
-          this.setState({
-            configMap: {...this.state.configMap, [item.uuid]: _LongParam}
+    let conAction = config.action.filter(item => (item.OpenType === 'pop' || item.OpenType === 'tab' || item.OpenType === 'blank'))
+    
+    if (conAction.length > 0) {
+      let deffers = conAction.map(item => {
+        return new Promise(resolve => {
+          Api.getSystemCacheConfig({
+            func: 'sPC_Get_LongParam',
+            MenuID: item.uuid
+          }).then(res => {
+            res.uuid = item.uuid
+            resolve(res)
           })
-        } else {
+        })
+      })
+
+      let _action = {}
+      let error = ''
+      Promise.all(deffers).then(result => {
+        result.forEach(res => {
+          if (res.status) {
+            let _LongParam = ''
+            if (res.LongParam) {
+              _LongParam = window.decodeURIComponent(window.atob(res.LongParam))
+              try {
+                _LongParam = JSON.parse(_LongParam)
+              } catch (e) {
+                _LongParam = ''
+              }
+            }
+
+            if (_LongParam) {
+              _action[res.uuid] = _LongParam
+            }
+          } else {
+            error = res
+            
+          }
+        })
+
+        this.setState({
+          configMap: {...this.state.configMap, ..._action}
+        })
+
+        if (error) {
           notification.warning({
             top: 92,
-            message: res.message,
+            message: error.message,
             duration: 10
           })
+        } else {
+          this.improveActionForm(Object.values(_action))
         }
       })
+    }
+  }
+
+  improveActionForm = (actions) => {
+    let subfields = []
+    actions.forEach(item => {
+      if (item.groups.length > 0) {
+        item.groups.forEach(group => {
+          group.sublist.forEach(field => {
+            if ((field.type === 'select' || field.type === 'link') && field.resourceType === '1') {
+              subfields.push(field)
+            }
+          })
+        })
+      } else {
+        item.fields.forEach(field => {
+          if ((field.type === 'select' || field.type === 'link') && field.resourceType === '1') {
+            subfields.push(field)
+          }
+        })
+      }
+    })
+
+    let deffers = subfields.map(item => {
+      let arrfield = item.valueField + ',' + item.valueText
+
+      if (item.type === 'link') {
+        arrfield = arrfield + ',' + item.linkField
+      }
+
+      let param = {
+        func: 'sPC_Get_SelectedList',
+        LText: item.dataSourceSql,
+        obj_name: 'data',
+        arr_field: arrfield
+      }
+
+      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
+      param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+      console.log(item)
+      return new Promise(resolve => {
+        Api.getSystemCacheConfig(param).then(res => {
+          res.search = item
+          resolve(res)
+        })
+      })
+    })
+
+    let _field = {}
+    let error = ''
+    Promise.all(deffers).then(result => {
+      result.forEach(res => {
+        if (res.status) {
+          let options = res.data.map(cell => {
+            return {
+              key: Utils.getuuid(),
+              Value: cell[res.search.valueField],
+              Text: cell[res.search.valueText]
+            }
+          })
+
+          _field[res.search.uuid] = options
+        } else {
+          error = res
+        }
+      })
+
+      this.setState({
+        configMap: {...this.state.configMap, ..._field}
+      })
+
+      if (error) {
+        notification.warning({
+          top: 92,
+          message: error.message,
+          duration: 10
+        })
+      }
     })
   }
 
@@ -326,6 +432,7 @@
 
     this.setState({
       loading: true,
+      pageIndex: 1,
       search: searches
     }, () => {
       this.loadmaindata()
@@ -353,15 +460,52 @@
     })
   }
 
+  reloadtable = () => {
+    this.refs.mainTable.resetTable()
+    this.setState({
+      loading: true,
+      pageIndex: 1
+    }, () => {
+      this.loadmaindata()
+    })
+  }
+
+  reloadview = () => {
+    this.setState({
+      loadingview: true,    // 椤甸潰鍔犺浇涓�
+      viewlost: false,      // 椤甸潰涓㈠け锛�1銆佹湭鑾峰彇鍒伴厤缃�-椤甸潰涓㈠け锛�2銆侀〉闈㈡湭鍚敤
+      lostmsg: '',          // 椤甸潰涓㈠け鏃剁殑鎻愮ず淇℃伅
+      config: {},
+      searchlist: null,
+      actions: null,
+      columns: null,
+      arr_field: '',
+      setting: null,
+      data: null,
+      total: 0,
+      loading: false,
+      pageIndex: 1,
+      pageSize: 10,
+      orderColumn: '',
+      orderType: 'asc',
+      search: '',
+      configMap: {}
+    }, () => {
+      this.loadconfig()
+    })
+  }
+
   refreshbyaction = (btn, type) => {
     // 鎸夐挳鎿嶄綔鍚庡埛鏂拌〃鏍�,閲嶇疆椤电爜鍙婇�夋嫨椤�
-    console.log(btn)
-    console.log(type)
-    this.refs.mainTable.resetTable()
-    // this.loadmaindata(1, this.state.param.pageSize, this.state.param.orderColumn, this.state.param.orderType, this.state.param.search)
-    // this.setState({
-    //   loading: true
-    // })
+    if (btn.execSuccess === 'grid' && type === 'success') {
+      this.reloadtable()
+    } else if (btn.execError === 'grid' && type === 'error') {
+      this.reloadview()
+    } else if (btn.execSuccess === 'view' && type === 'success') {
+      this.reloadtable()
+    } else if (btn.execError === 'view' && type === 'error') {
+      this.reloadview()
+    }
   }
 
   gettableselected = () => {
diff --git a/src/tabviews/commontable/mainAction/index.jsx b/src/tabviews/commontable/mainAction/index.jsx
index f7e16d1..0469e7c 100644
--- a/src/tabviews/commontable/mainAction/index.jsx
+++ b/src/tabviews/commontable/mainAction/index.jsx
@@ -1,8 +1,9 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-// import { is, fromJS } from 'immutable'
+import moment from 'moment'
 import { Button, Affix, Modal, notification } from 'antd'
 import MutilForm from '../mutilform'
+import Utils from '@/utils/utils.js'
 import Api from '@/api'
 import './index.scss'
 
@@ -100,38 +101,80 @@
     }
   }
 
-  execSubmit = (btn, data, _resolve) => {
+  execSubmit = (btn, data, _resolve, formdata) => {
     const { setting } = this.props
     if (btn.intertype === 'inner') {
-      // 浣跨敤鍐呴儴鎺ュ彛鏃讹紝鍐呴儴鍑芥暟鍜屾暟鎹簮涓嶅彲鍚屾椂涓虹┖
-      if (!btn.innerFunc && !btn.sql) {
+      // 浣跨敤鍐呴儴鎺ュ彛鏃讹紝鍐呴儴鍑芥暟鍜屾暟鎹簮涓嶅彲鍚屾椂涓虹┖, 浣跨敤绯荤粺鍑芥暟鏃讹紝绫诲瀷涓嶅彲涓虹┖
+      if (!btn.innerFunc && (!btn.sql || (btn.sql && !btn.sqlType))) {
         this.actionSettingError()
         _resolve()
         return
       }
 
-      if (btn.Ot === 'notRequired' || btn.Ot === 'requiredSgl' || btn.Ot === 'requiredOnce') {
-        // 鑾峰彇id
-        let param = {
+      if (
+        btn.Ot === 'notRequired' ||
+        btn.Ot === 'requiredSgl' ||
+        (btn.Ot === 'requiredOnce' && btn.OpenType !== 'pop') ||
+        (btn.OpenType === 'pop' && !btn.innerFunc && btn.sql && btn.sqlType === 'insert')
+      ) {
+        let param = { // 绯荤粺瀛樺偍杩囩▼
           func: 'sPC_TableData_InUpDe'
         }
-        let ID = ''
-        if (btn.Ot === 'notRequired') {
-          
-        } else if (btn.Ot === 'requiredSgl') {
-          ID = data[0][setting.primaryKey]
-        } else if (btn.Ot === 'requiredOnce') {
-          let ids = data.map(d => { return d[setting.primaryKey]})
-          ID = ids.join(',')
-        }
 
-        if (btn.innerFunc) {
-          param.func = btn.innerFunc
+        if (btn.OpenType === 'prompt' || btn.OpenType === 'exec') { // 鏄惁寮规鎴栫洿鎺ユ墽琛�
+          let ID = ''
+          if (btn.Ot === 'notRequired') {
+            
+          } else if (btn.Ot === 'requiredSgl') {
+            ID = data[0][setting.primaryKey]
+          } else if (btn.Ot === 'requiredOnce') {
+            let ids = data.map(d => { return d[setting.primaryKey]})
+            ID = ids.join(',')
+          }
+
           param.ID = ID
           param.BID = ''
-        } else if (btn.sql) {
-          param.LText = btn.sql // 鏁版嵁婧�
+
+          if (btn.innerFunc) {
+            param.func = btn.innerFunc
+          } else if (btn.sql) {
+            param.LText = Utils.formatOptions(Utils.getSysDefaultSql(btn, setting)) // 鏁版嵁婧�
+            param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
+            param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+          }
+        } else if (btn.OpenType === 'pop') { // 琛ㄥ崟
+          if (btn.innerFunc) {
+            param.func = btn.innerFunc
+
+            formdata.forEach(_data => {
+              param[_data.key] = _data.value
+            })
+            if (setting.primaryKey) {
+              if (!param.hasOwnProperty(setting.primaryKey) && data[0] && data[0][setting.primaryKey]) {
+                param[setting.primaryKey] = data[0][setting.primaryKey]
+              }
+            }
+            if (!param.hasOwnProperty('ID') && setting.primaryKey && data[0] && data[0][setting.primaryKey]) {
+              param.ID = data[0][setting.primaryKey]
+            }
+            if (!param.hasOwnProperty('BID')) {
+              param.BID = ''
+            }
+          } else if (btn.sql && btn.sqlType === 'insert') {
+            param.ID = Utils.getguid()
+            param.BID = ''
+            param.LText = Utils.formatOptions(Utils.getSysDefaultSql(btn, setting, formdata)) // 鏁版嵁婧�
+            param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
+            param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+          } else if (btn.sql) {
+            param.ID = data[0][setting.primaryKey]
+            param.BID = ''
+            param.LText = Utils.formatOptions(Utils.getSysDefaultSql(btn, setting, formdata)) // 鏁版嵁婧�
+            param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
+            param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+          }
         }
+        
 
         Api.genericInterface(param).then((res) => {
           if (res.status) {
@@ -141,19 +184,43 @@
           }
           _resolve()
         })
-      } else if (btn.Ot === 'required') {
+      } else if (btn.Ot === 'required' || (btn.Ot === 'requiredOnce' && btn.OpenType === 'pop')) {
         let deffers = data.map(cell => {
           let param = {
             func: 'sPC_TableData_InUpDe'
           }
-          let ID = cell[setting.primaryKey]
 
-          if (btn.innerFunc) {
-            param.func = btn.innerFunc
-            param.ID = ID
+          if (btn.OpenType === 'prompt' || btn.OpenType === 'exec') { // 鏄惁寮规鎴栫洿鎺ユ墽琛�
+            param.ID = cell[setting.primaryKey]
             param.BID = ''
-          } else if (btn.sql) {
-            param.LText = btn.sql // 鏁版嵁婧�
+
+            if (btn.innerFunc) {
+              param.func = btn.innerFunc
+            } else if (btn.sql) {
+              param.LText = Utils.formatOptions(Utils.getSysDefaultSql(btn, setting)) // 鏁版嵁婧�
+              param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
+              param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+            }
+          } else if (btn.OpenType === 'pop') { // 琛ㄥ崟
+            if (btn.innerFunc) {
+              param.func = btn.innerFunc
+  
+              formdata.forEach(_data => {
+                param[_data.key] = _data.value
+              })
+              if (!param.hasOwnProperty(setting.primaryKey) && cell[setting.primaryKey]) {
+                param[setting.primaryKey] = cell[setting.primaryKey]
+              }
+              if (!param.hasOwnProperty('ID') && cell[setting.primaryKey]) {
+                param.ID = cell[setting.primaryKey]
+              }
+            } else if (btn.sql) {
+              param.ID = cell[setting.primaryKey]
+              param.BID = ''
+              param.LText = Utils.formatOptions(Utils.getSysDefaultSql(btn, setting, formdata)) // 鏁版嵁婧�
+              param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
+              param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+            }
           }
 
           return new Promise(resolve => {
@@ -439,6 +506,11 @@
       message: this.props.dict['main.action.confirm.success'],
       duration: 5
     })
+    if (btn.OpenType === 'pop') {
+      this.setState({
+        visible: false
+      })
+    }
     this.refreshdata(btn, 'success')
   }
 
@@ -464,26 +536,12 @@
       this.setState({
         confirmLoading: true
       })
+      this.execSubmit(this.state.execAction, this.state.tabledata, () => {
+        this.setState({
+          confirmLoading: false
+        })
+      }, res)
       console.log(res)
-      // Api.setActionSubmit({
-      //   func: 'SetActionSubmitSuccess'
-      // }).then((res) => {
-      //   if (res.status) {
-      //     notification.success({
-      //       top: 92,
-      //       message: this.props.dict['main.action.confirm.success']
-      //     })
-      //     this.setState({
-      //       confirmLoading: false,
-      //       visible: false
-      //     })
-      //   } else {
-      //     notification.error({
-      //       top: 92,
-      //       message: res.message
-      //     })
-      //   }
-      // })
     }, () => {})
   }
 
@@ -526,7 +584,8 @@
         <MutilForm
           dict={this.props.dict}
           action={execAction}
-          data={this.state.tabledata}
+          configMap={this.props.configMap}
+          data={this.state.tabledata[0]}
           wrappedComponentRef={(inst) => this.formRef = inst}
         />
       </Modal>
diff --git a/src/tabviews/commontable/mutilform/index.jsx b/src/tabviews/commontable/mutilform/index.jsx
index 391eb45..9bf97eb 100644
--- a/src/tabviews/commontable/mutilform/index.jsx
+++ b/src/tabviews/commontable/mutilform/index.jsx
@@ -2,6 +2,7 @@
 import PropTypes from 'prop-types'
 import { Form, Row, Col, Input, InputNumber, Select, DatePicker } from 'antd'
 import moment from 'moment'
+import Utils from '@/utils/utils.js'
 import './index.scss'
 
 const {MonthPicker} = DatePicker
@@ -10,17 +11,20 @@
   static propTpyes = {
     action: PropTypes.object, // 鎼滅储鏉′欢鍒楄〃
     dict: PropTypes.object, // 瀛楀吀椤�
-    data: PropTypes.any // 琛ㄦ牸鏁版嵁
+    data: PropTypes.any, // 琛ㄦ牸鏁版嵁
+    configMap: PropTypes.object
   }
 
   state = {
     datatype: null,
+    readtype: null,
     formlist: []
   }
 
   componentDidMount () {
     const { action } = this.props
     let datatype = {}
+    let readtype = {}
     let formlist = []
     if (action.groups.length > 0) {
       action.groups.forEach(group => {
@@ -36,17 +40,36 @@
 
         group.sublist.forEach(item => {
           datatype[item.field] = item.type
+          readtype[item.field] = item.readonly === 'true'
           formlist.push(item)
         })
       })
     } else {
       formlist = action.fields.map(item => {
         datatype[item.field] = item.type
+        readtype[item.field] = item.readonly === 'true'
+
+        if (item.type === 'select' || item.type === 'link') {
+          if (item.setAll === 'true') {
+            item.options.unshift({
+              key: Utils.getuuid(),
+              Value: '',
+              Text: this.props.dict['main.all']
+            })
+          }
+
+          if (item.resourceType === '1' && this.props.configMap.hasOwnProperty(item.uuid)) {
+            item.options = [...item.options, ...this.props.configMap[item.uuid]]
+          }
+          console.log(item)
+        }
+
         return item
       })
     }
 
     this.setState({
+      readtype: readtype,
       datatype: datatype,
       formlist: formlist
     })
@@ -114,7 +137,7 @@
             </Form.Item>
           </Col>
         )
-      } else if (item.type === 'select') { // 涓嬫媺鎼滅储
+      } else if (item.type === 'select' || item.type === 'link') { // 涓嬫媺鎼滅储
         fields.push(
           <Col span={24 / cols} key={index}>
             <Form.Item label={item.label}>
@@ -130,7 +153,7 @@
                 <Select
                   showSearch
                   filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
-                  getPopupContainer={() => document.getElementById('form-box')}
+                  // getPopupContainer={() => document.getElementById('form-box')}
                 >
                   {item.options.map(option =>
                     <Select.Option id={option.key} title={option.Text} key={option.key} value={option.Value}>{option.Text}</Select.Option>
@@ -226,39 +249,50 @@
         if (!err) {
           let search = []
           Object.keys(values).forEach(key => {
-            if (this.state.style[key] === 'datetime') {
+            if (this.state.datatype[key] === 'datetime') {
               let _value = ''
               if (values[key]) {
                 _value = moment(values[key]).format('YYYY-MM-DD HH:mm:ss')
               }
               search.push({
-                type: this.state.style[key],
+                type: this.state.datatype[key],
+                readonly: this.state.readtype[key],
                 key: key,
                 value: _value
               })
-            } else if (this.state.style[key] === 'datemonth') {
+            } else if (this.state.datatype[key] === 'datemonth') {
               let _value = ''
               if (values[key]) {
                 _value = moment(values[key]).format('YYYY-MM')
               }
               search.push({
-                type: this.state.style[key],
+                type: this.state.datatype[key],
+                readonly: this.state.readtype[key],
                 key: key,
                 value: _value
               })
-            } else if (this.state.style[key] === 'date') {
+            } else if (this.state.datatype[key] === 'date') {
               let _value = ''
               if (values[key]) {
                 _value = moment(values[key]).format('YYYY-MM-DD')
               }
               search.push({
-                type: this.state.style[key],
+                type: this.state.datatype[key],
+                readonly: this.state.readtype[key],
                 key: key,
                 value: _value
               })
+            } else if (this.state.datatype[key] === 'number') {
+              search.push({
+                type: this.state.datatype[key],
+                readonly: this.state.readtype[key],
+                key: key,
+                value: values[key]
+              })
             } else {
               search.push({
-                type: this.state.style[key],
+                type: this.state.datatype[key],
+                readonly: this.state.readtype[key],
                 key: key,
                 value: values[key].replace(/(^\s*|\s*$)/ig, '')
               })
diff --git a/src/templates/comtableconfig/actionform/index.jsx b/src/templates/comtableconfig/actionform/index.jsx
index 14250ea..b1f06d8 100644
--- a/src/templates/comtableconfig/actionform/index.jsx
+++ b/src/templates/comtableconfig/actionform/index.jsx
@@ -210,6 +210,21 @@
       if (item.hidden) return
 
       if (item.type === 'text') { // 鏂囨湰鎼滅储
+        let _rules = []
+        if (item.key === 'innerFunc') {
+          let str = '^(' + item.fields.join('|') + ')'
+          let _patten = new RegExp(str + '[0-9a-zA-Z_]*', 'ig')
+          _rules = [{
+            pattern: _patten,
+            message: '鍚嶇О鍙厑璁稿寘鍚暟瀛椼�佸瓧姣嶅拰涓嬪垝绾匡紝涓斾互鎸囧畾瀛楃寮�濮嬨��'
+          }, {
+            min: 6,
+            message: '鍐呴儴鍑芥暟鍚嶇О涓嶅皬浜�6涓瓧绗︺��'
+          }, {
+            max: 100,
+            message: '鍐呴儴鍑芥暟鍚嶇О涓嶈秴杩�100涓瓧绗︺��'
+          }]
+        }
         fields.push(
           <Col span={12} key={index}>
             <Form.Item label={item.tooltip ?
@@ -224,7 +239,8 @@
                   {
                     required: item.readonly ? false : !!item.required,
                     message: this.props.dict['form.required.input'] + item.label + '!'
-                  }
+                  },
+                  ..._rules
                 ]
               })(<Input placeholder="" autoComplete="off" disabled={item.readonly} />)}
             </Form.Item>
@@ -317,13 +333,19 @@
             values.position = 'toolbar'
             values.Ot = 'notRequired'
           }
-
+          console.log(values)
           if (values.innerFunc === '' && values.sql === '') {
             notification.warning({
               top: 92,
               message: this.props.dict['header.form.actionhelp.datasource'],
               duration: 10
             })
+          } else if (values.innerFunc === '' && values.sql !== '' && values.sqlType === '') {
+            notification.warning({
+              top: 92,
+              message: this.props.dict['header.form.actionhelp.sqlType'],
+              duration: 10
+            })
           } else {
             resolve({
               type: 'action',
diff --git a/src/templates/comtableconfig/index.jsx b/src/templates/comtableconfig/index.jsx
index 75af4d9..e0fe8b5 100644
--- a/src/templates/comtableconfig/index.jsx
+++ b/src/templates/comtableconfig/index.jsx
@@ -1,5 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
+import {connect} from 'react-redux'
 import { is, fromJS } from 'immutable'
 import { DndProvider } from 'react-dnd'
 import HTML5Backend from 'react-dnd-html5-backend'
@@ -60,7 +61,8 @@
     selectedTables: [],      // 宸查�夎〃鍚�
     originMenu: null,        // 鍘熷鑿滃崟
     originActions: null,
-    delActions: []
+    delActions: [],
+    funcLoading: false
   }
 
   /**
@@ -471,6 +473,7 @@
   }
 
   handleAction = (card) => {
+    let ableField = this.props.permFuncField.join(', ')
     this.setState({
       visible: true,
       formtemp: 'action',
@@ -557,9 +560,10 @@
           label: this.state.dict['header.form.innerFunc'],
           initVal: card.innerFunc,
           tooltip: <div>
-            <p>鍐呴儴鎺ュ彛: 鍙嚜瀹氫箟鏁版嵁澶勭悊鍑芥暟锛屾湭璁剧疆鏃朵細璋冪敤绯荤粺鍑芥暟锛屼娇鐢ㄧ郴缁熷嚱鏁伴渶瀹屽杽鏁版嵁婧愬強鎿嶄綔绫诲瀷;</p>
+            <p>鍐呴儴鎺ュ彛: 鍙嚜瀹氫箟鏁版嵁澶勭悊鍑芥暟锛屽嚱鏁板悕绉伴渶浠ableField}绛夊瓧绗﹀紑濮嬶紱鏈缃椂浼氳皟鐢ㄧ郴缁熷嚱鏁帮紝浣跨敤绯荤粺鍑芥暟闇�瀹屽杽鏁版嵁婧愬強鎿嶄綔绫诲瀷;</p>
             <p>澶栭儴鎺ュ彛: 鍙嚜瀹氫箟鏁版嵁澶勭悊鍑芥暟锛屾彁浜ゆ暟鎹粡杩囧唴閮ㄥ嚱鏁板鐞嗗悗锛屼紶鍏ュ閮ㄦ帴鍙o紝鏈缃椂锛屾暟鎹細鐩存帴浼犲叆澶栭儴鎺ュ彛銆�</p>
           </div>,
+          fields: this.props.permFuncField,
           tooltipClass: 'middle',
           required: false,
           readonly: false
@@ -686,10 +690,13 @@
           type: 'select',
           key: 'sqlType',
           label: this.state.dict['header.form.action.type'],
-          initVal: card.sqlType || 'insert',
+          initVal: card.sqlType || '',
           tooltip: this.state.dict['header.form.actionhelp.sqlType'],
           required: false,
           options: [{
+            MenuID: '',
+            text: this.state.dict['header.form.empty']
+          }, {
             MenuID: 'insert',
             text: this.state.dict['header.form.action.insert']
           }, {
@@ -1039,15 +1046,21 @@
     }
   }
 
+  /**
+   * @description 鍒涘缓鎸夐挳瀛樺偍杩囩▼
+   */
   creatFunc = () => {
     let _config = JSON.parse(JSON.stringify(this.state.config))
 
     this.formRef.handleConfirm().then(res => {
-      let btn = res.values
-      let LText = ''
-      let DelText = ''
-      let isExit = false
+      let btn = res.values  // 鎸夐挳淇℃伅
+      let newLText = ''     // 鍒涘缓瀛樺偍杩囩▼sql
+      let DelText = ''      // 鍒犻櫎瀛樺偍杩囩▼sql
+      let isExit = false    // 瀛樺偍杩囩▼鏄惁瀛樺湪
+      let sysTVPText = ''   // 宸叉湁鐨勫瓨鍌ㄨ繃绋嬭鍙�(浜戠)
+      let localTVPText = '' // 宸叉湁鐨勫瓨鍌ㄨ繃绋嬭鍙�(鏈湴)
 
+      // 鍒涘缓瀛樺偍杩囩▼锛屽繀椤诲~鍐欏唴閮ㄥ嚱鏁板悕
       if (!btn.innerFunc) {
         notification.warning({
           top: 92,
@@ -1057,8 +1070,14 @@
         return
       }
 
+      // 鍒涘缓涓�
+      this.setState({
+        funcLoading: true
+      })
+
       new Promise(resolve => {
-        // 鍐呴儴璇锋眰
+        // 寮圭獥锛堣〃鍗曪級绫绘寜閽紝鍏堣幏鍙栨寜閽厤缃俊鎭紝濡傛灉灏氭湭閰嶇疆鎸夐挳鍒欎細鎶ラ敊骞剁粓姝€��
+        // 鑾峰彇淇℃伅鍚庣敓鎴愬垹闄ゅ拰鍒涘缓瀛樺偍杩囩▼鐨勮鍙�
         if (btn.OpenType === 'pop') {
           Api.getSystemConfig({
             func: 'sPC_Get_LongParam',
@@ -1090,7 +1109,7 @@
                 fields: fields,
                 menuNo: this.props.menu.MenuNo
               }
-              LText = Utils.formatOptions(Utils.getfunc(_param))
+              newLText = Utils.formatOptions(Utils.getfunc(_param))
               DelText = Utils.formatOptions(Utils.dropfunc(_param.funcName))
               resolve(true)
             } else {
@@ -1109,44 +1128,101 @@
             fields: '',
             menuNo: this.props.menu.MenuNo
           }
-          LText = Utils.formatOptions(Utils.getfunc(_param))
+          newLText = Utils.formatOptions(Utils.getfunc(_param))
           DelText = Utils.formatOptions(Utils.dropfunc(_param.funcName))
           resolve(true)
         }
       }).then(res => {
+        // 鑾峰彇浜戠鍙婃湰鍦帮紝鏄惁宸插瓨鍦ㄨ瀛樺偍杩囩▼鐨勪俊鎭�
         console.log(res)
         if (res === false) return res
-        
-        return Api.getSystemConfig({
-          func: 'sPC_Get_TVP',
-          TVPName: btn.innerFunc
-        })
-      }).then(res => {
-        console.log(res)
-        if (res === false) return res
-        if (!res.status) {
-          notification.warning({
-            top: 92,
-            message: res.message,
-            duration: 10
-          })
-          return false
-        }
 
-        if (res.TVPText && LText === res.TVPText) {
-          return 'drop'
-        } else {
-          if (res.TVPText) {
-            isExit = true
+        let sysDefer = new Promise(resolve => {
+          Api.getSystemConfig({
+            func: 'sPC_Get_TVP', // 浜戠鑾峰彇瀛樺偍缁撴灉
+            TVPName: btn.innerFunc
+          }).then(result => {
+            resolve(result)
+          })
+        })
+
+        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 => {
+        // 浜戠缁撴灉涓庢柊璇彞涓嶅悓鏃讹紝鏇存柊浜戠淇℃伅
+        console.log(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 {
+            console.log(result.Ltext)
+            if (result.Ltext) { // 鏈湴瀛樺偍杩囩▼鏄惁瀛樺湪
+              isExit = true
+            }
+            localTVPText = Utils.formatOptions(result.Ltext)
+          }
+        })
+
+        if (isError) return false
+        
+        if ((newLText === localTVPText) && (newLText === sysTVPText)) {
+          return 'drop'
+        } else if (!localTVPText || (sysTVPText === localTVPText)) {
+          // 鏈湴瀛樺偍杩囩▼涓嶅瓨鍦紝鎴栦簯绔拰鏈湴瀛樺偍杩囩▼涓�鑷存椂锛屽皢鏂扮殑瀛樺偍杩囩▼鏇存柊鑷充簯绔�
           return Api.getSystemConfig({
             func: 'sPC_TVP_InUp',
             TVPName: btn.innerFunc,
-            TVPText: LText,
+            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 => {
+        // 浜戠淇℃伅鏇存柊鍚庯紝鍒ゆ柇鏄垹闄ゆ垨鏄洿鎺ユ柊寤哄瓨鍌ㄨ繃绋�
         console.log(res)
         if (res === false || res === 'drop') return res
 
@@ -1163,17 +1239,22 @@
           return 'create'
         }
       }).then(res => {
+        // 鍒犻櫎瀛樺偍杩囩▼
         console.log(res)
         if (res === false || res === 'create') return res
 
         let _param = {
           func: 'sPC_TableData_InUpDe',
-          LText: DelText
+          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.getSystemConfig(_param)
+
+        return Api.getLocalConfig(_param)
       }).then(res => {
+        // 鏍规嵁涓婅堪鎿嶄綔缁撴灉锛屽垽鏂槸鍚︽柊寤哄瓨鍌ㄨ繃绋�
         console.log(res)
         if (res === false || res === 'create') return res
 
@@ -1188,18 +1269,21 @@
           return 'create'
         }
       }).then(res => {
+        // 鏂板缓瀛樺偍杩囩▼
         console.log(res)
         if (res === false) return res
 
         let _param = {
           func: 'sPC_TableData_InUpDe',
-          LText: LText
+          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.getSystemConfig(_param)
+        return Api.getLocalConfig(_param)
       }).then(res => {
+        // 澶勭悊鏂板缓缁撴灉
         console.log(res)
         if (res === false) return res
 
@@ -1219,8 +1303,14 @@
           return true
         }
       }).then(res => {
+        // 鏂板缓鎴愬姛鍚庯紝鏇存柊椤甸潰鎸夐挳淇℃伅
         console.log(res)
-        if (res === false) return res
+        if (res === false) {
+          this.setState({
+            funcLoading: false
+          })
+          return
+        }
 
         let isupdate = false
         _config.action = _config.action.map(item => {
@@ -1263,7 +1353,8 @@
 
         this.setState({
           config: _config,
-          actionloading: true
+          actionloading: true,
+          funcLoading: false
         }, () => {
           this.setState({
             actionloading: false
@@ -2177,7 +2268,7 @@
           onOk={this.handleSubmit}
           footer={[
             this.state.formtemp === 'action' ?
-            <Button key="delete" className="mk-btn mk-purple" onClick={this.creatFunc} loading={this.state.confirmLoading}>{this.state.dict['header.menu.func.create']}</Button> : null,
+            <Button key="delete" className="mk-btn mk-purple" onClick={this.creatFunc} loading={this.state.funcLoading}>{this.state.dict['header.menu.func.create']}</Button> : null,
             <Button key="cancel" onClick={() => { this.setState({ visible: false }) }}>{this.state.dict['header.cancel']}</Button>,
             <Button key="confirm" type="primary" onClick={this.handleSubmit}>{this.state.dict['header.confirm']}</Button>
           ]}
@@ -2287,4 +2378,14 @@
   }
 }
 
-export default ComTableConfig
\ No newline at end of file
+const mapStateToProps = (state) => {
+  return {
+    permFuncField: state.permFuncField
+  }
+}
+
+const mapDispatchToProps = () => {
+  return {}
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(ComTableConfig)
diff --git a/src/templates/modalconfig/index.jsx b/src/templates/modalconfig/index.jsx
index 0b30439..cf0a7cb 100644
--- a/src/templates/modalconfig/index.jsx
+++ b/src/templates/modalconfig/index.jsx
@@ -75,6 +75,11 @@
       _config.setting.title = editAction.label
     }
 
+    if (menu.LongParam.tables && menu.LongParam.tables.length > 0 && _config.tables.length === 0) {
+      // 涓昏彍鍗曞凡鏈夐�夋嫨鐨勮〃鍚嶏紝妯℃�佹娌℃湁琛ㄥ悕鏃讹紝澶嶅埗涓昏彍鍗曡〃鍚�
+      _config.tables = menu.LongParam.tables
+    }
+
     this.setState({
       config: _config,
       selectedTables: _config.tables || [],
@@ -483,10 +488,14 @@
       let _config = JSON.parse(JSON.stringify(this.state.config))
 
       if ((res.type === 'select' || res.type === 'link') && res.resourceType === '1') {
-        let sql = 'select ' + res.valueField + ',' + res.valueText + ' from (' + res.dataSource + ')'
-        if (res.orderBy) {
-          sql = sql + ' ld order by ' + res.orderBy + ' ' + res.orderType
+        let sql = 'select ' + res.valueField + ',' + res.valueText + ' from ' + res.dataSource
+        if (res.type === 'link') {
+          sql = 'select ' + res.valueField + ',' + res.valueText + ',' + res.linkField + ' from ' + res.dataSource
         }
+        if (res.orderBy) {
+          sql = sql + ' order by ' + res.orderBy + ' ' + res.orderType
+        }
+        console.log(sql)
         res.dataSourceSql = Utils.formatOptions(sql)
       }
 
diff --git a/src/utils/utils.js b/src/utils/utils.js
index d76bdcd..62df4d8 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -25,13 +25,14 @@
    */
   static getguid () {
     // 浜х敓涓�涓柊鐨凣UID鍊�
-    let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
-      let r = Math.random() * 16 | 0
-      // eslint-disable-next-line
-      let v = (c === 'x') ? r : (r & 0x3 | 0x8)
-      return v.toString(16)
-    })
-    return uuid
+    let uuid = []
+    let d = new Date()
+    let options = '0123456789abcdefghigklmnopqrstuv'
+    for (let i = 0; i < 19; i++) {
+      uuid.push(options.substr(Math.floor(Math.random() * 0x20), 1))
+    }
+    uuid = moment().format('YYYYMMDDHHmmss') + d.getMilliseconds() + uuid.join('')
+    return uuid.toUpperCase()
   }
 
   /**
@@ -317,6 +318,59 @@
   }
 
   /**
+   * @description 浣跨敤绯荤粺鍑芥暟鏃讹紙sPC_TableData_InUpDe 锛夛紝鐢熸垚sql璇彞
+   * @return {String} type   鎵ц绫诲瀷
+   * @return {String} table  琛ㄥ悕
+   */
+  static getSysDefaultSql (btn, setting, formdata) {
+    console.log(btn)
+    console.log(formdata)
+    let _sql = ''
+    if (btn.OpenType === 'pop' && btn.sqlType === 'insert') {
+      let keys = []
+      let values = []
+      formdata.forEach(item => {
+        if (!item.readonly && item.type === 'number') {
+          keys.push(item.key)
+          values.push(item.value)
+        } else if (!item.readonly) {
+          keys.push(item.key)
+          values.push('\'' + item.value + '\'')
+        }
+      })
+      keys = keys.join(',')
+      values = values.join(',')
+
+      _sql = `insert into ${btn.sql} (${keys}, createuserid) select ${values},@userid`
+    } else if (btn.OpenType === 'pop' && btn.sqlType === 'update') {
+      let _form = []
+      formdata.forEach(item => {
+        if (!item.readonly && item.type === 'number') {
+          _form.push(item.key + '=' + item.value)
+        } else if (!item.readonly) {
+          _form.push(item.key + '=\'' + item.value + '\'')
+        }
+      })
+      _form = _form.join(',')
+      _sql = `update ${btn.sql} set ${_form},modifydate=getdate(),modifyuserid=@userid where ${setting.primaryKey}=@id`
+    } else if ((btn.OpenType === 'prompt' || btn.OpenType === 'exec') && btn.sqlType === 'LogicDelete') { // 閫昏緫鍒犻櫎
+      _sql = `update ${btn.sql} set deleted=1,modifydate=getdate(),modifyuserid=@userid where ${setting.primaryKey}=@id`
+    } else if ((btn.OpenType === 'prompt' || btn.OpenType === 'exec') && btn.sqlType === 'delete') {
+      _sql = `insert into snote (remark,createuserid) select '鍒犻櫎琛�:${btn.sql} 鏁版嵁: id='+@id,@userid delete ${btn.sql} where ${setting.primaryKey}=@id`
+    }
+    //insert into 琛ㄥ悕 (琛ㄥ崟瀛楁锛岄�楀彿鍒嗛殧锛屽鏋滀富閿负鍙紪杈戝垯浼犲~鍐欏唴瀹癸紝鍙鎴栨病鏈夐厤缃〃鍗曪紝鍒欎紶鍓嶇鐢熸垚id,+createuserid)
+    // +select 琛ㄥ崟瀛楁鍊�+@userid
+
+    // 淇敼锛歶pdate 琛ㄥ悕 set 琛ㄥ崟闈炲彧璇诲瓧娈�=琛ㄥ崟鍊硷紝modifydate=getdate(),modifyuserid=@userid where 涓婚敭=@id琛宨d
+
+    // 閫昏緫鍒犻櫎:update 琛ㄥ悕 set deleted=1锛宮odifydate=getdate(),modifyuserid=@userid where 涓婚敭=@id琛宨d
+
+    // 鐗╃悊鍒犻櫎锛歩nsert into snote (remark,createuserid) select '鍒犻櫎琛� '+琛ㄥ悕+'鏁版嵁 '+id=@id delete 琛ㄥ悕 where  涓婚敭=@id琛宨d
+    console.log(_sql)
+    return _sql
+  }
+
+  /**
    * @description 鍒犻櫎瀛樺偍杩囩▼sql
    * @return {String} name 瀛樺偍杩囩▼鍚嶇О
    */
@@ -338,7 +392,7 @@
         if (item.field) {
           let type = ''
           if (item.type.match(/date/ig)) {
-            type = 'datetime is null'
+            type = 'datetime=null'
           } else if (item.type === 'number') {
             type = `decimal(18,${item.decimal})=0`
           } else {
@@ -436,8 +490,8 @@
       ROLLBACK TRAN
       
     END`
-    console.log(Ltext)
     Ltext = Ltext.replace(/\n\s{4}/ig, 'mchr13k')
+    console.log(Ltext)
     return Ltext
   }
 }
\ No newline at end of file

--
Gitblit v1.8.0