From c39ea1f23d21b070188abcf5f4dd5bdd7b47c1f9 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期二, 10 三月 2020 10:32:13 +0800
Subject: [PATCH] 2020-03-10

---
 src/tabviews/tableshare/verifycard/index.jsx             |  368 ++++++++++++++++
 src/tabviews/tableshare/verifycard/actionform/index.scss |    0 
 src/views/printTemplate/index.jsx                        |   55 +
 src/views/printTemplate/index.scss                       |   10 
 src/tabviews/tableshare/verifycard/index.scss            |   53 ++
 src/tabviews/tableshare/actionList/index.jsx             |  143 ++++++
 src/templates/tableshare/dragelement/card.jsx            |    4 
 src/api/index.js                                         |   66 ++
 src/tabviews/subtable/index.jsx                          |    3 
 src/templates/tableshare/searchform/index.jsx            |   29 +
 src/locales/zh-CN/comtable.js                            |    1 
 src/tabviews/commontable/index.jsx                       |  190 +++++--
 src/tabviews/commontable/mainTable/index.jsx             |   39 -
 src/templates/tableshare/verifycard/index.jsx            |    2 
 src/locales/en-US/comtable.js                            |    1 
 src/tabviews/tableshare/topSearch/index.scss             |    2 
 src/templates/tableshare/dragelement/index.jsx           |    2 
 src/tabviews/tableshare/topSearch/index.jsx              |   50 +-
 src/templates/comtableconfig/settingform/index.jsx       |    1 
 src/templates/subtableconfig/index.scss                  |    2 
 src/tabviews/commontable/index.scss                      |   47 +
 src/templates/comtableconfig/index.scss                  |    2 
 src/templates/tableshare/searchform/index.scss           |    3 
 src/views/printTemplate/dragelement/index.scss           |    2 
 src/tabviews/tableshare/verifycard/actionform/index.jsx  |  188 ++++++++
 src/templates/tableshare/formconfig.js                   |   10 
 src/views/login/index.jsx                                |   63 +-
 27 files changed, 1,132 insertions(+), 204 deletions(-)

diff --git a/src/api/index.js b/src/api/index.js
index 4c4bfb3..20e1874 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -142,8 +142,15 @@
     param.nonc = Utils.getuuid()
     
     let keys = Object.keys(param).sort()
-    keys = keys.filter(key => key !== 'rduri')
-    let values = keys.map(key => key + param[key]).join('')
+    let values = ''
+    keys.forEach(key => {
+      if (key === 'rduri' || key === 't') return
+      if (typeof(param[key]) === 'object') {
+        values += key + JSON.stringify(param[key])
+      } else {
+        values += key + param[key]
+      }
+    })
     param.sign  = md5(values)
     param.t = new Date().getTime()
 
@@ -175,8 +182,15 @@
     param.nonc = Utils.getuuid()
     
     let keys = Object.keys(param).sort()
-    keys = keys.filter(key => key !== 'rduri')
-    let values = keys.map(key => key + param[key]).join('')
+    let values = ''
+    keys.forEach(key => {
+      if (key === 'rduri' || key === 't') return
+      if (typeof(param[key]) === 'object') {
+        values += key + JSON.stringify(param[key])
+      } else {
+        values += key + param[key]
+      }
+    })
     param.sign  = md5(values)
     param.t = new Date().getTime()
 
@@ -199,8 +213,15 @@
     param.nonc = Utils.getuuid()
     
     let keys = Object.keys(param).sort()
-    keys = keys.filter(key => key !== 'rduri')
-    let values = keys.map(key => key + param[key]).join('')
+    let values = ''
+    keys.forEach(key => {
+      if (key === 'rduri' || key === 't') return
+      if (typeof(param[key]) === 'object') {
+        values += key + JSON.stringify(param[key])
+      } else {
+        values += key + param[key]
+      }
+    })
     param.sign  = md5(values)
     param.t = new Date().getTime()
 
@@ -245,8 +266,15 @@
       param.nonc = Utils.getuuid()
       
       let keys = Object.keys(param).sort()
-      keys = keys.filter(key => key !== 'rduri')
-      let values = keys.map(key => key + param[key]).join('')
+      let values = ''
+      keys.forEach(key => {
+        if (key === 'rduri' || key === 't') return
+        if (typeof(param[key]) === 'object') {
+          values += key + JSON.stringify(param[key])
+        } else {
+          values += key + param[key]
+        }
+      })
       param.sign  = md5(values)
       param.t = new Date().getTime()
 
@@ -281,8 +309,15 @@
     param.nonc = Utils.getuuid()
     
     let keys = Object.keys(param).sort()
-    keys = keys.filter(key => key !== 'rduri' && key !== 't')
-    let values = keys.map(key => key + param[key]).join('')
+    let values = ''
+    keys.forEach(key => {
+      if (key === 'rduri' || key === 't') return
+      if (typeof(param[key]) === 'object') {
+        values += key + JSON.stringify(param[key])
+      } else {
+        values += key + param[key]
+      }
+    })
     param.sign  = md5(values)
     param.t = new Date().getTime()
 
@@ -374,8 +409,15 @@
     param.nonc = Utils.getuuid()
     
     let keys = Object.keys(param).sort()
-    keys = keys.filter(key => key !== 'rduri')
-    let values = keys.map(key => key + param[key]).join('')
+    let values = ''
+    keys.forEach(key => {
+      if (key === 'rduri' || key === 't') return
+      if (typeof(param[key]) === 'object') {
+        values += key + JSON.stringify(param[key])
+      } else {
+        values += key + param[key]
+      }
+    })
     param.sign  = md5(values)
     param.t = new Date().getTime()
 
diff --git a/src/locales/en-US/comtable.js b/src/locales/en-US/comtable.js
index b54c62b..d673147 100644
--- a/src/locales/en-US/comtable.js
+++ b/src/locales/en-US/comtable.js
@@ -224,6 +224,7 @@
   'header.form.thawbutton': '瑙e喕鎸夐挳',
   'header.form.maxRows': '鏈�澶ц鏁�',
   'header.form.paste': '绮樿创',
+  'header.form.ratio': '姣斾緥',
   'header.modal.form.edit': '琛ㄥ崟-缂栬緫',
   'header.modal.search.edit': '鎼滅储鏉′欢-缂栬緫',
   'header.modal.action.edit': '鎸夐挳-缂栬緫',
diff --git a/src/locales/zh-CN/comtable.js b/src/locales/zh-CN/comtable.js
index 7069ce7..95185fa 100644
--- a/src/locales/zh-CN/comtable.js
+++ b/src/locales/zh-CN/comtable.js
@@ -224,6 +224,7 @@
   'header.form.thawbutton': '瑙e喕鎸夐挳',
   'header.form.maxRows': '鏈�澶ц鏁�',
   'header.form.paste': '绮樿创',
+  'header.form.ratio': '姣斾緥',
   'header.modal.form.edit': '琛ㄥ崟-缂栬緫',
   'header.modal.search.edit': '鎼滅储鏉′欢-缂栬緫',
   'header.modal.action.edit': '鎸夐挳-缂栬緫',
diff --git a/src/tabviews/commontable/index.jsx b/src/tabviews/commontable/index.jsx
index cc1217c..f214488 100644
--- a/src/tabviews/commontable/index.jsx
+++ b/src/tabviews/commontable/index.jsx
@@ -13,6 +13,7 @@
 import {refreshTabView, modifyTabview} from '@/store/action'
 
 import MainTable from './mainTable'
+import VerifyCard from '@/tabviews/tableshare/verifycard'
 import MainAction from '@/tabviews/tableshare/actionList'
 import MainSearch from '@/tabviews/tableshare/topSearch'
 import SubTable from '@/tabviews/subtable'
@@ -54,16 +55,16 @@
     orderBy: '',          // 鎺掑簭
     search: '',           // 鎼滅储鏉′欢鏁扮粍锛屼娇鐢ㄦ椂闇�鍒嗗満鏅鐞�
     BIDs: {},             // 涓婄骇琛╥d
-    setsingle: false,     // 涓昏〃鍗曢�夊閫夊垏鎹�
     pickup: false,        // 涓昏〃鏁版嵁闅愯棌鏄剧ず鍒囨崲
-    isLinkMain: false,    // 鏄惁瀛樺湪涓庝富琛ㄥ叧鑱旂殑瀛愯〃
     popAction: false,     // 寮规椤甸潰锛屾寜閽俊鎭�
     popData: false,       // 寮规椤甸潰锛屾墍閫夌殑琛ㄦ牸鏁版嵁
     visible: false,       // 寮规鏄剧ず闅愯棌鎺у埗
     treevisible: false,   // 鑿滃崟缁撴瀯鏍戝脊妗嗘樉绀洪殣钘忔帶鍒�
     tabBtn: null,         // 琛ㄥ崟鏍囩鎸夐挳
     tabParam: null,       // 琛ㄥ崟鏍囩鍙傛暟
-    refreshtabs: null     // 闇�瑕佸埛鏂扮殑鏍囩闆�
+    refreshtabs: null,    // 闇�瑕佸埛鏂扮殑鏍囩闆�
+    confirmLoading: false,// 鑷畾涔夎缃ā鎬佹鍔犺浇涓�
+    settingVisible: false // 鑷畾涔夎缃ā鎬佹
   }
 
   /**
@@ -79,12 +80,20 @@
     let result = await Api.getSystemCacheConfig(param)
     if (result.status) {
       let config = ''
+      let userConfig = ''
 
       try { // 閰嶇疆淇℃伅瑙f瀽
         config = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
       } catch (e) {
         console.warn('Parse Failure')
         config = ''
+      }
+      
+      try { // 閰嶇疆淇℃伅瑙f瀽
+        userConfig = JSON.parse(window.decodeURIComponent(window.atob(result.LongParamUser)))
+      } catch (e) {
+        console.warn('Parse Failure')
+        userConfig = ''
       }
 
       // 椤甸潰閰嶇疆瑙f瀽閿欒鏃舵彁绀�
@@ -106,18 +115,34 @@
         return
       }
 
-      let _arrField = []     // 瀛楁闆�
-      let _columns = []      // 鏄剧ず鍒�
-      let _logcolumns = []   // 鏃ュ織鏄剧ず鍒�
-      let _hideCol = []      // 闅愯棌鍙婂悎骞跺垪涓瓧娈电殑uuid闆�
-      let colMap = new Map() // 鐢ㄤ簬瀛楁杩囨护
-
       // 鏉冮檺杩囨护
       config.action = config.action.filter(item => permAction[item.uuid])
       // config.tabgroups.forEach(group => {
       //   if (!config[group]) return
       //   config[group] = config[group].filter(tab => permAction[tab.uuid])
       // })
+
+      if (userConfig) {
+        config.setting = {...config.setting, ...userConfig.setting}
+        let _actions = {}
+        userConfig.action.forEach(item => {
+          _actions[item.uuid] = item
+        })
+
+        config.action = config.action.map(item => {
+          if (_actions[item.uuid]) {
+            item = {...item, ..._actions[item.uuid]}
+          }
+
+          return item
+        })
+      }
+
+      let _arrField = []     // 瀛楁闆�
+      let _columns = []      // 鏄剧ず鍒�
+      let _logcolumns = []   // 鏃ュ織鏄剧ず鍒�
+      let _hideCol = []      // 闅愯棌鍙婂悎骞跺垪涓瓧娈电殑uuid闆�
+      let colMap = new Map() // 鐢ㄤ簬瀛楁杩囨护
 
       let _actions = []     // 宸ュ叿鏍忔寜閽�
       let _operations = []  // 鎿嶄綔鍒楁寜閽紙瀛樺湪鏃讹級
@@ -180,17 +205,6 @@
         }
       })
 
-      let _isLinkMain = false // 妫�鏌ユ槸鍚︽湁涓庝富琛ㄥ叧鑱旂殑瀛愯〃
-      config.tabgroups.forEach(groupId => {
-        if (!config[groupId] || config[groupId].length === 0) return
-
-        config[groupId].forEach(tab => {
-          if (tab.supMenu === 'mainTable') {
-            _isLinkMain = true
-          }
-        })
-      })
-
       this.setState({
         loadingview: false,
         config: config,
@@ -199,18 +213,17 @@
         actions: _actions,
         columns: _columns,
         logcolumns: _logcolumns,
-        isLinkMain: _isLinkMain,
         arr_field: _arrField.join(','),
         search: Utils.initMainSearch(config.search) // 鎼滅储鏉′欢鍒濆鍖栵紙鍚湁鏃堕棿鏍煎紡锛岄渶瑕佽浆鍖栵級
       }, () => {
         this.improveSearch()
-
         if (config.setting.onload !== 'false') { // 鍒濆鍖栧彲鍔犺浇
           this.setState({
             loading: true
           })
           this.loadmaindata()
         }
+        this.setShortcut()
       })
     } else {
       this.setState({
@@ -221,6 +234,36 @@
         top: 92,
         message: result.message,
         duration: 10
+      })
+    }
+  }
+
+  setShortcut = () => {
+    const { actions } = this.state
+    if (!actions) return
+
+    document.onkeydown = (event) => {
+      let e = event || window.event
+      let keyCode = e.keyCode || e.which || e.charCode
+      let preKey = ''
+
+      if (e.ctrlKey) {
+        preKey = 'ctrl'
+      } else if (e.shiftKey) {
+        preKey = 'shift'
+      } else if (e.altKey) {
+        preKey = 'alt'
+      }
+      
+      let istrigger = false
+      actions.forEach(item => {
+        if (!item.shortcut || istrigger) return
+
+        if (preKey === item.shortcut && keyCode === item.shortcutkey) {
+          e.preventDefault()
+          istrigger = true
+          this.refs.mainButton.actionTrigger(item)
+        }
       })
     }
   }
@@ -551,9 +594,7 @@
       orderBy: '',
       search: '',
       BIDs: {},
-      setsingle: false,
-      pickup: false,
-      isLinkMain: false
+      pickup: false
     }, () => {
       this.loadconfig()
     })
@@ -665,22 +706,6 @@
         [type]: id,
         [type + 'data']: data
       }
-    })
-  }
-
-  /**
-   * @description 琛ㄦ牸鍗曢�夊閫夊垏鎹�
-   */
-  checkChange = () => {
-    const { setsingle, BIDs } = this.state
-
-    let _BIDs = JSON.parse(JSON.stringify(BIDs))
-    _BIDs.mainTable = ''
-
-    this.setState({
-      setsingle: !setsingle,
-      pickup: false,
-      BIDs: _BIDs
     })
   }
   
@@ -831,19 +856,50 @@
     })
   }
 
+  controlCustomSetting = () => {
+    this.setState({
+      settingVisible: true,
+      confirmLoading: false
+    })
+  }
+
+  settingSubmit = () => {
+    this.verifyRef.handleConfirm().then(res => {
+      let _LongParam = ''
+
+      try {
+        _LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(res)))
+      } catch (e) {
+        notification.warning({
+          top: 92,
+          message: '缂栬瘧閿欒',
+          duration: 10
+        })
+        return
+      }
+
+      let param = {
+        func: 'sPC_TrdMenu_UserParam',
+        MenuID: this.props.MenuID,
+        LongParam: _LongParam
+      }
+
+      this.setState({
+        confirmLoading: true
+      })
+
+      Api.getSystemConfig(param).then(result => {
+        this.setState({
+          settingVisible: false,
+          confirmLoading: false
+        })
+      })
+    })
+  }
+
   UNSAFE_componentWillMount () {
     // 缁勪欢鍔犺浇鏃讹紝鑾峰彇鑿滃崟鏁版嵁
     this.loadconfig()
-  }
-
-  componentDidMount () {
-    // document.onkeydown = (event) => {
-    //   let e = event || window.event
-
-    //   if(e && e.keyCode === 27) {
-    //     console.log(this.props.MenuID)
-    //   }
-    // }
   }
 
   UNSAFE_componentWillReceiveProps(nextProps) {
@@ -871,11 +927,11 @@
   }
 
   render() {
-    const { view, setting, searchlist, actions, columns, loadingview, viewlost, setsingle, pickup, isLinkMain, config } = this.state
+    const { view, setting, searchlist, actions, columns, loadingview, viewlost, pickup, config } = this.state
 
     return (
       <div>
-        {view === 'commontable' ? <div className={'commontable ' + (isLinkMain ? 'pick-control' : '')} id={this.state.ContainerId}>
+        {view === 'commontable' ? <div className="commontable pick-control" id={this.state.ContainerId}>
           {loadingview && <Spin size="large" />}
           {searchlist && searchlist.length > 0 ?
             <MainSearch
@@ -904,18 +960,15 @@
           }
           {columns && setting.onload !== 'false' ?
             <div className="main-table-box">
-              {isLinkMain ?
-                <div className="pickchange">
-                  {setting.tableType === 'checkbox' ? <Switch title="鍗曢�夊垏鎹�" checkedChildren="鍗�" unCheckedChildren="澶�" defaultChecked={setsingle} onChange={this.checkChange} /> : null}
-                  {this.state.BIDs.mainTable && (setting.tableType === 'radio' || setsingle) ? <Switch title="鏀惰捣" checkedChildren="寮�" unCheckedChildren="鍏�" defaultChecked={pickup} onChange={this.pickupChange} /> : null}
-                </div> : null
+              <Icon className="custom-control" type="setting" onClick={this.controlCustomSetting} />
+              {this.state.data && this.state.data.length > 0 ?
+                <Switch title="鏀惰捣" className="main-pickup" checkedChildren="寮�" unCheckedChildren="鍏�" defaultChecked={pickup} onChange={this.pickupChange} /> : null
               }
               <MainTable
                 ref="mainTable"
                 pickup={pickup}
                 setting={setting}
                 columns={columns}
-                setsingle={setsingle}
                 dict={this.state.dict}
                 data={this.state.data}
                 total={this.state.total}
@@ -1010,6 +1063,25 @@
               {this.getTreeNode(config.funcs)}
             </Tree> : null}
           </Modal>
+          {/* 鎸夐挳浣跨敤绯荤粺瀛樺偍杩囩▼鏃讹紝楠岃瘉淇℃伅妯℃�佹 */}
+          <Modal
+            wrapClassName="common-table-custom-modal"
+            title={'鑷畾涔夎缃�'}
+            maskClosable={false}
+            width={850}
+            visible={this.state.settingVisible}
+            onOk={this.settingSubmit}
+            onCancel={() => { this.setState({ settingVisible: false }) }}
+            confirmLoading={this.state.confirmLoading}
+            destroyOnClose
+          >
+            {this.state.config ?
+              <VerifyCard
+                config={this.state.config}
+                wrappedComponentRef={(inst) => this.verifyRef = inst}
+              /> : null
+            }
+          </Modal>
           {viewlost ? <NotFount msg={this.state.lostmsg} /> : null}
         </div> : null}
         {view === 'formtab' ? <FormTab MenuID={this.state.tabBtn.uuid} param={this.state.tabParam} refresh={this.refreshbyformtab}/> : null}
diff --git a/src/tabviews/commontable/index.scss b/src/tabviews/commontable/index.scss
index 847136c..20b0579 100644
--- a/src/tabviews/commontable/index.scss
+++ b/src/tabviews/commontable/index.scss
@@ -50,16 +50,20 @@
   }
   .main-table-box {
     position: relative;
-    .pickchange {
+    .main-pickup {
       position: absolute;
-      right: 0px;
+      right: 20px;
       top: -25px;
-      .ant-switch {
-        z-index: 1;
-        float: right;
-        margin-right: 20px;
-        margin-bottom: 5px;
-      }
+      z-index: 1;
+    }
+    .custom-control {
+      position: absolute;
+      z-index: 1;
+      right: 20px;
+      top: -55px;
+      font-size: 16px;
+      padding: 3px;
+      cursor: pointer;
     }
   }
   > .ant-tabs {
@@ -106,4 +110,31 @@
       cursor: default;
     }
   }
+}
+.common-table-custom-modal {
+  .ant-modal {
+    top: 50px;
+    padding-bottom: 5px;
+    .ant-modal-body {
+      max-height: calc(100vh - 190px);
+      overflow-y: auto;
+      .ant-empty {
+        margin: 15vh 8px;
+      }
+    }
+    .ant-modal-body::-webkit-scrollbar {
+      width: 7px;
+    }
+    .ant-modal-body::-webkit-scrollbar-thumb {
+      border-radius: 5px;
+      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
+      background: rgba(0, 0, 0, 0.13);
+    }
+    .ant-modal-body::-webkit-scrollbar-track {
+      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
+      border-radius: 3px;
+      border: 1px solid rgba(0, 0, 0, 0.07);
+      background: rgba(0, 0, 0, 0);
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/tabviews/commontable/mainTable/index.jsx b/src/tabviews/commontable/mainTable/index.jsx
index 3fd499f..8d9bfca 100644
--- a/src/tabviews/commontable/mainTable/index.jsx
+++ b/src/tabviews/commontable/mainTable/index.jsx
@@ -1,6 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { is, fromJS } from 'immutable'
+// import { is, fromJS } from 'immutable'
 import { Table, message, Affix, Button, Typography } from 'antd'
 import './index.scss'
 
@@ -12,7 +12,6 @@
     MenuID: PropTypes.string,      // 鑿滃崟Id
     setting: PropTypes.object,     // 琛ㄦ牸鍏ㄥ眬璁剧疆锛歵ableType锛堣〃鏍兼槸鍚﹀彲閫夈�佸崟閫夈�佸閫夛級銆乧olumnfixed锛堝垪鍥哄畾锛夈�乤ctionfixed锛堟寜閽浐瀹氾級
     pickup: PropTypes.any,         // 鏁版嵁鏀惰捣
-    setsingle: PropTypes.any,      // 璁剧疆鍗曢�夊閫�
     columns: PropTypes.array,      // 琛ㄦ牸鍒�
     data: PropTypes.any,           // 琛ㄦ牸鏁版嵁
     total: PropTypes.number,       // 鎬绘暟
@@ -26,13 +25,11 @@
     selectedRowKeys: [],  // 琛ㄦ牸涓�変腑琛�
     pageIndex: 1,         // 鍒濆椤甸潰绱㈠紩
     pageSize: 10,         // 姣忛〉鏁版嵁鏉℃暟
-    columns: null,        // 鏄剧ず鍒�
-    selectId: '',
-    isSingleSelect: false
+    columns: null         // 鏄剧ず鍒�
   }
 
   UNSAFE_componentWillMount () {
-    const { columns, setting } = this.props
+    const { columns } = this.props
     let _columns = []
     
     columns.forEach(item => {
@@ -50,19 +47,8 @@
     })
 
     this.setState({
-      columns: _columns,
-      isSingleSelect: setting.tableType === 'radio'
+      columns: _columns
     })
-  }
-
-  UNSAFE_componentWillReceiveProps(nextProps) {
-    if (!is(fromJS(this.props.setsingle), fromJS(nextProps.setsingle))) {
-      this.setState({
-        isSingleSelect: nextProps.setsingle,
-        selectedRowKeys: [],
-        selectId: ''
-      })
-    }
   }
 
   getContent = (item, record) => {
@@ -247,8 +233,6 @@
   }
 
   onSelectChange = selectedRowKeys => {
-    if (this.props.pickup) return
-
     let index = ''
     if (selectedRowKeys.length > 0) {
       index = selectedRowKeys[selectedRowKeys.length - 1]
@@ -266,7 +250,7 @@
     let newkeys = JSON.parse(JSON.stringify(this.state.selectedRowKeys))
     let _re = newkeys.includes(index)
 
-    if (this.props.setting.tableType === 'radio' || this.state.isSingleSelect) {
+    if (this.props.setting.tableType === 'radio') {
       this.changedata(index)
       this.setState({ selectedRowKeys: [index] })
     } else {
@@ -301,30 +285,25 @@
       _data = data[index] || ''
     }
 
-    this.setState({
-      selectId: _id
-    })
-
     this.props.handleTableId('mainTable', _id, _data)
   }
 
   resetTable = () => {
     this.setState({
       pageIndex: 1,
-      selectId: '',
       selectedRowKeys: []
     })
   }
 
   render() {
     const { setting, pickup } = this.props
-    let { selectedRowKeys, isSingleSelect, selectId } = this.state
+    let { selectedRowKeys } = this.state
 
     let rowSelection = null
     if (setting.tableType) {
       rowSelection = {
         selectedRowKeys,
-        type: (setting.tableType === 'radio' || isSingleSelect) ? 'radio' : 'checkbox',
+        type: (setting.tableType === 'radio') ? 'radio' : 'checkbox',
         onChange: this.onSelectChange
       }
     }
@@ -345,8 +324,8 @@
 
     let _data = this.props.data ? this.props.data : []
 
-    if (selectId && pickup && isSingleSelect) {
-      _data = _data.filter(item => item[setting.primaryKey] === selectId)
+    if (pickup) {
+      _data = _data.filter((item, index) => selectedRowKeys.includes(index))
     }
 
     return (
diff --git a/src/tabviews/subtable/index.jsx b/src/tabviews/subtable/index.jsx
index a941e3b..310af7f 100644
--- a/src/tabviews/subtable/index.jsx
+++ b/src/tabviews/subtable/index.jsx
@@ -682,9 +682,6 @@
             gettableselected={this.gettableselected}
           />
         }
-        {/* {this.state.data && this.state.data.length > 0 ?
-          <Switch title="鏀惰捣" className="subtable-pickup" checkedChildren="寮�" unCheckedChildren="鍏�" defaultChecked={pickup} onChange={this.pickupChange} /> : null
-        } */}
         {columns ?
           <div className="subtable-box">
             {this.state.data && this.state.data.length > 0 ?
diff --git a/src/tabviews/tableshare/actionList/index.jsx b/src/tabviews/tableshare/actionList/index.jsx
index dbb9143..31c03eb 100644
--- a/src/tabviews/tableshare/actionList/index.jsx
+++ b/src/tabviews/tableshare/actionList/index.jsx
@@ -11,6 +11,7 @@
 import './index.scss'
 
 const { confirm } = Modal
+let socket = null
 
 class MainAction extends Component {
   static propTpyes = {
@@ -185,7 +186,25 @@
       if (item.funcType === 'changeuser') {
         this.changeUser(item, data)
       } else if (item.funcType === 'print') {
-        this.triggerPrint(item, data)
+        if (item.execMode === 'pop') {
+          this.setState({
+            execAction: item,
+            tabledata: data,
+            btnloading: true
+          }, () => {
+            this.improveAction(item)
+          })
+        } else if (item.execMode === 'prompt') {
+          confirm({
+            title: this.props.dict['main.action.confirm.tip'],
+            onOk() {
+              _this.triggerPrint(item, data)
+            },
+            onCancel() {}
+          })
+        } else {
+          this.triggerPrint(item, data)
+        }
       }
     } else {
       notification.warning({
@@ -199,8 +218,10 @@
   /**
    * @description 瑙﹀彂鎵撳嵃
    */
-  triggerPrint = (item, data) => {
+  triggerPrint = (item, data, formdata) => {
     console.log(item)
+    console.log(data)
+    console.log(formdata)
     if (!item.verify || !item.verify.Template || !item.verify.linkUrl) {
       notification.warning({
         top: 92,
@@ -224,7 +245,33 @@
 
       Api.getLocalConfig(param).then(res => {
         if (res.status) {
-          resolve(res)
+          
+          if (!res.ConfigParam) {
+            notification.warning({
+              top: 92,
+              message: '鏈幏鍙栧埌鎵撳嵃妯℃澘淇℃伅锛�',
+              duration: 15
+            })
+            resolve(false)
+          } else {
+            let configParam = ''
+
+            try {
+              configParam = JSON.parse(window.decodeURIComponent(window.atob(res.ConfigParam)))
+            } catch (e) {
+              configParam = ''
+            }
+
+            if (!configParam) {
+              notification.warning({
+                top: 92,
+                message: '鎵撳嵃妯℃澘瑙f瀽閿欒锛�',
+                duration: 15
+              })
+            } else {
+              resolve(configParam)
+            }
+          }
         } else {
           this.execError(res, item)
           resolve(false)
@@ -233,7 +280,87 @@
     }).then(res => {
       console.log(res)
       if (!res) return
-      
+
+      if (!socket || socket.readyState !== 1 || socket.url !== 'ws://' + item.verify.linkUrl) {
+        socket = new WebSocket('ws://' + item.verify.linkUrl)
+      }
+      // 鎵撳紑Socket
+      socket.onopen = () =>{
+        if (!item.printer) {
+          let request  = {
+            requestID: '',
+            version: '',
+            cmd: 'getPrinters'
+          }
+          socket.send(JSON.stringify(request))
+        } else {
+          let printdata = {
+            cmd: 'print',
+            requestID: '',
+            version: '',
+            task: {
+              taskID: '1',
+              preview: false,
+              printer: item.printer,
+              documents: [
+                {
+                  documentID: '9890000106027',
+                  contents: [
+                    {
+                      data: {
+                        barcode: '12345'
+                      },
+                      templateURL: '{"Version":"","Title":"1234","Author":"U000000001","Description":"","PrintTempNO":"","PageSetting":{"Width":210,"Height":297,"Left":"0","Right":"0","Top":"0","Bottom":"0","Landscape":false},"PageHeader":[],"ReportHeader":{"Control":[{"Name":"","Type":"barcode","Value":"","Field":"barcode","Left":71,"Top":32,"Width":52,"Height":26,"Rotate":0,"BorderSize":0.1,"BorderColor":"black","Align":"center","VerticalAlign":"middle","BackColor":"white","ForeColor":"black","BarcodeType":"code128","BarcodeWidth":31,"BarcodeHeight":10,"BarcodeLabel":true,"LabelSize":12}]},"ReportFooter":[],"PageFooter":[]}'
+                    }
+                  ]
+                }
+              ]
+            }
+          }
+
+          socket.send(JSON.stringify(printdata))
+        }
+      }
+      // 鐩戝惉娑堟伅
+      socket.onmessage = (event) => {
+        let data = JSON.parse(event.data)
+
+        if (data.defaultPrinter) {
+          let printdata = {
+            cmd: 'print',
+            requestID: '',
+            version: '',
+            task: {
+              taskID: '1',
+              preview: false,
+              printer: data.defaultPrinter,
+              documents: [
+                {
+                  documentID: '9890000106027',
+                  contents: [
+                    {
+                      data: {
+                        barcode: '12345'
+                      },
+                      templateURL: '{"Version":"","Title":"1234","Author":"U000000001","Description":"","PrintTempNO":"","PageSetting":{"Width":210,"Height":297,"Left":"0","Right":"0","Top":"0","Bottom":"0","Landscape":false},"PageHeader":[],"ReportHeader":{"Control":[{"Name":"","Type":"barcode","Value":"","Field":"barcode","Left":71,"Top":32,"Width":52,"Height":26,"Rotate":0,"BorderSize":0.1,"BorderColor":"black","Align":"center","VerticalAlign":"middle","BackColor":"white","ForeColor":"black","BarcodeType":"code128","BarcodeWidth":31,"BarcodeHeight":10,"BarcodeLabel":true,"LabelSize":12}]},"ReportFooter":[],"PageFooter":[]}'
+                    }
+                  ]
+                }
+              ]
+            }
+          }
+
+          socket.send(JSON.stringify(printdata))
+        }
+      }
+
+      socket.onerror = () => {
+        notification.warning({
+          top: 92,
+          message: '鏃犳硶杩炴帴鍒�:' + item.verify.linkUrl,
+          duration: 10
+        })
+      }
     })
 
 
@@ -309,6 +436,14 @@
   execSubmit = (btn, data, _resolve, formdata) => {
     const { setting, logcolumns } = this.props
 
+    if (btn.OpenType === 'funcbutton' && btn.funcType === 'print' && btn.execMode === 'pop') {
+      this.setState({
+        confirmLoading: false,
+        visible: false
+      })
+      this.triggerPrint(btn, data, formdata)
+      return
+    }
     if (btn.intertype === 'inner') {
       // 浣跨敤鍐呴儴鎺ュ彛鏃讹紝鍐呴儴鍑芥暟鍜屾暟鎹簮涓嶅彲鍚屾椂涓虹┖, 浣跨敤绯荤粺鍑芥暟鏃讹紝绫诲瀷涓嶅彲涓虹┖
       if (!btn.innerFunc && (!btn.sql || (btn.sql && !btn.sqlType))) {
diff --git a/src/tabviews/tableshare/topSearch/index.jsx b/src/tabviews/tableshare/topSearch/index.jsx
index 4222f5a..3107b87 100644
--- a/src/tabviews/tableshare/topSearch/index.jsx
+++ b/src/tabviews/tableshare/topSearch/index.jsx
@@ -172,7 +172,7 @@
 
       if (item.type === 'text') { // 鏂囨湰鎼滅储
         fields.push(
-          <Col span={6} key={index}>
+          <Col span={item.ratio || 6} key={index}>
             <Form.Item label={item.label}>
               {getFieldDecorator(item.field, {initialValue: item.initval })(<Input placeholder="" autoComplete="off" />)}
             </Form.Item>
@@ -180,7 +180,7 @@
         )
       } else if (item.type === 'select') { // 涓嬫媺鎼滅储
         fields.push(
-          <Col span={6} key={index}>
+          <Col span={item.ratio || 6} key={index}>
             <Form.Item label={item.label}>
               {getFieldDecorator(item.field, {initialValue: item.initval })(
                 <Select
@@ -200,7 +200,7 @@
       } else if (item.type === 'multiselect') { // 涓嬫媺澶氶��
         let _initval = item.initval ? item.initval.split(',').filter(Boolean) : []
         fields.push(
-          <Col span={6} key={index}>
+          <Col span={item.ratio || 6} key={index}>
             <Form.Item label={item.label}>
               {getFieldDecorator(item.field, {initialValue: _initval })(
                 <Select
@@ -220,7 +220,7 @@
         )
       } else if (item.type === 'date') { // 鏃堕棿鎼滅储
         fields.push(
-          <Col span={6} key={index}>
+          <Col span={item.ratio || 6} key={index}>
             <Form.Item label={item.label}>
               {getFieldDecorator(item.field, {initialValue: item.initval ? moment().subtract(item.initval, 'days') : null })(
                 <DatePicker onChange={this.searchChange} getCalendarContainer={() => document.getElementById(this.state.formId)} />
@@ -230,7 +230,7 @@
         )
       } else if (item.type === 'datemonth') {
         fields.push(
-          <Col span={6} key={index}>
+          <Col span={item.ratio || 6} key={index}>
             <Form.Item label={item.label}>
               {getFieldDecorator(item.field, {initialValue: item.initval ? moment().subtract(item.initval, 'month') : null })(
                 <MonthPicker onChange={this.searchChange} getCalendarContainer={() => document.getElementById(this.state.formId)} />
@@ -240,7 +240,7 @@
         )
       } else if (item.type === 'dateweek') {
         fields.push(
-          <Col span={6} key={index}>
+          <Col span={item.ratio || 6} key={index}>
             <Form.Item label={item.label}>
               {getFieldDecorator(item.field, {initialValue: item.initval ? moment().subtract(item.initval * 7, 'days') : null })(
                 <WeekPicker onChange={this.searchChange} getCalendarContainer={() => document.getElementById(this.state.formId)} />
@@ -261,7 +261,7 @@
         }
 
         fields.push(
-          <Col className="daterange" span={6} key={index}>
+          <Col className="daterange" span={item.ratio || 6} key={index}>
             <Form.Item label={item.label}>
               {getFieldDecorator(item.field,
                 {
@@ -280,29 +280,18 @@
       }
     })
 
-    if (this.props.searchlist.length >= 4) { // 娣诲姞鎼滅储銆侀噸缃寜閽�
-      fields.push(
-        <Col span={this.props.searchlist.length % 4 ? 6 : 24} style={{paddingLeft: '112px', whiteSpace: 'nowrap'}} key="actions">
+    fields.push(
+      <Col span={6} style={{ whiteSpace: 'nowrap' }} key="actions">
+        <Form.Item label={' '} colon={false}>
           <Button type="primary" htmlType="submit">
             {this.props.dict['main.search']}
           </Button>
           <Button style={{ marginLeft: 8 }} onClick={this.handleReset}>
             {this.props.dict['main.reset']}
           </Button>
-        </Col>
-      )
-    } else {
-      fields.push(
-        <Col span={6} style={{ paddingTop: '4px', whiteSpace: 'nowrap' }} key="actions">
-          <Button type="primary" htmlType="submit">
-            {this.props.dict['main.search']}
-          </Button>
-          <Button style={{ marginLeft: 8 }} onClick={this.handleReset}>
-            {this.props.dict['main.reset']}
-          </Button>
-        </Col>
-      )
-    }
+        </Form.Item>
+      </Col>
+    )
     
     return fields
   }
@@ -402,8 +391,19 @@
   }
 
   render() {
+    const formItemLayout = {
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 8 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      }
+    }
+
     return (
-      <Form className="ant-advanced-search-form top-search" id={this.state.formId} onSubmit={this.handleSearch}>
+      <Form {...formItemLayout} className="ant-advanced-search-form top-search" id={this.state.formId} onSubmit={this.handleSearch}>
         <Row gutter={24}>{this.getFields()}</Row>
       </Form>
     )
diff --git a/src/tabviews/tableshare/topSearch/index.scss b/src/tabviews/tableshare/topSearch/index.scss
index 8854945..7a76b0e 100644
--- a/src/tabviews/tableshare/topSearch/index.scss
+++ b/src/tabviews/tableshare/topSearch/index.scss
@@ -10,7 +10,7 @@
     width: calc(100% - 100px);
   }
   .ant-form-item-label {
-    width: 100px;
+    // width: 100px;
     text-overflow: ellipsis;
   }
   .daterange .ant-calendar-picker-input {
diff --git a/src/tabviews/tableshare/verifycard/actionform/index.jsx b/src/tabviews/tableshare/verifycard/actionform/index.jsx
new file mode 100644
index 0000000..b1297b6
--- /dev/null
+++ b/src/tabviews/tableshare/verifycard/actionform/index.jsx
@@ -0,0 +1,188 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { Form, Row, Col, Select, Button, Input } from 'antd'
+import './index.scss'
+
+
+class UniqueForm extends Component {
+  static propTpyes = {
+    dict: PropTypes.object,       // 瀛楀吀椤�
+    actionChange: PropTypes.func  // 淇敼鍑芥暟
+  }
+
+  state = {
+    editItem: null, // 缂栬緫鍏冪礌
+    shortcut: ''
+  }
+
+  edit = (record) => {
+    this.setState({
+      editItem: record,
+      shortcut: record.shortcut || ''
+    }, () => {
+      let item = {
+        label: record.label,
+        shortcut: record.shortcut
+      }
+
+      if (record.shortcut) {
+        item.shortcutkey = record.shortcutkey
+      }
+      if (record.OpenType === 'funcbutton' && record.funcType === 'print') {
+        item.printer = record.printer || ''
+      }
+
+      this.props.form.setFieldsValue(item)
+    })
+  }
+
+
+  handleConfirm = () => {
+    // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
+    this.props.form.validateFieldsAndScroll((err, values) => {
+      if (!err) {
+        values.uuid = this.state.editItem ? this.state.editItem.uuid : ''
+
+        this.props.actionChange(values)
+        this.setState({
+          editItem: null,
+          shortcut: ''
+        }, () => {
+          this.props.form.setFieldsValue({
+            shortcut: '',
+            label: ''
+          })
+        })
+      }
+    })
+  }
+
+  shortcutChange = (value) => {
+    this.setState({
+      shortcut: value
+    })
+  }
+
+  render() {
+    const { getFieldDecorator } = this.props.form
+    const { editItem } = this.state
+    const formItemLayout = {
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 8 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      }
+    }
+
+    let hasprint = editItem && editItem.OpenType === 'funcbutton' && editItem.funcType === 'print'
+
+    return (
+      <Form {...formItemLayout} className="verify-form" id="verifycard1">
+        <Row gutter={24}>
+          <Col span={7}>
+            <Form.Item label={'鍚嶇О'}>
+              {getFieldDecorator('label', {
+                initialValue: '',
+              })(<Input placeholder="" autoComplete="off" disabled />)}
+            </Form.Item>
+          </Col>
+          {hasprint ? 
+            <Col span={7}>
+              <Form.Item label={'鎵撳嵃鏈�'}>
+                {getFieldDecorator('printer', {
+                  initialValue: '',
+                  rules: [
+                    {
+                      required: true,
+                      message: '璇烽�夋嫨鎵撳嵃鏈�!'
+                    }
+                  ]
+                })(
+                  <Select>
+                    {editItem.printers && editItem.printers.map(option =>
+                      <Select.Option id={option.value} title={option.text} key={option.value} value={option.value}>{option.text}</Select.Option>
+                    )}
+                  </Select>
+                )}
+              </Form.Item>
+            </Col> : null
+          }
+          <Col span={7}>
+            <Form.Item label={'蹇嵎閿�'}>
+              {getFieldDecorator('shortcut', {
+                initialValue: ''
+              })(
+                <Select onChange={(value) => {this.shortcutChange(value)}}>
+                  <Select.Option value=""> 绌� </Select.Option>
+                  <Select.Option value="shift"> shift </Select.Option>
+                  <Select.Option value="ctrl"> ctrl </Select.Option>
+                  <Select.Option value="alt"> alt </Select.Option>
+                </Select>
+              )}
+            </Form.Item>
+          </Col>
+          {hasprint ? <Col span={3} className="add">
+            <Button onClick={this.handleConfirm} type="primary" className="add-row">
+              纭畾
+            </Button>
+          </Col> : null}
+          {this.state.shortcut ? 
+            <Col span={7}>
+              <Form.Item label={'缁勫悎閿�'}>
+                {getFieldDecorator('shortcutkey', {
+                  initialValue: '',
+                  rules: [
+                    {
+                      required: true,
+                      message: '璇烽�夋嫨缁勫悎閿�!'
+                    }
+                  ]
+                })(
+                  <Select>
+                    <Select.Option value=""> 绌� </Select.Option>
+                    {this.state.shortcut !== 'alt' ? <Select.Option value={65}> A </Select.Option> : null}
+                    <Select.Option value={66}> B </Select.Option>
+                    {this.state.shortcut !== 'ctrl' ? <Select.Option value={67}> C </Select.Option> : null}
+                    <Select.Option value={68}> D </Select.Option>
+                    <Select.Option value={69}> E </Select.Option>
+                    <Select.Option value={70}> F </Select.Option>
+                    <Select.Option value={71}> G </Select.Option>
+                    <Select.Option value={72}> H </Select.Option>
+                    <Select.Option value={73}> I </Select.Option>
+                    <Select.Option value={74}> J </Select.Option>
+                    <Select.Option value={75}> K </Select.Option>
+                    <Select.Option value={76}> L </Select.Option>
+                    <Select.Option value={77}> M </Select.Option>
+                    <Select.Option value={78}> N </Select.Option>
+                    <Select.Option value={79}> O </Select.Option>
+                    <Select.Option value={80}> P </Select.Option>
+                    <Select.Option value={81}> Q </Select.Option>
+                    <Select.Option value={82}> R </Select.Option>
+                    <Select.Option value={83}> S </Select.Option>
+                    <Select.Option value={84}> T </Select.Option>
+                    <Select.Option value={85}> U </Select.Option>
+                    {this.state.shortcut !== 'ctrl' ? <Select.Option value={86}> V </Select.Option> : null}
+                    <Select.Option value={87}> W </Select.Option>
+                    <Select.Option value={88}> X </Select.Option>
+                    <Select.Option value={89}> Y </Select.Option>
+                    <Select.Option value={90}> Z </Select.Option>
+                  </Select>
+                )}
+              </Form.Item>
+            </Col> : null
+          }
+          {!hasprint ? <Col span={3} className="add">
+            <Button onClick={this.handleConfirm} type="primary" className="add-row">
+              纭畾
+            </Button>
+          </Col> : null}
+        </Row>
+      </Form>
+    )
+  }
+}
+
+export default Form.create()(UniqueForm)
\ No newline at end of file
diff --git a/src/tabviews/tableshare/verifycard/actionform/index.scss b/src/tabviews/tableshare/verifycard/actionform/index.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/tabviews/tableshare/verifycard/actionform/index.scss
diff --git a/src/tabviews/tableshare/verifycard/index.jsx b/src/tabviews/tableshare/verifycard/index.jsx
new file mode 100644
index 0000000..5e06ffc
--- /dev/null
+++ b/src/tabviews/tableshare/verifycard/index.jsx
@@ -0,0 +1,368 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { Form, Tabs, Row, Col, Radio, Table, Icon, Select, notification } from 'antd'
+
+import Utils from '@/utils/utils.js'
+
+import ActionForm from './actionform'
+import './index.scss'
+
+const { TabPane } = Tabs
+const keycode = {
+  65: 'A',
+  66: 'B',
+  67: 'C',
+  68: 'D',
+  69: 'E',
+  70: 'F',
+  71: 'G',
+  72: 'H',
+  73: 'I',
+  74: 'J',
+  75: 'K',
+  76: 'L',
+  77: 'M',
+  78: 'N',
+  79: 'O',
+  80: 'P',
+  81: 'Q',
+  82: 'R',
+  83: 'S',
+  84: 'T',
+  85: 'U',
+  86: 'V',
+  87: 'W',
+  88: 'X',
+  89: 'Y',
+  90: 'Z'
+}
+
+class VerifyCard extends Component {
+  static propTpyes = {
+    config: PropTypes.object     // 椤甸潰閰嶇疆
+  }
+
+  state = {
+    colColumns: [
+      {
+        title: '瀛楁鍚�',
+        dataIndex: 'field',
+        width: '35%'
+      },
+      {
+        title: '鎿嶄綔',
+        align: 'center',
+        width: '25%',
+        dataIndex: 'operation',
+        render: (text, record) =>
+          (<div>
+            <span className="operation-btn" title="缂栬緫" onClick={() => this.handleEdit(record, 'column')} style={{color: '#1890ff'}}><Icon type="edit" /></span>
+            <span className="operation-btn" title="涓婄Щ" onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span>
+            <span className="operation-btn" title="涓嬬Щ" onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span>
+            <span className="operation-btn" title="鐘舵�佸垏鎹�" onClick={() => this.handleStatus(record)} style={{color: '#8E44AD'}}><Icon type="swap" /></span>
+          </div>)
+      }
+    ],
+    actionColumns: [
+      {
+        title: '鍚嶇О',
+        dataIndex: 'label',
+        width: '20%'
+      },
+      {
+        title: '蹇嵎閿�',
+        dataIndex: 'shortcut',
+        width: '20%'
+      },
+      {
+        title: '缁勫悎閿�',
+        dataIndex: 'shortcutkey',
+        width: '20%',
+        render: (text, record) => keycode[text] || ''
+      },
+      {
+        title: '鎵撳嵃鏈�',
+        dataIndex: 'printer',
+        width: '20%'
+      },
+      {
+        title: '鎿嶄綔',
+        align: 'center',
+        width: '20%',
+        dataIndex: 'operation',
+        render: (text, record) =>
+          (<div>
+            <span className="operation-btn" title="缂栬緫" onClick={() => this.handleEdit(record, 'action')} style={{color: '#1890ff'}}><Icon type="edit" /></span>
+          </div>)
+      }
+    ]
+  }
+
+  UNSAFE_componentWillMount() {
+    const { config } = this.props
+    
+    this.setState({
+      config: JSON.parse(JSON.stringify(config))
+    })
+  }
+
+  componentDidMount() {
+    let printbtns = this.state.config.action.filter(item => item.OpenType === 'funcbutton' && item.funcType === 'print')
+
+    printbtns.forEach(item => {
+      if (!item.verify || !item.verify.linkUrl) {
+        notification.warning({
+          top: 92,
+          message: '鎵撳嵃鎸夐挳銆�' + item.label + '銆嬭缃敊璇�!',
+          duration: 10
+        })
+      } else {
+        let socket = null
+        socket = new WebSocket('ws://' + item.verify.linkUrl)
+        // 鎵撳紑Socket
+        socket.onopen = () =>{
+          let request  = {
+            requestID: '',
+            version: '',
+            cmd: 'getPrinters'
+          }
+          socket.send(JSON.stringify(request))
+        }
+        // 鐩戝惉娑堟伅
+        socket.onmessage = (event) => {
+          let data = JSON.parse(event.data)
+          if (data.defaultPrinter) {
+            let printers = Array.from(new Set(data.printers))
+            
+            let _config = JSON.parse(JSON.stringify(this.state.config))
+
+            _config.action = _config.action.map(cell => {
+              if (item.uuid === cell.uuid) {
+                cell.printer = cell.printer || data.defaultPrinter
+                cell.printers = printers.map(print => {
+                  return {
+                    value: print,
+                    text: print
+                  }
+                })
+              }
+              return cell
+            })
+
+            this.setState({
+              config: _config
+            })
+          }
+        }
+
+        socket.onerror = () => {
+          notification.warning({
+            top: 92,
+            message: '鏃犳硶杩炴帴鍒�:' + item.verify.linkUrl,
+            duration: 10
+          })
+        }
+      }
+    })
+  }
+
+  columnChange = (values) => {
+    let verify = JSON.parse(JSON.stringify(this.state.verify))
+
+    if (values.uuid) {
+      verify.uniques = verify.uniques.map(item => {
+        if (item.uuid === values.uuid) {
+          return values
+        } else {
+          return item
+        }
+      })
+    } else {
+      values.uuid = Utils.getuuid()
+      verify.uniques.push(values)
+    }
+
+    this.setState({
+      verify: verify
+    })
+  }
+
+  actionChange = (values) => {
+    let config = JSON.parse(JSON.stringify(this.state.config))
+
+    config.action = config.action.map(item => {
+      if (values.uuid === item.uuid) {
+        item = {...item, ...values}
+      }
+
+      return item
+    })
+
+    this.setState({
+      config: config
+    })
+  }
+
+  handleEdit = (record, type) => {
+    if (type === 'action') {
+      this.actionForm.edit(record)
+    } else if (type === 'column') {
+      this.uniqueForm.edit(record)
+    }
+
+    let node = document.getElementById('verify-card-box-tab').parentNode
+
+    if (node && node.scrollTop) {
+      node.scrollTop = 0
+    }
+  }
+
+  handleStatus = (record) => {
+    let verify = JSON.parse(JSON.stringify(this.state.verify))
+    record.status = record.status === 'false' ? 'true' : 'false'
+
+    verify.scripts = verify.scripts.map(item => {
+      if (item.uuid === record.uuid) {
+        return record
+      } else {
+        return item
+      }
+    })
+
+    this.setState({
+      verify: verify
+    })
+  }
+
+  handleUpDown = (record, type, direction) => {
+    let verify = JSON.parse(JSON.stringify(this.state.verify))
+    let index = 0
+
+    verify.customverifys = verify.customverifys.filter((item, i) => {
+      if (item.uuid === record.uuid) {
+        index = i
+      }
+
+      return item.uuid !== record.uuid
+    })
+    if ((index === 0 && direction === 'up') || (index === verify.customverifys.length && direction === 'down')) {
+      return
+    }
+
+    if (direction === 'up') {
+      verify.customverifys.splice(index - 1, 0, record)
+    } else {
+      verify.customverifys.splice(index + 1, 0, record)
+    }
+
+    this.setState({
+      verify: verify
+    })
+  }
+
+  handleConfirm = () => {
+    const { config } = this.state
+    // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
+    return new Promise((resolve, reject) => {
+      this.props.form.validateFieldsAndScroll((err, values) => {
+        if (!err) {
+          let _config = {}
+          _config.setting = values
+          _config.action = config.action.map(item => {
+            return {
+              uuid: item.uuid,
+              shortcut: item.shortcut || '',
+              shortcutkey: item.shortcutkey || '',
+              printer: item.printer || ''
+            }
+          })
+          
+          resolve(_config)
+        }
+      })
+    })
+  }
+
+
+  render() {
+    const { getFieldDecorator } = this.props.form
+    const { actionColumns, config } = this.state
+    const formItemLayout = {
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 8 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      }
+    }
+
+    return (
+      <div id="verify-card-box-tab">
+        <Tabs defaultActiveKey="1" className="verify-card-box">
+          <TabPane tab="鍩虹璁剧疆" key="1">
+            <Form {...formItemLayout}>
+              <Row gutter={24}>
+                <Col span={8}>
+                  <Form.Item label="鍥哄畾鎸夐挳">
+                    {getFieldDecorator('actionfixed', {
+                      initialValue: config.setting.actionfixed ? 'true' : 'false'
+                    })(
+                      <Radio.Group>
+                        <Radio value="true">鏄�</Radio>
+                        <Radio value="false">鍚�</Radio>
+                      </Radio.Group>
+                    )}
+                  </Form.Item>
+                </Col>
+                <Col span={8}>
+                  <Form.Item label="鍥哄畾琛ㄥご">
+                    {getFieldDecorator('columnfixed', {
+                      initialValue: config.setting.columnfixed ? 'true' : 'false'
+                    })(
+                      <Radio.Group>
+                        <Radio value="true">鏄�</Radio>
+                        <Radio value="false">鍚�</Radio>
+                      </Radio.Group>
+                    )}
+                  </Form.Item>
+                </Col>
+                <Col span={8}>
+                  <Form.Item label="琛ㄦ牸灞炴��">
+                    {getFieldDecorator('tableType', {
+                      initialValue: config.setting.tableType || 'checkbox'
+                    })(
+                      <Select>
+                        <Select.Option value="">涓嶅彲閫�</Select.Option>
+                        <Select.Option value="radio">鍗曢��</Select.Option>
+                        <Select.Option value="checkbox">澶氶��</Select.Option>
+                      </Select>
+                    )}
+                  </Form.Item>
+                </Col>
+              </Row>
+            </Form>
+          </TabPane>
+          <TabPane tab="鎸夐挳璁剧疆" key="action">
+            <ActionForm
+              dict={this.props.dict}
+              actionChange={this.actionChange}
+              wrappedComponentRef={(inst) => this.actionForm = inst}
+            />
+            <Table
+              bordered
+              rowKey="uuid"
+              className="custom-table"
+              dataSource={config.action}
+              columns={actionColumns}
+              pagination={false}
+            />
+          </TabPane>
+        </Tabs>
+      </div>
+    )
+  }
+}
+
+export default Form.create()(VerifyCard)
\ No newline at end of file
diff --git a/src/tabviews/tableshare/verifycard/index.scss b/src/tabviews/tableshare/verifycard/index.scss
new file mode 100644
index 0000000..e9b51d0
--- /dev/null
+++ b/src/tabviews/tableshare/verifycard/index.scss
@@ -0,0 +1,53 @@
+.verify-card-box {
+  .ant-tabs-nav-scroll {
+    text-align: center;
+  }
+  .ant-tabs-content {
+    min-height: 40vh;
+  }
+  table tr td {
+    word-wrap: break-word;
+    word-break: break-word;
+  }
+  .verify-form {
+    .ant-input-number {
+      width: 100%;
+    }
+    .sql {
+      .ant-col-sm-8 {
+        width: 10.5%;
+      }
+      .ant-col-sm-16 {
+        width: 89.5%;
+        padding-top: 4px;
+      }
+    }
+    .sqlfield {
+      .ant-form-item {
+        margin-bottom: 5px;
+      }
+      .ant-col-sm-8 {
+        width: 10.5%;
+      }
+      .ant-col-sm-16 {
+        width: 89.5%;
+      }
+    }
+    .add {
+      padding-top: 4px;
+    }
+  }
+  .custom-table .ant-empty {
+    margin: 20px 8px!important;
+  }
+  .errorval {
+    display: inline-block;
+    width: 30px;
+  }
+  .operation-btn {
+    display: inline-block;
+    font-size: 16px;
+    padding: 0 5px;
+    cursor: pointer;
+  }
+}
\ No newline at end of file
diff --git a/src/templates/comtableconfig/index.scss b/src/templates/comtableconfig/index.scss
index 064a25d..46ac2f6 100644
--- a/src/templates/comtableconfig/index.scss
+++ b/src/templates/comtableconfig/index.scss
@@ -199,7 +199,7 @@
             display: flex;
             margin-bottom: 0px;
             .ant-form-item-label {
-              width: 100px;
+              // width: 100px;
               height: 40px;
               label {
                 width: 100%;
diff --git a/src/templates/comtableconfig/settingform/index.jsx b/src/templates/comtableconfig/settingform/index.jsx
index 84d451b..95b93c6 100644
--- a/src/templates/comtableconfig/settingform/index.jsx
+++ b/src/templates/comtableconfig/settingform/index.jsx
@@ -295,7 +295,6 @@
               )}
             </Form.Item>
           </Col>
-          
           <Col span={12}>
             <Form.Item label="鍥哄畾琛ㄥご">
               {getFieldDecorator('columnfixed', {
diff --git a/src/templates/subtableconfig/index.scss b/src/templates/subtableconfig/index.scss
index 989b573..59a199c 100644
--- a/src/templates/subtableconfig/index.scss
+++ b/src/templates/subtableconfig/index.scss
@@ -199,7 +199,7 @@
             display: flex;
             margin-bottom: 0px;
             .ant-form-item-label {
-              width: 100px;
+              // width: 100px;
               height: 40px;
               label {
                 width: 100%;
diff --git a/src/templates/tableshare/dragelement/card.jsx b/src/templates/tableshare/dragelement/card.jsx
index 5419ea0..ab0ea27 100644
--- a/src/templates/tableshare/dragelement/card.jsx
+++ b/src/templates/tableshare/dragelement/card.jsx
@@ -89,10 +89,10 @@
       <div ref={node => drag(drop(node))}>
         {type === 'search' ?
           <div className="ant-row ant-form-item">
-            <div className="ant-col ant-form-item-label">
+            <div className="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-8">
               <label title={card.label}>{card.label}</label>
             </div>
-            <div className="ant-col ant-form-item-control-wrapper">
+            <div className="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-16">
               {card.type === 'text' ?
                 <Input style={{marginTop: '4px'}} defaultValue={card.initval} /> : null
               }
diff --git a/src/templates/tableshare/dragelement/index.jsx b/src/templates/tableshare/dragelement/index.jsx
index 7737c7a..934db4b 100644
--- a/src/templates/tableshare/dragelement/index.jsx
+++ b/src/templates/tableshare/dragelement/index.jsx
@@ -218,7 +218,7 @@
         />
       ))}
       {type === 'search' && cards.map(card => (
-        <Col key={card.uuid} span={6}>
+        <Col key={card.uuid} span={card.ratio || 6}>
           <Card
             id={`${card.uuid}`}
             type={type}
diff --git a/src/templates/tableshare/formconfig.js b/src/templates/tableshare/formconfig.js
index 3f7a21a..57410cd 100644
--- a/src/templates/tableshare/formconfig.js
+++ b/src/templates/tableshare/formconfig.js
@@ -205,6 +205,16 @@
       }]
     },
     {
+      type: 'number',
+      key: 'ratio',
+      min: 1,
+      max: 24,
+      label: Formdict['header.form.ratio'],
+      tooltip: '姣忚鍒嗕负24浠斤紝姣斾緥鍙缃负1-24',
+      initVal: card.ratio,
+      required: false
+    },
+    {
       type: 'select',
       key: 'quick',
       label: Formdict['header.form.quickadd'],
diff --git a/src/templates/tableshare/searchform/index.jsx b/src/templates/tableshare/searchform/index.jsx
index 51a0c5b..adba3f1 100644
--- a/src/templates/tableshare/searchform/index.jsx
+++ b/src/templates/tableshare/searchform/index.jsx
@@ -1,6 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { Form, Row, Col, Input, Select, Icon, Radio, notification, Tooltip } from 'antd'
+import { Form, Row, Col, Input, Select, Icon, Radio, notification, Tooltip, InputNumber } from 'antd'
 import { dateOptions, matchReg, formRule } from '@/utils/option.js'
 import EditTable from '../editable'
 import './index.scss'
@@ -32,7 +32,7 @@
 
     let type = formlist.filter(cell => cell.key === 'type')[0].initVal
     let resourceType = formlist.filter(cell => cell.key === 'resourceType')[0].initVal
-    let _options = ['label', 'field', 'initval', 'type', 'match']                // 榛樿鏄剧ず椤�
+    let _options = ['label', 'field', 'initval', 'type', 'match', 'ratio']                // 榛樿鏄剧ず椤�
 
     if ((type === 'multiselect' || type === 'select' || type === 'link') && resourceType === '0') {        // 涓嬫媺閫夋嫨绫诲瀷銆侀�夐」涓鸿嚜瀹氫箟璧勬簮
       _options = [..._options, 'resourceType', 'options', 'display', 'quick']
@@ -104,7 +104,7 @@
     const { resourceType } = this.state
 
     if (key === 'type') {
-      let _options = ['label', 'field', 'initval', 'type', 'match']
+      let _options = ['label', 'field', 'initval', 'type', 'match', 'ratio']
 
       if ((value === 'multiselect' || value === 'select' || value === 'link') && resourceType === '0') {        // 涓嬫媺閫夋嫨绫诲瀷銆侀�夐」涓鸿嚜瀹氫箟璧勬簮
         _options = [..._options, 'resourceType', 'options', 'display', 'quick']
@@ -189,7 +189,7 @@
     let value = e.target.value
 
     if (key === 'resourceType') {
-      let _options = ['label', 'field', 'initval', 'type', 'match', 'resourceType', 'display']
+      let _options = ['label', 'field', 'initval', 'type', 'match', 'resourceType', 'display', 'ratio']
 
       if (value === '0') {
         _options = [..._options, 'options', 'quick']
@@ -267,6 +267,27 @@
             </Form.Item>
           </Col>
         )
+      } else if (item.type === 'number') {
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.tooltip ?
+              <Tooltip placement="topLeft" title={item.tooltip}>
+                <Icon type="question-circle" />
+                {item.label}
+              </Tooltip> : item.label
+            }>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal || 6,
+                rules: [
+                  {
+                    required: item.required,
+                    message: this.props.dict['form.required.input'] + item.label + '!'
+                  }
+                ]
+              })(<InputNumber min={item.min} max={item.max} precision={0} />)}
+            </Form.Item>
+          </Col>
+        )
       } else if (item.type === 'select') { // 涓嬫媺鎼滅储
         fields.push(
           <Col span={12} key={index}>
diff --git a/src/templates/tableshare/searchform/index.scss b/src/templates/tableshare/searchform/index.scss
index 55f5d81..64b8351 100644
--- a/src/templates/tableshare/searchform/index.scss
+++ b/src/templates/tableshare/searchform/index.scss
@@ -15,4 +15,7 @@
     position: relative;
     left: -3px;
   }
+  .ant-input-number {
+    width: 100%;
+  }
 }
\ No newline at end of file
diff --git a/src/templates/tableshare/verifycard/index.jsx b/src/templates/tableshare/verifycard/index.jsx
index b53fb4e..3ced595 100644
--- a/src/templates/tableshare/verifycard/index.jsx
+++ b/src/templates/tableshare/verifycard/index.jsx
@@ -1002,7 +1002,7 @@
 
     return (
       <div id="verify-card-box-tab">
-        <Tabs defaultActiveKey="1" className="verify-card-box" onChange={this.tabchange}>
+        <Tabs defaultActiveKey="1" className="verify-card-box">
           <TabPane tab="鍩虹楠岃瘉" key="1">
             <Form {...formItemLayout}>
               <Row gutter={24}>
diff --git a/src/views/login/index.jsx b/src/views/login/index.jsx
index 004eb56..e1b9292 100644
--- a/src/views/login/index.jsx
+++ b/src/views/login/index.jsx
@@ -56,45 +56,44 @@
   async loginsubmit (param) {
     // 鐧诲綍鎻愪氦
     // let password = this.md5Password(param.password)
-    let result = await Api.loginsystem(param.username, param.password)
-    if (!result.IsError) {
-      Api.getusermsg(param.username, param.password).then(res => {
-        if (res.status) {
-          sessionStorage.setItem('UserID', res.UserID)
-          sessionStorage.setItem('SessionUid', Utils.getuuid())
-          sessionStorage.setItem('LoginUID', res.LoginUID)
-          sessionStorage.setItem('User_Name', res.UserName)
-          sessionStorage.setItem('avatar', res.icon || '')
-          
-          localStorage.setItem('lang', param.lang)
+    // let result = await Api.loginsystem(param.username, param.password)
+    // if (!result.IsError) {
+    let res = await Api.getusermsg(param.username, param.password)
+    if (res.status) {
+      sessionStorage.setItem('UserID', res.UserID)
+      sessionStorage.setItem('SessionUid', Utils.getuuid())
+      sessionStorage.setItem('LoginUID', res.LoginUID)
+      sessionStorage.setItem('User_Name', res.UserName)
+      sessionStorage.setItem('avatar', res.icon || '')
+      
+      localStorage.setItem('lang', param.lang)
 
-          let _url = window.location.href.split('#')[0]
+      let _url = window.location.href.split('#')[0]
 
-          if (param.remember) { // 璁颁綇瀵嗙爜鏃惰处鍙峰瘑鐮佸瓨鍏ocalStorage
-            localStorage.setItem(_url, window.btoa(window.encodeURIComponent(JSON.stringify({username: param.username, password: param.password}))))
-          } else {
-            localStorage.removeItem(_url)
-          }
-    
-          if (this.props.location.state && this.props.location.state.from.pathname) {
-            // 鏌ョ湅鏄惁涓哄叾浠栭〉闈㈣烦杞紝璺緞瀛樺湪鏃讹紝璺冲洖鍘熼〉闈�
-            this.props.history.replace(this.props.location.state.from.pathname)
-          } else {
-            this.props.history.replace('/main')
-          }
-        } else {
-          message.warning(res.message)
-          this.setState({
-            isDisabled: false
-          })
-        }
-      })
+      if (param.remember) { // 璁颁綇瀵嗙爜鏃惰处鍙峰瘑鐮佸瓨鍏ocalStorage
+        localStorage.setItem(_url, window.btoa(window.encodeURIComponent(JSON.stringify({username: param.username, password: param.password}))))
+      } else {
+        localStorage.removeItem(_url)
+      }
+
+      if (this.props.location.state && this.props.location.state.from.pathname) {
+        // 鏌ョ湅鏄惁涓哄叾浠栭〉闈㈣烦杞紝璺緞瀛樺湪鏃讹紝璺冲洖鍘熼〉闈�
+        this.props.history.replace(this.props.location.state.from.pathname)
+      } else {
+        this.props.history.replace('/main')
+      }
     } else {
-      message.warning(result.Message)
+      message.warning(res.message)
       this.setState({
         isDisabled: false
       })
     }
+    // } else {
+    //   message.warning(result.Message)
+    //   this.setState({
+    //     isDisabled: false
+    //   })
+    // }
   }
 
   componentDidMount () {
diff --git a/src/views/printTemplate/dragelement/index.scss b/src/views/printTemplate/dragelement/index.scss
index bf335cf..a271383 100644
--- a/src/views/printTemplate/dragelement/index.scss
+++ b/src/views/printTemplate/dragelement/index.scss
@@ -12,6 +12,8 @@
   }
 }
 .print-area {
+  position: relative;
+  z-index: 2;
   display: inline-block;
   margin: 0 auto;
   margin-right: 30px;
diff --git a/src/views/printTemplate/index.jsx b/src/views/printTemplate/index.jsx
index fc31b6a..b071926 100644
--- a/src/views/printTemplate/index.jsx
+++ b/src/views/printTemplate/index.jsx
@@ -47,10 +47,11 @@
     let scrollTop = document.documentElement.scrollTop || document.body.scrollTop
     let screenX = e.clientX
     let screenY = e.clientY + scrollTop
-    let offsetT = screenY - document.getElementById('darea').offsetTop
-    let offsetL = screenX - document.getElementById('darea').offsetLeft
-    
-    let cx = Math.floor(offsetL / parseInt(document.getElementById('darea').style.width) * config.width)
+    let offsetT = screenY - 75
+    let _width = parseInt(document.getElementById('darea').style.width)
+    let offsetL = screenX - (document.body.offsetWidth - _width - 30) / 2
+
+    let cx = Math.floor(offsetL / _width * config.width)
     let cy = Math.floor(offsetT / parseInt(document.getElementById('darea').style.height) * config.height)
 
     return {
@@ -104,10 +105,11 @@
           y -= 4
           height = 8
         }
-        if (cx > x && cx < x + width && cy > y && cy < y + height) {
+        if (cx >= x && cx <= x + width && cy >= y && cy <= y + height) {
           _selectItem = element
         }
       })
+
       if (!_selectItem) {
         _selectItem = _config
       } else {
@@ -298,7 +300,14 @@
     document.getElementById('darea').addEventListener('drop', (e) => {
       dropPoint = this.getclickpoint(e)
     })
+    
+    this.handleResize()
+    window.addEventListener('resize', this.handleResize)
 
+    this.loadconfig()
+  }
+
+  handleResize = () => {
     if (document.body.offsetWidth < 1360) {
       document.getElementById('darea').style.width = '600px'
     } else if (document.body.offsetWidth < 1500) {
@@ -306,8 +315,6 @@
     } else if (document.body.offsetWidth < 1920) {
       document.getElementById('darea').style.width = '800px'
     }
-
-    this.loadconfig()
   }
 
   resetbox = () => {
@@ -381,6 +388,18 @@
         duration: 10
       })
     }
+  }
+
+  switchbox = () => {
+    const { config } = this.state
+
+    this.setState({
+      editItemId: config.uuid,
+      editItemType: config.type,
+      formlist: getpageform(config)
+    }, () => {
+      this.resetview()
+    })
   }
 
   /**
@@ -658,22 +677,21 @@
           if (result.status) {
             resolve(Utils.getcloudurl(result.Images))
           } else {
-            // notification.warning({
-            //   top: 92,
-            //   message: result.ErrMesg,
-            //   duration: 10
-            // })
-            // this.setState({
-            //   saveloading: false
-            // })
-            // resolve(false)
-            resolve(true)
+            notification.warning({
+              top: 92,
+              message: result.ErrMesg,
+              duration: 10
+            })
+            this.setState({
+              saveloading: false
+            })
+            resolve(false)
           }
         })
       })
     }).then(res => {
       if (!res) return
-      param.Images = 'http://css.positecgroup.com/Content/Upload/2020-01-08/2020010810525808769824_U000000001.png'
+      param.Images = res
 
       return Api.getCloudConfig(param)
     }).then(res => {
@@ -710,6 +728,7 @@
               })}
             </Card>
           </aside>
+          <div className="switchbox" onClick={this.switchbox}></div>
           <DragElement dropcard={this.dropcard} />
           <aside className="setting">
             {this.state.editItemId ?
diff --git a/src/views/printTemplate/index.scss b/src/views/printTemplate/index.scss
index 3eb4643..b5f0419 100644
--- a/src/views/printTemplate/index.scss
+++ b/src/views/printTemplate/index.scss
@@ -21,6 +21,7 @@
   .tools {
     width: 240px;
     position: fixed;
+    z-index: 3;
     top: 47px;
     left: -1px;
     bottom: 0px;
@@ -42,6 +43,7 @@
   .setting {
     width: 300px;
     position: fixed;
+    z-index: 3;
     top: 47px;
     right: -1px;
     bottom: 0px;
@@ -88,5 +90,11 @@
       margin-bottom: 10px;
     }
   }
-  
+  .switchbox {
+    position: absolute;
+    left: 240px;
+    right: 300px;
+    top: 48px;
+    bottom: 0px;
+  }
 }
\ No newline at end of file

--
Gitblit v1.8.0