From e9e8b1c7b481415714fff9a0d83099fd5a7d6ff0 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期四, 18 五月 2023 17:25:11 +0800
Subject: [PATCH] 2023-05-18

---
 src/menu/components/table/edit-table/columns/tableIn/index.jsx              |  115 ++
 src/templates/zshare/verifycard/baseform/index.scss                         |   26 
 src/menu/components/share/pastebasetable/index.jsx                          |   41 
 src/utils/utils-custom.js                                                   |  227 +--
 src/menu/components/card/cardcellcomponent/elementform/index.jsx            |  198 +--
 src/templates/comtableconfig/updatetable/index.jsx                          |   27 
 src/tabviews/zshare/settingcomponent/index.jsx                              |   45 
 public/options.json                                                         |   12 
 src/tabviews/custom/popview/index.jsx                                       |  149 +-
 src/views/tabledesign/source.jsx                                            |    6 
 src/menu/components/table/normal-table/columns/editColumn/index.jsx         |  101 +
 src/tabviews/basetable/index.jsx                                            |   80 
 src/views/billprint/index.jsx                                               |   14 
 src/tabviews/zshare/actionList/normalbutton/index.jsx                       |    4 
 src/menu/components/table/edit-table/columns/editColumn/index.jsx           |   79 
 src/views/mobdesign/index.jsx                                               |  104 +
 src/views/menudesign/index.jsx                                              |   71 +
 src/menu/components/table/edit-table/columns/tableIn/index.scss             |  138 ++
 src/menu/modulesource/option.jsx                                            |    4 
 src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx      |   79 -
 src/tabviews/custom/components/card/cardcellList/index.jsx                  |   13 
 src/tabviews/custom/components/module/voucher/index.jsx                     |    8 
 src/menu/components/card/cardcellcomponent/index.jsx                        |    3 
 src/tabviews/custom/components/table/edit-table/normalTable/index.jsx       |   40 
 src/menu/components/table/edit-table/columns/index.scss                     |    5 
 src/tabviews/custom/index.jsx                                               |  158 +-
 src/menu/components/table/base-table/columns/index.jsx                      |   92 
 src/menu/components/table/normal-table/index.jsx                            |   14 
 src/menu/components/table/normal-table/columns/index.jsx                    |   95 
 src/menu/components/table/edit-table/columns/index.jsx                      |   89 
 src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx    |   31 
 src/templates/zshare/codemirror/index.scss                                  |   10 
 src/menu/components/table/base-table/columns/editColumn/formconfig.jsx      |   67 
 src/menu/transfer/index.jsx                                                 |    4 
 src/tabviews/custom/components/table/edit-table/index.jsx                   |    3 
 src/views/tabledesign/index.jsx                                             |  109 +
 src/tabviews/custom/components/share/normalTable/index.jsx                  |   19 
 src/menu/components/table/normal-table/columns/index.scss                   |    5 
 src/menu/components/table/edit-table/index.jsx                              |    7 
 src/menu/components/share/usercomponent/index.jsx                           |   50 
 src/menu/components/table/base-table/columns/index.scss                     |    5 
 src/menu/components/table/base-table/columns/editColumn/index.jsx           |  200 ++-
 src/menu/components/share/pastecomponent/index.jsx                          |   40 
 src/views/pcdesign/index.jsx                                                |  100 +
 src/menu/replaceField/index.jsx                                             |   92 
 src/menu/components/share/actioncomponent/index.jsx                         |    2 
 src/menu/modulecell/index.jsx                                               |    3 
 src/menu/components/card/cardcellcomponent/formconfig.jsx                   |   30 
 src/menu/components/table/base-table/columns/editColumn/index.scss          |   18 
 src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx |   54 
 src/menu/components/table/base-table/index.jsx                              |   42 
 src/templates/zshare/verifycard/baseform/index.jsx                          |   93 -
 52 files changed, 1,691 insertions(+), 1,330 deletions(-)

diff --git a/public/options.json b/public/options.json
index 6942fe8..bedcbee 100644
--- a/public/options.json
+++ b/public/options.json
@@ -1,14 +1,14 @@
 {
-  "appId": "201912040924165801464FF1788654BC5AC73",
-  "appkey": "20191106103859640976D6E924E464D029CF0",
+  "appId": "202108312122504607B107A83F55B40C98CCF",
+  "appkey": "20210831212235413F287EC3BF489424496C8",
   "mainSystemApi": "http://sso.mk9h.cn/cloud/webapi/dostars",
   "systemType": "",
   "externalDatabase": "",
   "lineColor": "",
   "filter": "false",
-  "defaultApp": "mk",
+  "defaultApp": "mkindustry",
   "defaultLang": "zh-CN",
-  "WXAppID": "wx4d8a34c8d4494872",
+  "WXAppID": "",
   "WXminiAppID": "",
   "nginx": "true",
   "debugger": false,
@@ -17,6 +17,6 @@
   "transfer": "false",
   "keepPassword": "true",
   "platforms": ["H5", "wechat", "android", "ios", "wxMiniProgram"],
-  "host": "http://qingqiumarket.cn",
-  "service": "MKWMS/"
+  "host": "http://demo.mk9h.cn",
+  "service": "erp_new/"
 }
\ No newline at end of file
diff --git a/src/menu/components/card/cardcellcomponent/elementform/index.jsx b/src/menu/components/card/cardcellcomponent/elementform/index.jsx
index 02ece02..647b4ee 100644
--- a/src/menu/components/card/cardcellcomponent/elementform/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/elementform/index.jsx
@@ -29,7 +29,7 @@
   color: ['eleType', 'datatype', 'width', 'lenWidRadio', 'noValue', 'copyable'],
 }
 
-class MainSearch extends Component {
+class ElementEditForm extends Component {
   static propTpyes = {
     config: PropTypes.object,    // 缁勪欢淇℃伅
     formlist: PropTypes.any,     // 琛ㄥ崟淇℃伅
@@ -38,28 +38,24 @@
   }
 
   state = {
-    formlist: null,  // 琛ㄥ崟淇℃伅
-    eleType: '',
-    datatype: '',
-    showType: '',
-    showInfo: 'false',
-    fixStyle: '',
-    link: ''
+    formlist: null  // 琛ㄥ崟淇℃伅
   }
 
+  record = null
+
   UNSAFE_componentWillMount () {
-    const { card, config, side } = this.props
-    let _options = this.getOptions(card.eleType, card.datatype, card.link, (card.showType || 'line'), card.showInfo, card.fixStyle || '', card.posterType || '')
+    const { card, config, side, formlist } = this.props
     
+    this.record = {}
+
+    formlist.forEach(item => {
+      this.record[item.key] = item.initVal
+    })
+    
+    let _options = this.getOptions()
+
     this.setState({
-      link: card.link,
-      eleType: card.eleType,
-      datatype: card.datatype,
-      showType: card.showType || 'line',
-      showInfo: card.showInfo || 'false',
-      fixStyle: card.fixStyle || '',
-      posterType: card.posterType || '',
-      formlist: this.props.formlist.map(item => {
+      formlist: formlist.map(item => {
         item.hidden = !_options.includes(item.key)
 
         if (item.key === 'field' || item.key === 'linkurl' || item.key === 'bgImage' || item.key === 'posterField') {
@@ -154,50 +150,50 @@
     })
   }
 
-  getOptions = (eleType, datatype, link, showType, showInfo, fixStyle, posterType) => {
-    let _options = fromJS(cardTypeOptions[eleType]).toJS() // 閫夐」鍒楄〃
+  getOptions = () => {
+    let _options = fromJS(cardTypeOptions[this.record.eleType]).toJS() // 閫夐」鍒楄〃
     
-    if (['text', 'number', 'picture', 'slider', 'barcode', 'qrcode', 'video', 'color'].includes(eleType)) {
-      if (datatype === 'dynamic') {
+    if (['text', 'number', 'picture', 'slider', 'barcode', 'qrcode', 'video', 'color'].includes(this.record.eleType)) {
+      if (this.record.datatype === 'dynamic') {
         _options.push('field')
-        if (eleType === 'number') {
+        if (this.record.eleType === 'number') {
           _options.push('decimal', 'format')
         }
-      } else if (eleType === 'picture' || eleType === 'video') {
+      } else if (this.record.eleType === 'picture' || this.record.eleType === 'video') {
         _options.push('url')
       } else {
         _options.push('value')
       }
-      if (eleType === 'video' && posterType) {
-        if (posterType === 'dynamic') {
+      if (this.record.eleType === 'video' && this.record.posterType) {
+        if (this.record.posterType === 'dynamic') {
           _options.push('posterField')
         } else {
           _options.push('posterUrl')
         }
       }
 
-      if (['text', 'picture'].includes(eleType) && link) {
-        // if (link === 'dynamic' || link === 'static') {
-          _options.push('linkurl', 'joint', 'linkType')
-        // }
-      } else if (eleType === 'picture' && !link) {
+      if (['text', 'picture'].includes(this.record.eleType) && this.record.link) {
+        _options.push('linkurl', 'joint', 'linkType')
+      } else if (this.record.eleType === 'picture' && !this.record.link) {
         _options.push('scale')
-      } else if (eleType === 'slider') {
-        if (showInfo === 'true') {
+      } else if (this.record.eleType === 'slider') {
+        if (this.record.showInfo === 'true') {
           _options.push('infoColor')
         }
-        if (showType !== 'line') {
+        if (this.record.showType !== 'line') {
           _options.push('outlineWidth', 'textAlign')
         }
       }
-    } else if (eleType === 'icon') {
-      if (datatype === 'dynamic') {
+    } else if (this.record.eleType === 'icon') {
+      if (this.record.datatype === 'dynamic') {
         _options.push('field', 'noValue')
       } else {
         _options.push('icon')
       }
+    } else if (this.record.eleType === 'formula' && this.record.eval === 'true') {
+      _options.push('decimal')
     }
-    if (_options.includes('fixStyle') && fixStyle === 'alone') {
+    if (_options.includes('fixStyle') && this.record.fixStyle === 'alone') {
       _options.push('fixSize', 'fixColor', 'fixLeft', 'fixRight')
     }
 
@@ -211,13 +207,22 @@
    * 3銆佸垏鎹㈡爣绛剧被鍨嬶紝閲嶇疆鍙�夋爣绛�
    */
   selectChange = (key, value, option) => {
-    const { card, config, side } = this.props
-    const { datatype, eleType, showType, showInfo, fixStyle, posterType } = this.state
+    const { config, side } = this.props
+
+    this.record[key] = value
 
     if (key === 'eleType') {
-      let _options = this.getOptions(value, datatype, '', showType, showInfo, fixStyle, posterType)
+      this.record.link = ''
+      let _options = this.getOptions()
+
+      if (value === 'splitline') {
+        this.record.color = '#EBE9E9'
+      } else if (value === 'formula') {
+        this.record.decimal = ''
+      }
       
       let _formlist = this.state.formlist.map(item => {
+        item.initVal = this.record[item.key]
         item.hidden = !_options.includes(item.key)
 
         if (item.key === 'field') {
@@ -274,16 +279,6 @@
           }
         } else if (item.key === 'url') {
           item.required = value !== 'qrcode'
-        } else if (item.key === 'showInfo') {
-          item.initVal = showInfo
-        } else if (item.key === 'posterType') {
-          item.initVal = posterType
-        } else if (item.key === 'fixStyle') {
-          item.initVal = fixStyle
-        } else if (item.key === 'color') {
-          if (value === 'splitline') {
-            item.initVal = '#EBE9E9'
-          }
         }
 
         return item
@@ -295,9 +290,6 @@
       }
 
       this.setState({
-        link: '',
-        eleType: value,
-        showType: card.showType || 'line',
         formlist: _formlist
       }, () => {
         if (value === 'splitline') {
@@ -320,90 +312,27 @@
         this.props.form.setFieldsValue({value: option.props.title})
       }
     } else if (key === 'link') {
-      let _options = this.getOptions(eleType, datatype, value, showType, showInfo, fixStyle, posterType)
+      let _options = this.getOptions()
       this.setState({
-        link: value,
         formlist: this.state.formlist.map(item => {
+          item.initVal = this.record[item.key]
           item.hidden = !_options.includes(item.key)
+
           if (item.key === 'linkurl') {
             item.type = value === 'dynamic' ? 'select' : 'textarea'
           }
           return item
         })
       })
-    }
-  }
-
-  onChange = (e, key) => {
-    const { eleType, datatype, link, showType, showInfo, fixStyle, posterType } = this.state
-    let value = e.target.value
-
-    if (key === 'datatype') {
-      let _options = this.getOptions(eleType, value, link, showType, showInfo, fixStyle, posterType)
+    } else if (['datatype', 'showInfo', 'showType', 'fixStyle', 'posterType', 'eval'].includes(key)) {
+      let _options = this.getOptions()
 
       this.setState({
-        datatype: value,
         formlist: this.state.formlist.map(item => {
+          item.initVal = this.record[item.key]
           item.hidden = !_options.includes(item.key)
 
           return item
-        })
-      })
-    } else if (key === 'link') {
-      let _options = this.getOptions(eleType, datatype, value, showType, showInfo, fixStyle, posterType)
-      this.setState({
-        link: value,
-        formlist: this.state.formlist.map(item => {
-          item.hidden = !_options.includes(item.key)
-          if (item.key === 'linkurl') {
-            item.type = value === 'dynamic' ? 'select' : 'textarea'
-          }
-          return item
-        })
-      })
-    } else if (key === 'showInfo') {
-      let _options = this.getOptions(eleType, datatype, link, showType, value, fixStyle, posterType)
-      this.setState({
-        showInfo: value,
-        formlist: this.state.formlist.map(item => {
-          item.hidden = !_options.includes(item.key)
-          return item
-        })
-      })
-    } else if (key === 'showType') {
-      this.setState({
-        showType: value
-      }, () => {
-        let _options = this.getOptions(eleType, datatype, link, value, showInfo, fixStyle, posterType)
-        this.setState({
-          formlist: this.state.formlist.map(item => {
-            item.hidden = !_options.includes(item.key)
-            return item
-          })
-        })
-      })
-    } else if (key === 'fixStyle') {
-      this.setState({
-        fixStyle: value
-      }, () => {
-        let _options = this.getOptions(eleType, datatype, link, showType, showInfo, value, posterType)
-        this.setState({
-          formlist: this.state.formlist.map(item => {
-            item.hidden = !_options.includes(item.key)
-            return item
-          })
-        })
-      })
-    } else if (key === 'posterType') {
-      this.setState({
-        posterType: value
-      }, () => {
-        let _options = this.getOptions(eleType, datatype, link, showType, showInfo, fixStyle, value)
-        this.setState({
-          formlist: this.state.formlist.map(item => {
-            item.hidden = !_options.includes(item.key)
-            return item
-          })
         })
       })
     }
@@ -585,7 +514,7 @@
                   message: '璇烽�夋嫨' + item.label + '!'
                 }]
               })(
-                <Radio.Group onChange={(e) => {this.onChange(e, item.key)}} disabled={item.readonly}>
+                <Radio.Group onChange={(e) => {this.selectChange(item.key, e.target.value)}} disabled={item.readonly}>
                   {item.options.map(option => {
                     return (
                       <Radio key={option.value} value={option.value}>{option.text}</Radio>
@@ -670,12 +599,33 @@
   }
 
   handleConfirm = () => {
+    const { config } = this.props
+
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     return new Promise((resolve, reject) => {
       this.props.form.validateFieldsAndScroll((err, values) => {
         if (!err) {
           values.uuid = this.props.card.uuid
           values.marks = this.props.card.marks || null
+
+          // eslint-disable-next-line
+          if (values.eleType === 'formula' && values.eval !== 'false' && /^[\u4E00-\u9FA50-9a-zA-Z_\s@\+\-\*\/]*$/ig.test(values.formula) && /[\+\-\*\/]/ig.test(values.formula)) {
+            let cols = []
+            config.subColumns && config.subColumns.forEach(col => {
+              if (/^(Int|Decimal)/ig.test(col.datatype)) {
+                cols.push({reg: new RegExp('@' + col.field + '@', 'ig'), value: `(@${col.field}@)`})
+              }
+            })
+            config.columns.forEach(col => {
+              if (/^(Int|Decimal)/ig.test(col.datatype)) {
+                cols.push({reg: new RegExp('@' + col.field + '@', 'ig'), value: `(@${col.field}@)`})
+              }
+            })
+
+            cols.forEach(col => {
+              values.formula = values.formula.replace(col.reg, col.value)
+            })
+          }
 
           resolve(values)
         } else {
@@ -704,4 +654,4 @@
   }
 }
 
-export default Form.create()(MainSearch)
\ No newline at end of file
+export default Form.create()(ElementEditForm)
\ No newline at end of file
diff --git a/src/menu/components/card/cardcellcomponent/formconfig.jsx b/src/menu/components/card/cardcellcomponent/formconfig.jsx
index e7675ad..47866cd 100644
--- a/src/menu/components/card/cardcellcomponent/formconfig.jsx
+++ b/src/menu/components/card/cardcellcomponent/formconfig.jsx
@@ -169,6 +169,21 @@
       required: true
     },
     {
+      type: 'radio',
+      key: 'eval',
+      label: '瑙f瀽',
+      initVal: card.eval || 'false',
+      tooltip: '褰撳叕寮忓唴瀹规秹鍙婅绠楁椂璇烽�夋嫨鈥滄槸鈥濓紝褰撳叕寮忓唴瀹逛负瀛楁鎷兼帴鏃惰閫夋嫨鈥滃惁鈥濄��',
+      required: false,
+      options: [{
+        value: 'true',
+        text: '鏄�'
+      }, {
+        value: 'false',
+        text: '鍚�'
+      }]
+    },
+    {
       type: 'number',
       key: 'decimal',
       min: 0,
@@ -540,21 +555,6 @@
       key: 'joint',
       label: '鎷兼帴鍙傛暟',
       initVal: card.joint || 'true',
-      required: false,
-      options: [{
-        value: 'true',
-        text: '鏄�'
-      }, {
-        value: 'false',
-        text: '鍚�'
-      }]
-    },
-    {
-      type: 'radio',
-      key: 'eval',
-      label: '瑙f瀽',
-      initVal: card.eval || 'false',
-      tooltip: '褰撳叕寮忓唴瀹规秹鍙婅绠楁椂璇烽�夋嫨鈥滄槸鈥濓紝褰撳叕寮忓唴瀹逛负瀛楁鎷兼帴鏃惰閫夋嫨鈥滃惁鈥濄��',
       required: false,
       options: [{
         value: 'true',
diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx
index f676322..8e7bc2a 100644
--- a/src/menu/components/card/cardcellcomponent/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/index.jsx
@@ -624,10 +624,9 @@
   }
 
   dropButton = (id) => {
-    const { cards, cardCell } = this.props
+    const { cards } = this.props
 
     if (!cards.action) return
-    if (cardCell.type === 'custom') return
 
     let index = cards.action.findIndex(item => item.uuid === id)
 
diff --git a/src/menu/components/share/actioncomponent/index.jsx b/src/menu/components/share/actioncomponent/index.jsx
index 89e63fa..9e48add 100644
--- a/src/menu/components/share/actioncomponent/index.jsx
+++ b/src/menu/components/share/actioncomponent/index.jsx
@@ -599,7 +599,7 @@
     let _col = null
     if (config.type === 'table') {
       config.cols.forEach(col => {
-        if (col.type !== 'action') return
+        if (col.type !== 'custom') return
 
         col.elements = col.elements.filter(item => {
           if (item.uuid === id) {
diff --git a/src/menu/components/share/pastebasetable/index.jsx b/src/menu/components/share/pastebasetable/index.jsx
index adb2c56..5c8eb9a 100644
--- a/src/menu/components/share/pastebasetable/index.jsx
+++ b/src/menu/components/share/pastebasetable/index.jsx
@@ -39,42 +39,27 @@
         return cell
       })
 
-      let loopCol = (col) => {
-        col.subcols = col.subcols.map(c => {
-          c.uuid = Utils.getuuid()
+      let loopCol = (cols) => {
+        return cols.map(col => {
+          col.uuid = Utils.getuuid()
+          
+          if (col.type === 'action') {
+            col.type = 'custom'
+          }
 
-          if (c.type === 'colspan' && c.subcols) {
-            c = loopCol(c)
-          } else if (c.type === 'custom' && c.elements) {
-            c.elements = c.elements.map(cell => {
+          if (col.type === 'colspan' && col.subcols) {
+            col.subcols = loopCol(col.subcols)
+          } else if (col.type === 'custom' && col.elements) {
+            col.elements = col.elements.map(cell => {
               cell.uuid = Utils.getuuid()
               return cell
             })
           }
-          return c
+          return col
         })
-
-        return col
       }
 
-      res.cols = res.cols.map(col => {
-        col.uuid = Utils.getuuid()
-
-        if (col.type === 'colspan' && col.subcols) {
-          col = loopCol(col)
-        } else if (col.type === 'custom' && col.elements) {
-          col.elements = col.elements.map(cell => {
-            cell.uuid = Utils.getuuid()
-            return cell
-          })
-        } else if (col.type === 'action' && col.elements) {
-          col.elements = col.elements.map(cell => {
-            cell.uuid = Utils.getuuid()
-            return cell
-          })
-        }
-        return col
-      })
+      res.cols = loopCol(res.cols)
 
       let oriUids = {}
       res.action = res.action.map(cell => {
diff --git a/src/menu/components/share/pastecomponent/index.jsx b/src/menu/components/share/pastecomponent/index.jsx
index 51ae57d..5c2b417 100644
--- a/src/menu/components/share/pastecomponent/index.jsx
+++ b/src/menu/components/share/pastecomponent/index.jsx
@@ -74,41 +74,27 @@
         })
       }
     } else if (item.copyType === 'cols') {
-      let loopCol = (col) => {
-        col.subcols = col.subcols.map(c => {
-          c.uuid = Utils.getuuid()
+      let loopCol = (cols) => {
+        return cols.map(col => {
+          col.uuid = Utils.getuuid()
 
-          if (c.type === 'colspan' && c.subcols) {
-            c = loopCol(c)
-          } else if (c.type === 'custom' && c.elements) {
-            c.elements = c.elements.map(cell => {
+          if (col.type === 'action') {
+            col.type = 'custom'
+          }
+
+          if (col.type === 'colspan' && col.subcols) {
+            col.subcols = loopCol(col.subcols)
+          } else if (col.type === 'custom' && col.elements) {
+            col.elements = col.elements.map(cell => {
               cell.uuid = Utils.getuuid()
               return cell
             })
           }
-          return c
+          return col
         })
-
-        return col
       }
 
-      item.cols = item.cols.map(_item => {
-        _item.uuid = Utils.getuuid()
-        if (_item.type === 'colspan' && _item.subcols) {
-          _item = loopCol(_item)
-        } else if (_item.type === 'custom' && _item.elements) {
-          _item.elements = _item.elements.map(cell => {
-            cell.uuid = Utils.getuuid()
-            return cell
-          })
-        } else if (_item.type === 'action' && _item.elements) {
-          _item.elements = _item.elements.map(cell => {
-            cell.uuid = Utils.getuuid()
-            return cell
-          })
-        }
-        return _item
-      })
+      item.cols = loopCol(item.cols)
     }
 
     return item
diff --git a/src/menu/components/share/usercomponent/index.jsx b/src/menu/components/share/usercomponent/index.jsx
index 07c968b..8862fa6 100644
--- a/src/menu/components/share/usercomponent/index.jsx
+++ b/src/menu/components/share/usercomponent/index.jsx
@@ -82,36 +82,30 @@
       return item
     })
 
-    _config.cols = _config.cols.map(col => {
-      if (col.type === 'colspan' && col.subcols) {
-        col = this.loopCol(col)
-      } else if (col.type === 'custom' && col.elements) {
-        col.elements = col.elements.map(cell => this.resetElement(cell))
-      } else if (col.type === 'action' && col.elements) {
-        col.elements = col.elements.map(cell => {
-          cell.verify = null
-          return cell
-        })
-      }
-      col.marks = null
-      return col
-    })
+    let loopCol = (cols) => {
+      return cols.map(col => {
+        col.uuid = Utils.getuuid()
+        col.marks = null
+
+        if (col.type === 'colspan' && col.subcols) {
+          col.subcols = loopCol(col.subcols)
+        } else if (col.type === 'custom' && col.elements) {
+          col.elements = col.elements.map(cell => {
+            if (cell.eleType === 'button') {
+              cell.verify = null
+            } else {
+              cell = this.resetElement(cell)
+            }
+            return cell
+          })
+        }
+        return col
+      })
+    }
+
+    _config.cols = loopCol(_config.cols)
 
     return _config
-  }
-
-  loopCol = (col) => {
-    col.subcols = col.subcols.map(c => {
-      if (c.type === 'colspan' && c.subcols) {
-        c = this.loopCol(c)
-      } else if (c.type === 'custom' && c.elements) {
-        c.elements = c.elements.map(cell => this.resetElement(cell))
-      }
-      c.marks = null
-      return c
-    })
-
-    return col
   }
 
   resetElement = (item) => {
diff --git a/src/menu/components/table/base-table/columns/editColumn/formconfig.jsx b/src/menu/components/table/base-table/columns/editColumn/formconfig.jsx
index fb51dad..e139d76 100644
--- a/src/menu/components/table/base-table/columns/editColumn/formconfig.jsx
+++ b/src/menu/components/table/base-table/columns/editColumn/formconfig.jsx
@@ -58,11 +58,9 @@
     text: '搴忓彿'
   }]
 
-  if (!card.isSub) {
-    options.push({
-      value: 'action',
-      text: '鎿嶄綔'
-    })
+  let decimal = card.decimal === undefined ? 0 : card.decimal
+  if (card.type === 'formula' && typeof(card.decimal) !== 'number') {
+    decimal = ''
   }
 
   return [
@@ -71,7 +69,11 @@
       key: 'label',
       label: '鍒楀ご鏂囧瓧',
       initVal: card.label,
-      required: true
+      required: true,
+      rules: [{
+        max: 100,
+        message: '鏈�澶�100涓瓧绗︺��'
+      }]
     },
     {
       type: 'select',
@@ -87,14 +89,25 @@
       label: '瀛楁',
       initVal: card.field,
       required: true,
-      options: card.isSub ? fields : []
+      options: card.isSub ? fields : [],
+      rules: [{
+        pattern: /^[\u4E00-\u9FA50-9a-zA-Z_]*$/ig,
+        message: '瀛楁鍚嶅彧鍏佽鍖呭惈鏁板瓧銆佸瓧姣嶃�佹眽瀛椾互鍙奯'
+      }, {
+        max: 100,
+        message: '鏈�澶�100涓瓧绗︺��'
+      }]
     },
     {
       type: 'text',
       key: 'nameField',
       label: '鍚嶇О瀛楁',
       initVal: card.nameField || '',
-      required: false
+      required: false,
+      rules: [{
+        max: 100,
+        message: '鏈�澶�100涓瓧绗︺��'
+      }]
     },
     {
       type: 'number',
@@ -147,6 +160,18 @@
         value: 'false',
         text: '鍚�'
       }]
+    },
+    {
+      type: 'radio',
+      key: 'eval',
+      label: '瑙f瀽',
+      initVal: card.eval || 'false',
+      tooltip: '褰撳叕寮忓唴瀹规秹鍙婅绠楁椂璇烽�夋嫨鈥滄槸鈥濓紝褰撳叕寮忓唴瀹逛负瀛楁鎷兼帴鏃惰閫夋嫨鈥滃惁鈥濄��',
+      required: false,
+      options: [
+        { value: 'true', text: '鏄�' },
+        { value: 'false', text: '鍚�' }
+      ]
     },
     {
       type: 'radio',
@@ -231,7 +256,7 @@
       max: 18,
       decimal: 0,
       label: '灏忔暟浣�',
-      initVal: card.decimal === undefined ? 0 : card.decimal,
+      initVal: decimal,
       required: !card.isSub
     },
     {
@@ -280,7 +305,11 @@
       label: '鍓嶇紑',
       initVal: card.prefix || '',
       required: false,
-      readonly: false
+      readonly: false,
+      rules: [{
+        max: 100,
+        message: '鏈�澶�100涓瓧绗︺��'
+      }]
     },
     {
       type: 'text',
@@ -288,7 +317,11 @@
       label: '鍚庣紑',
       initVal: card.postfix || '',
       required: false,
-      readonly: false
+      readonly: false,
+      rules: [{
+        max: 100,
+        message: '鏈�澶�100涓瓧绗︺��'
+      }]
     },
     {
       type: 'number',
@@ -390,18 +423,6 @@
       initVal: card.linkfields || [],
       required: false,
       options: fields,
-    },
-    {
-      type: 'radio',
-      key: 'eval',
-      label: '瑙f瀽',
-      initVal: card.eval || 'false',
-      tooltip: '褰撳叕寮忓唴瀹规秹鍙婅绠楁椂璇烽�夋嫨鈥滄槸鈥濓紝褰撳叕寮忓唴瀹逛负瀛楁鎷兼帴鏃惰閫夋嫨鈥滃惁鈥濄��',
-      required: false,
-      options: [
-        { value: 'true', text: '鏄�' },
-        { value: 'false', text: '鍚�' }
-      ]
     },
     {
       type: 'textarea',
diff --git a/src/menu/components/table/base-table/columns/editColumn/index.jsx b/src/menu/components/table/base-table/columns/editColumn/index.jsx
index 1311e6e..16ae1ca 100644
--- a/src/menu/components/table/base-table/columns/editColumn/index.jsx
+++ b/src/menu/components/table/base-table/columns/editColumn/index.jsx
@@ -1,11 +1,10 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
-import { Form, Row, Col, Input, Select, InputNumber, Radio, Tooltip, Cascader, Modal, Checkbox } from 'antd'
+import { Form, Row, Col, Input, Select, InputNumber, Radio, Tooltip, Cascader, Modal, Checkbox, Popover } from 'antd'
 import { QuestionCircleOutlined } from '@ant-design/icons'
 
 import { getColumnForm } from './formconfig'
-import { formRule } from '@/utils/option.js'
 import './index.scss'
 
 const { TextArea } = Input
@@ -25,7 +24,6 @@
 
 class NormalTableColumn extends Component {
   static propTpyes = {
-    visible: PropTypes.bool,
     column: PropTypes.object,
     fields: PropTypes.array,
     submitCol: PropTypes.func,  // 鎻愪氦浜嬩欢
@@ -36,6 +34,8 @@
     visible: false,
     formlist: null
   }
+
+  record = null
 
   UNSAFE_componentWillReceiveProps (nextProps) {
     if (nextProps.column && !is(fromJS(this.props.column), fromJS(nextProps.column))) {
@@ -50,20 +50,26 @@
     })
     
     let formlist = getColumnForm(column, fields)
-    let _options = fromJS(columnTypeOptions[column.type]).toJS()
-    if (column.type === 'text' || column.type === 'number') {
-      if (column.perspective === 'linkmenu') {
-        _options.push('linkmenu', 'linkfields', 'open')
-      } else if (column.perspective === 'linkurl') {
-        _options.push('linkurl', 'linkfields', 'open')
-      }
-    }
+
+    this.record = {}
+
+    formlist.forEach(item => {
+      this.record[item.key] = item.initVal
+    })
+    
+    let _options = this.getOptions()
 
     this.setState({
       visible: true,
-      type: column.type,
       formlist: formlist.map(item => {
         item.hidden = !_options.includes(item.key)
+
+        if (item.key === 'formula') {
+          item.fields = this.props.fields.map(col => col.field)
+          item.fields = item.fields.join(', ')
+        } else if (this.record.type === 'formula' && item.key === 'decimal') {
+          item.required = false
+        }
 
         return item
       })
@@ -80,13 +86,41 @@
     }
   }
 
+  getOptions = () => {
+    let _options = fromJS(columnTypeOptions[this.record.type]).toJS()
+
+    if (this.record.type === 'text' || this.record.type === 'number') {
+      if (this.record.perspective === 'linkmenu') {
+        _options.push('linkmenu', 'linkfields', 'open')
+      } else if (this.record.perspective === 'linkurl') {
+        _options.push('linkurl', 'linkfields', 'open')
+      }
+    }
+    
+    if (this.record.type === 'formula' && this.record.eval === 'true') {
+      _options.push('decimal')
+    }
+
+    return _options
+  }
+
   typeChange = (key, value, option) => {
+    const { column } = this.props
+    this.record[key] = value
+
     if (key === 'type') {
-      let _options = fromJS(columnTypeOptions[value]).toJS()
+      let _options = this.getOptions()
 
       this.setState({
-        type: value,
         formlist: this.state.formlist.map(item => {
+          if (item.key === 'decimal') {
+            item.required = !(column.isSub || value === 'formula')
+            if (value === 'formula') {
+              this.record.decimal = ''
+            }
+          }
+
+          item.initVal = this.record[item.key]
           item.hidden = !_options.includes(item.key)
 
           return item
@@ -98,8 +132,6 @@
           this.props.form.setFieldsValue({perspective: ''})
         } else if (value === 'colspan') {
           this.props.form.setFieldsValue({Align: 'center'})
-        } else if (value === 'action') {
-          this.props.form.setFieldsValue({Align: 'center', label: '鎿嶄綔'})
         } else if (value === 'index') {
           this.props.form.setFieldsValue({label: '搴忓彿'})
         }
@@ -117,13 +149,18 @@
         values.type = 'text'
       }
 
-      if (values.type !== this.state.type) {
+      let _type = this.record.type
+      this.record.type = values.type
+
+      if (values.type !== _type) {
         values.perspective = ''
-        let _options = fromJS(columnTypeOptions[values.type]).toJS()
+        this.record.perspective = ''
+
+        let _options = this.getOptions()
 
         this.setState({
-          type: values.type,
           formlist: this.state.formlist.map(item => {
+            item.initVal = this.record[item.key]
             item.hidden = !_options.includes(item.key)
 
             return item
@@ -136,21 +173,12 @@
       }
     } else if (key === 'format' && value === 'percent') {
       this.props.form.setFieldsValue({postfix: '%'})
-    }
-  }
-
-  changeRadio = (key, value) => {
-    if (key === 'perspective') {
-      let _options = fromJS(columnTypeOptions[this.state.type]).toJS()
-
-      if (value === 'linkmenu') {
-        _options.push('linkmenu', 'linkfields', 'open')
-      } else if (value === 'linkurl') {
-        _options.push('linkurl', 'linkfields', 'open')
-      }
+    } else if (['perspective', 'eval'].includes(key)) {
+      let _options = this.getOptions()
 
       this.setState({
         formlist: this.state.formlist.map(item => {
+          item.initVal = this.record[item.key]
           item.hidden = !_options.includes(item.key)
 
           return item
@@ -170,21 +198,6 @@
       if (item.hidden || item.forbid) return
 
       if (item.type === 'text') {
-        let rules = []
-        if (item.key === 'field') {
-          rules = [{
-            pattern: /^[\u4E00-\u9FA50-9a-zA-Z_]*$/ig,
-            message: '瀛楁鍚嶅彧鍏佽鍖呭惈鏁板瓧銆佸瓧姣嶃�佹眽瀛椾互鍙奯'
-          }, {
-            max: formRule.input.max,
-            message: formRule.input.message
-          }]
-        } else if (item.key !== 'linkurl') {
-          rules = [{
-            max: formRule.input.max,
-            message: formRule.input.message
-          }]
-        }
         fields.push(
           <Col span={12} key={index}>
             <Form.Item label={item.tooltip ?
@@ -200,7 +213,7 @@
                     required: !!item.required,
                     message: '璇疯緭鍏�' + item.label + '!'
                   },
-                  ...rules
+                  ...item.rules
                 ]
               })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.handleSubmit} />)}
             </Form.Item>
@@ -275,14 +288,10 @@
                   }
                 ]
               })(
-                <Radio.Group onChange={(e) => {this.changeRadio(item.key, e.target.value)}}>
-                  {
-                    item.options.map(option => {
-                      return (
-                        <Radio key={option.value} value={option.value}>{option.text}</Radio>
-                      )
-                    })
-                  }
+                <Radio.Group onChange={(e) => {this.typeChange(item.key, e.target.value)}}>
+                  {item.options.map(option => {
+                    return (<Radio key={option.value} value={option.value}>{option.text}</Radio>)
+                  })}
                 </Radio.Group>
               )}
             </Form.Item>
@@ -350,35 +359,76 @@
           </Col>
         )
       } else if (item.type === 'textarea') {
-        fields.push(
-          <Col span={24} key={index} className="textarea">
-            <Form.Item label={item.tooltip ?
-              <Tooltip placement="topLeft" title={item.tooltip}>
-                <QuestionCircleOutlined className="mk-form-tip" />
-                {item.label}
-              </Tooltip> : item.label
-            }>
-              {getFieldDecorator(item.key, {
-                initialValue: item.initVal || '',
-                rules: [
-                  {
-                    required: !!item.required,
-                    message: '璇疯緭鍏�' + item.label + '!'
-                  }
-                ]
-              })(<TextArea rows={2} disabled={item.readonly} placeholder={item.placeholder || ''}/>)}
-            </Form.Item>
-          </Col>
-        )
+        if (item.key === 'formula') {
+          fields.push(
+            <Col span={24} className="textarea" key={index}>
+              <Form.Item label={item.tooltip ?
+                <Tooltip placement="topLeft" title={item.tooltip}>
+                  <QuestionCircleOutlined className="mk-form-tip" />
+                  {item.label}
+                </Tooltip> : item.label
+              }>
+                {getFieldDecorator(item.key, {
+                  initialValue: item.initVal || '',
+                  rules: [
+                    {
+                      required: !!item.required,
+                      message: '璇疯緭鍏�' + item.label + '!'
+                    }
+                  ]
+                })(<TextArea autoSize={{minRows: 2}} disabled={item.readonly} placeholder={item.placeholder || ''} />)}
+              </Form.Item>
+              <Popover overlayClassName="formula-fields" placement="topLeft" title="" content={<div>{item.fields}</div>} trigger="click">
+                <span className="formula-icon">瀛楁闆�</span>
+              </Popover>
+            </Col>
+          )
+        } else {
+          fields.push(
+            <Col span={24} key={index} className="textarea">
+              <Form.Item label={item.tooltip ?
+                <Tooltip placement="topLeft" title={item.tooltip}>
+                  <QuestionCircleOutlined className="mk-form-tip" />
+                  {item.label}
+                </Tooltip> : item.label
+              }>
+                {getFieldDecorator(item.key, {
+                  initialValue: item.initVal || '',
+                  rules: [
+                    {
+                      required: !!item.required,
+                      message: '璇疯緭鍏�' + item.label + '!'
+                    }
+                  ]
+                })(<TextArea rows={2} disabled={item.readonly} placeholder={item.placeholder || ''}/>)}
+              </Form.Item>
+            </Col>
+          )
+        }
       }
     })
     return fields
   }
 
   handleSubmit = () => {
+    const { fields } = this.props
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     this.props.form.validateFieldsAndScroll((err, values) => {
       if (!err) {
+        // eslint-disable-next-line
+        if (values.type === 'formula' && values.eval !== 'false' && /^[\u4E00-\u9FA50-9a-zA-Z_\s@\+\-\*\/]*$/ig.test(values.formula) && /[\+\-\*\/]/ig.test(values.formula)) {
+          let cols = []
+          fields.forEach(col => {
+            if (/^(Int|Decimal)/ig.test(col.datatype)) {
+              cols.push({reg: new RegExp('@' + col.field + '@', 'ig'), value: `(@${col.field}@)`})
+            }
+          })
+
+          cols.forEach(col => {
+            values.formula = values.formula.replace(col.reg, col.value)
+          })
+        }
+
         this.props.submitCol(values, () => {
           this.setState({visible: false, formlist: null})
         })
diff --git a/src/menu/components/table/base-table/columns/editColumn/index.scss b/src/menu/components/table/base-table/columns/editColumn/index.scss
index 6d72890..e653f84 100644
--- a/src/menu/components/table/base-table/columns/editColumn/index.scss
+++ b/src/menu/components/table/base-table/columns/editColumn/index.scss
@@ -14,9 +14,27 @@
       width: 88%;
     }
   }
+  .formula-icon {
+    position: absolute;
+    bottom: 5px;
+    right: 15px;
+    cursor: pointer;
+    font-size: 12px;
+    color: #1890ff;
+  }
   >.ant-row >.ant-col {
     display: inline-block;
     vertical-align: top;
     float: none;
   }
 }
+.formula-fields {
+  z-index: 1200!important;
+
+  .ant-popover-inner-content {
+    div {
+      max-width: 750px;
+      word-break: break-all;
+    }
+  }
+}
diff --git a/src/menu/components/table/base-table/columns/index.jsx b/src/menu/components/table/base-table/columns/index.jsx
index e970390..c6b6e95 100644
--- a/src/menu/components/table/base-table/columns/index.jsx
+++ b/src/menu/components/table/base-table/columns/index.jsx
@@ -3,7 +3,7 @@
 import { is, fromJS } from 'immutable'
 import { DndProvider, DragSource, DropTarget } from 'react-dnd'
 import { Table, Popover, Modal, message, notification } from 'antd'
-import { PlusOutlined, EditOutlined, CopyOutlined, DeleteOutlined, FontColorsOutlined, CloseCircleOutlined, AntDesignOutlined, InfoOutlined } from '@ant-design/icons'
+import { PlusOutlined, PlusSquareOutlined, EditOutlined, CopyOutlined, DeleteOutlined, FontColorsOutlined, CloseCircleOutlined, AntDesignOutlined, InfoOutlined } from '@ant-design/icons'
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
@@ -53,7 +53,7 @@
   render() {
     const { connectDragSource, connectDropTarget, moveCol, addElement, dropCol, updateCol, editColumn, pasteCell, changeStyle, deleteCol, index, column, align, fields, children, ...restProps } = this.props
 
-    if (index !== undefined) {
+    if (index !== undefined && column) {
       let style = {cursor: 'move', textAlign: align}
       if (column.Width) {
         style.width = column.Width
@@ -65,17 +65,17 @@
       }
 
       return connectDragSource(
-        connectDropTarget(<th {...restProps} index={index} style={style} onDoubleClick={() => column && this.props.editColumn(column)}>
+        connectDropTarget(<th {...restProps} index={index} style={style} onDoubleClick={() => this.props.editColumn(column)}>
           <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
             <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
-              {column && ['custom', 'colspan', 'action'].includes(column.type) ?
-                <PlusOutlined className="plus" title="娣诲姞" onClick={() => this.props.addElement(column)} /> : null
-              }
+              {column.type === 'colspan' ? <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.props.addElement(column)} /> : null}
+              {column.type === 'custom' ? <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={() => this.props.addElement(column)} /> : null}
+              {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.props.addElement(column, 'button')} /> : null}
               <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
-              {column && column.type === 'custom' ? <PasteComponent options={['customCardElement']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
-              {column && (column.type === 'custom' || column.type === 'action') ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
+              {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
+              {column.type === 'custom' ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
               <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
-              {column && ['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
+              {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
             </div>
           } trigger="hover">
             {children}
@@ -97,13 +97,13 @@
         <th {...restProps} style={style} key={column.uuid} onDoubleClick={() => this.props.editColumn(column)}>
           <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
             <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
-              {column && ['custom', 'colspan'].includes(column.type) ?
-                <PlusOutlined className="plus" title="娣诲姞" onClick={() => this.props.addElement(column)} /> : null
-              }
+              {column.type === 'colspan' ? <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.props.addElement(column)} /> : null}
+              {column.type === 'custom' ? <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={() => this.props.addElement(column)} /> : null}
+              {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.props.addElement(column, 'button')} /> : null}
               <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
-              {column.type === 'custom' ? <PasteComponent options={['customCardElement']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
+              {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
               <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
-              {column && ['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
+              {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
             </div>
           } trigger="hover">
             {children}
@@ -200,12 +200,6 @@
     if (column && column.type === 'custom') {
       return (
         <td style={{padding: 0, ...(column.style || {})}} className={className}>
-          <CardCellComponent cards={config} cardCell={column} elements={column.elements} updateElement={this.updateCard}/>
-        </td>
-      )
-    } else if (column && column.type === 'action') {
-      return (
-        <td style={{padding: 0, textAlign: column.Align, ...(column.style || {})}} className={'action-column ' + className}>
           <CardCellComponent cards={config} cardCell={column} elements={column.elements} updateElement={this.updateCard}/>
         </td>
       )
@@ -322,11 +316,9 @@
   dropCol = (item, hoverIndex) => {
     let _columns = fromJS(this.state.columns).toJS()
 
-    let col = { focus: true, uuid: Utils.getuuid(), label: 'label', field: '', type: item.subType, elements: [] }
+    let col = { focus: true, uuid: Utils.getuuid(), Width: 120, label: 'label', field: '', type: item.subType, elements: [] }
     if (col.type === 'colspan') {
       col.subcols = []
-    } else if (col.type === 'action') {
-      col.label = '鎿嶄綔'
     } else if (col.type === 'index') {
       col.label = '搴忓彿'
     }
@@ -381,14 +373,23 @@
   pasteCell = (col, cell, resolve) => {
     resolve({status: true})
     
-    delete cell.copyType
     cell.uuid = Utils.getuuid()
     cell.focus = true
+    
+    if (!cell.eleType) {
+      if (cell.copyType === 'action') {
+        cell.eleType = 'button'
+        cell.width = cell.width || 12
+      } else {
+        cell.eleType = 'text'
+      }
+    }
+    delete cell.copyType
     
     MKEmitter.emit('cardAddElement', col.uuid, cell)
   }
 
-  addElement = (col) => {
+  addElement = (col, type) => {
     let column = fromJS(col).toJS()
 
     if (column.type === 'colspan') {
@@ -401,26 +402,28 @@
       })
       this.updateCol(column)
     } else if (column.type === 'custom') {
-      let newcard = {uuid: Utils.getuuid(), focus: true, width: 24, eleType: 'text', datatype: 'dynamic', style: {paddingLeft: '4px'}}
+      if (type === 'button') {
+        let newcard = {
+          uuid: Utils.getuuid(),
+          focus: true,
+          eleType: 'button',
+          label: 'button',
+          OpenType: 'prompt',
+          class: 'primary',
+          intertype: 'system',
+          execSuccess: 'grid',
+          execError: 'never',
+          show: 'link'
+        }
   
-      // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
-      MKEmitter.emit('cardAddElement', column.uuid, newcard)
-    } else if (column.type === 'action') {
-      let newcard = {
-        uuid: Utils.getuuid(),
-        focus: true,
-        eleType: 'button',
-        label: 'button',
-        OpenType: 'prompt',
-        class: 'primary',
-        intertype: 'system',
-        execSuccess: 'grid',
-        execError: 'never',
-        show: 'link'
+        // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
+        MKEmitter.emit('cardAddElement', column.uuid, newcard)
+      } else {
+        let newcard = {uuid: Utils.getuuid(), focus: true, width: 24, eleType: 'text', datatype: 'dynamic', style: {paddingLeft: '4px'}}
+    
+        // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
+        MKEmitter.emit('cardAddElement', column.uuid, newcard)
       }
-
-      // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
-      MKEmitter.emit('cardAddElement', column.uuid, newcard)
     }
   }
 
@@ -436,9 +439,6 @@
     } else if (col.type === 'custom') {
       col.style = card.style || {}
       col.elements = card.type === 'custom' ? (card.elements || []) : []
-    } else if (col.type === 'action') {
-      col.style = card.style || {}
-      col.elements = card.type === 'action' ? (card.elements || []) : []
     }
 
     if (!col.field || col.isSub) {
diff --git a/src/menu/components/table/base-table/columns/index.scss b/src/menu/components/table/base-table/columns/index.scss
index 2c350a3..45da4dc 100644
--- a/src/menu/components/table/base-table/columns/index.scss
+++ b/src/menu/components/table/base-table/columns/index.scss
@@ -36,11 +36,6 @@
         }
       }
     }
-    .action-column {
-      .card-detail-row:empty {
-        min-height: 40px;
-      }
-    }
     tr:hover td {
       background: #ffffff!important;
     }
diff --git a/src/menu/components/table/base-table/index.jsx b/src/menu/components/table/base-table/index.jsx
index 30ad6c2..e301f10 100644
--- a/src/menu/components/table/base-table/index.jsx
+++ b/src/menu/components/table/base-table/index.jsx
@@ -99,39 +99,6 @@
     MKEmitter.removeListener('completeSave', this.completeSave)
   }
 
-  // updateFix = (card) => {
-  //   let fixs = {}
-
-  //   card.cols.forEach(col => {
-  //     if (!col.field) return
-  //     if (col.postfix || col.prefix) {
-  //       fixs[col.field] = col
-  //     }
-  //   })
-
-  //   card.cols.forEach(col => {
-  //     if (col.type === 'custom') {
-  //       col.elements.forEach(cell => {
-  //         if (cell.datatype === 'dynamic') {
-  //           cell.height = ''
-  //           cell.innerHeight = 'auto'
-
-  //           if (fixs[cell.field]) {
-  //             if (!cell.prefix && fixs[cell.field].prefix) {
-  //               cell.prefix = fixs[cell.field].prefix
-  //             }
-  //             if (!cell.postfix && fixs[cell.field].postfix) {
-  //               cell.postfix = fixs[cell.field].postfix
-  //             }
-  //           }
-  //         }
-  //       })
-  //     }
-  //   })
-
-  //   return card
-  // }
-
   completeSave = () => {
     const { card } = this.state
 
@@ -255,8 +222,13 @@
     let _actions = [...action]
 
     cols.forEach(col => {
-      if (col.type !== 'action') return
-      _actions.push(...col.elements)
+      if (col.type === 'custom') {
+        col.elements.forEach(cell => {
+          if (cell.eleType !== 'button') return
+
+          _actions.push(cell)
+        })
+      }
     })
 
     return getWrapForm(wrap, _actions, columns)
diff --git a/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx b/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx
index 72898a7..14981f8 100644
--- a/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx
+++ b/src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx
@@ -14,7 +14,6 @@
     roleList = []
   }
 
-  // if (['picture', 'link', 'colspan'].includes(card.type)) {
   if (['picture', 'link'].includes(card.type)) {
     card.type = 'text'
   }
@@ -34,9 +33,6 @@
   }, {
     value: 'colspan',
     text: '鍚堝苟鍒�'
-  // }, {
-  //   value: 'action',
-  //   text: '鎿嶄綔'
   }, {
     value: 'formula',
     text: '鍏紡'
@@ -44,13 +40,6 @@
     value: 'index',
     text: '搴忓彿'
   }]
-
-  if (!card.isSub) {
-    options.push({
-      value: 'action',
-      text: '鎿嶄綔'
-    })
-  }
 
   let editCols = [
     {
@@ -148,6 +137,18 @@
     },
     {
       type: 'radio',
+      key: 'eval',
+      label: '瑙f瀽',
+      initVal: card.eval || 'false',
+      tooltip: '褰撳叕寮忓唴瀹规秹鍙婅绠楁椂璇烽�夋嫨鈥滄槸鈥濓紝褰撳叕寮忓唴瀹逛负瀛楁鎷兼帴鏃惰閫夋嫨鈥滃惁鈥濄��',
+      required: false,
+      options: [
+        { value: 'true', text: '鏄�' },
+        { value: 'false', text: '鍚�' }
+      ]
+    },
+    {
+      type: 'radio',
       key: 'Align',
       label: '瀵归綈鏂瑰紡',
       initVal: card.Align || 'left',
@@ -163,21 +164,6 @@
         text: '鍙冲榻�'
       }]
     },
-    // {
-    //   type: 'radio',
-    //   key: 'sum',
-    //   label: '鏄剧ず鍚堣',
-    //   initVal: card.sum || 'false',
-    //   tooltip: '鍚堣淇℃伅鍙湪浣跨敤绯荤粺鏁版嵁婧愭椂鏈夋晥銆�',
-    //   required: false,
-    //   options: [{
-    //     value: 'true',
-    //     text: '鏄�'
-    //   }, {
-    //     value: 'false',
-    //     text: '鍚�'
-    //   }]
-    // },
     {
       type: 'radio',
       key: 'editable',
@@ -259,16 +245,6 @@
         text: '鏁版嵁婧�'
       }]
     },
-    // {
-    //   type: 'select',
-    //   key: 'editField',
-    //   label: '缂栬緫瀛楁',
-    //   initVal: card.editField || '',
-    //   tooltip: '褰撳�间笌鎻愮ず鏂囧瓧涓嶅悓鏃讹紝鍙澶栨坊鍔犵紪杈戝瓧娈碉紝浣滀负瀹為檯鍊肩殑褰曞叆瀛楁銆�',
-    //   allowClear: true,
-    //   required: false,
-    //   options: fields
-    // },
     {
       type: 'options',
       key: 'options',
@@ -392,23 +368,6 @@
       tooltip: '澶氫釜鍊肩敤閫楀彿鍒嗛殧銆�',
       required: false
     },
-    // {
-    //   type: 'radio',
-    //   key: 'footEnter',
-    //   label: '鏈鍥炶溅',
-    //   initVal: card.footEnter || 'false',
-    //   tooltip: '鏂板鍔熻兘浠呭湪琛ㄦ牸鍙柊澧炴椂鏈夋晥銆�',
-    //   options: [{
-    //     value: 'sub',
-    //     text: '鎻愪氦'
-    //   }, {
-    //     value: 'add',
-    //     text: '鏂板'
-    //   }, {
-    //     value: 'false',
-    //     text: '鏃犲姩浣�'
-    //   }]
-    // },
     {
       type: 'number',
       key: 'decimal',
@@ -416,7 +375,7 @@
       max: 18,
       precision: 0,
       label: '灏忔暟浣�',
-      initVal: card.decimal || 0,
+      initVal: card.decimal,
       required: false
     },
     {
@@ -488,18 +447,6 @@
       label: '鍚庣紑',
       initVal: card.postfix || '',
       required: false,
-    },
-    {
-      type: 'radio',
-      key: 'eval',
-      label: '瑙f瀽',
-      initVal: card.eval || 'false',
-      tooltip: '褰撳叕寮忓唴瀹规秹鍙婅绠楁椂璇烽�夋嫨鈥滄槸鈥濓紝褰撳叕寮忓唴瀹逛负瀛楁鎷兼帴鏃惰閫夋嫨鈥滃惁鈥濄��',
-      required: false,
-      options: [
-        { value: 'true', text: '鏄�' },
-        { value: 'false', text: '鍚�' }
-      ]
     },
     {
       type: 'textarea',
diff --git a/src/menu/components/table/edit-table/columns/editColumn/index.jsx b/src/menu/components/table/edit-table/columns/editColumn/index.jsx
index 0f479c0..9a0143c 100644
--- a/src/menu/components/table/edit-table/columns/editColumn/index.jsx
+++ b/src/menu/components/table/edit-table/columns/editColumn/index.jsx
@@ -17,18 +17,17 @@
 const { TextArea } = Input
 const columnTypeOptions = {
   text: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'prefix', 'postfix', 'textFormat', 'editable', 'initval', 'blacklist'],
-  number: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'decimal', 'format', 'prefix', 'postfix', 'editable', 'initval', 'sum', 'blacklist', 'noValue'],
+  number: ['label', 'field', 'type', 'Align', 'Hide', 'IsSort', 'Width', 'decimal', 'format', 'prefix', 'postfix', 'editable', 'initval', 'sum', 'blacklist'],
   textarea: ['label', 'field', 'type', 'Align', 'Hide', 'Width', 'prefix', 'initval', 'postfix', 'blacklist'],
   custom: ['label', 'type', 'Align', 'Width', 'blacklist'],
   colspan: ['label', 'type', 'Align', 'Hide', 'blacklist'],
   action: ['label', 'type', 'Align', 'Width'],
-  formula: ['label', 'type', 'Align', 'Hide', 'Width', 'prefix', 'postfix', 'eval', 'formula', 'blacklist', 'noValue'],
+  formula: ['label', 'type', 'Align', 'Hide', 'Width', 'prefix', 'postfix', 'eval', 'formula', 'blacklist'],
   index: ['label', 'type', 'Align', 'Width']
 }
 
 class EdiTableColumn extends Component {
   static propTpyes = {
-    visible: PropTypes.bool,
     column: PropTypes.object,
     columns: PropTypes.array,
     fields: PropTypes.array,
@@ -43,7 +42,7 @@
     transfield: {}
   }
 
-  column = null
+  record = null
 
   UNSAFE_componentWillMount() {
     let transfield = {}
@@ -61,22 +60,22 @@
   }
 
   getOptions = () => {
-    let _options = fromJS(columnTypeOptions[this.column.type]).toJS()
+    let _options = fromJS(columnTypeOptions[this.record.type]).toJS()
 
-    if (this.column.editable === 'true') {
+    if (['number', 'text'].includes(this.record.type) && this.record.editable === 'true') {
       _options.push('ctrlField')
-      if (this.column.ctrlField) {
+      if (this.record.ctrlField) {
         _options.push('ctrlValue')
       }
-      if (this.column.type === 'text') {
+      if (this.record.type === 'text') {
         _options.push('editType')
 
-        if (this.column.editType === 'switch') {
+        if (this.record.editType === 'switch') {
           _options.push('enter', 'openVal', 'closeVal', 'openText', 'closeText', 'editField')
-        } else if (this.column.editType === 'select') {
+        } else if (this.record.editType === 'select') {
           _options.push('required', 'enter', 'resourceType', 'linkSubField', 'editField', 'dropdown')
 
-          if (this.column.resourceType === '0') {
+          if (this.record.resourceType === '0') {
             _options.push('options')
           } else {
             _options.push('dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'disableField', 'database')
@@ -84,9 +83,15 @@
         } else {
           _options.push('required', 'enter')
         }
-      } else if (this.column.type === 'number') {
+      } else if (this.record.type === 'number') {
         _options.push('max', 'min', 'enter')
       }
+    }
+    if (this.record.type === 'formula' && this.record.eval === 'true') {
+      _options.push('decimal')
+    }
+    if (['number', 'formula'].includes(this.record.type) && this.record.Hide !== 'true') {
+      _options.push('noValue')
     }
 
     return _options
@@ -99,10 +104,11 @@
     })
 
     let formlist = getColumnForm(column, fields, this.props.columns)
+    this.record = {}
 
-    this.column = fromJS(column).toJS()
-    this.column.editType = this.column.editType || 'text'
-    this.column.resourceType = this.column.resourceType || '0'
+    formlist.forEach(item => {
+      this.record[item.key] = item.initVal
+    })
     
     let _options = this.getOptions()
 
@@ -132,7 +138,7 @@
   }
 
   typeChange = (key, value, option) => {
-    this.column[key] = value
+    this.record[key] = value
 
     if (key === 'type') {
       let _options = this.getOptions()
@@ -144,7 +150,11 @@
 
       this.setState({
         formlist: this.state.formlist.map(item => {
-          item.initVal = this.column[item.key] || item.initVal
+          if (item.key === 'decimal' && value === 'formula') {
+            this.record.decimal = ''
+          }
+
+          item.initVal = this.record[item.key]
           item.hidden = !_options.includes(item.key)
 
           return item
@@ -154,8 +164,6 @@
           this.props.form.setFieldsValue({Align: 'center'})
         } else if (value === 'formula' && _field) {
           this.props.form.setFieldsValue({formula: '@' + _field + '@'})
-        } else if (value === 'action') {
-          this.props.form.setFieldsValue({Align: 'center', label: '鎿嶄綔'})
         } else if (value === 'index') {
           this.props.form.setFieldsValue({label: '搴忓彿'})
         }
@@ -173,15 +181,15 @@
         values.type = 'text'
       }
 
-      let _type = this.column.type
-      this.column.type = values.type
+      let _type = this.record.type
+      this.record.type = values.type
 
       if (values.type !== _type) {
         let _options = this.getOptions()
 
         this.setState({
           formlist: this.state.formlist.map(item => {
-            item.initVal = this.column[item.key] || item.initVal
+            item.initVal = this.record[item.key]
             item.hidden = !_options.includes(item.key)
 
             return item
@@ -194,12 +202,12 @@
       }
     } else if (key === 'format' && value === 'percent') {
       this.props.form.setFieldsValue({postfix: '%'})
-    } else if (key === 'editable' || key === 'editType' || key === 'resourceType' || key === 'ctrlField') {
+    } else if (['editable', 'editType', 'resourceType', 'ctrlField', 'eval', 'Hide'].includes(key)) {
       let _options = this.getOptions()
 
       this.setState({
         formlist: this.state.formlist.map(item => {
-          item.initVal = this.column[item.key] || item.initVal
+          item.initVal = this.record[item.key]
           item.hidden = !_options.includes(item.key)
 
           return item
@@ -211,7 +219,7 @@
   multiselectChange = (key, value) => {
     if (key !== 'linkSubField') return
 
-    this.column[key] = value
+    this.record[key] = value
   }
 
   handleEmpty = () => {
@@ -249,7 +257,7 @@
   }
 
   changeOptions = (data) => {
-    this.column.options = data || []
+    this.record.options = data || []
   }
 
   getFields() {
@@ -371,7 +379,7 @@
         span = 24
         className = 'text-area'
 
-        let linkSubFields = this.column.linkSubField || []
+        let linkSubFields = this.record.linkSubField || []
       
         content = <EditTable type={'select'} module="form" transfield={transfield} linkSubFields={linkSubFields} onChange={this.changeOptions}/>
       }
@@ -396,6 +404,7 @@
   }
 
   handleSubmit = () => {
+    const { fields } = this.props
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     this.props.form.validateFieldsAndScroll((err, values) => {
       if (!err) {
@@ -408,6 +417,18 @@
             })
             return
           }
+          // eslint-disable-next-line
+        } else if (values.type === 'formula' && values.eval !== 'false' && /^[\u4E00-\u9FA50-9a-zA-Z_\s@\+\-\*\/]*$/ig.test(values.formula) && /[\+\-\*\/]/ig.test(values.formula)) {
+          let cols = []
+          fields.forEach(col => {
+            if (/^(Int|Decimal)/ig.test(col.datatype)) {
+              cols.push({reg: new RegExp('@' + col.field + '@', 'ig'), value: `(@${col.field}@)`})
+            }
+          })
+
+          cols.forEach(col => {
+            values.formula = values.formula.replace(col.reg, col.value)
+          })
         }
 
         if (values.dataSource && /\s/.test(values.dataSource)) {
@@ -448,7 +469,7 @@
             if (result.status) {
               this.setState({visible: false, loading: false, formlist: null})
               this.props.submitCol(values)
-              this.column = null
+              this.record = null
             } else {
               this.setState({loading: false})
               Modal.error({
@@ -459,7 +480,7 @@
         } else {
           this.setState({visible: false, formlist: null})
           this.props.submitCol(values)
-          this.column = null
+          this.record = null
         }
       }
     })
diff --git a/src/menu/components/table/edit-table/columns/index.jsx b/src/menu/components/table/edit-table/columns/index.jsx
index cf70fdb..cc785fd 100644
--- a/src/menu/components/table/edit-table/columns/index.jsx
+++ b/src/menu/components/table/edit-table/columns/index.jsx
@@ -3,7 +3,7 @@
 import { is, fromJS } from 'immutable'
 import { DndProvider, DragSource, DropTarget } from 'react-dnd'
 import { Table, Popover, Modal, message, Button, Typography } from 'antd'
-import { PlusOutlined, FileSyncOutlined, EditOutlined, CopyOutlined, DeleteOutlined, FontColorsOutlined, CloseCircleOutlined, AntDesignOutlined } from '@ant-design/icons'
+import { PlusOutlined, PlusSquareOutlined, FileSyncOutlined, EditOutlined, CopyOutlined, DeleteOutlined, FontColorsOutlined, CloseCircleOutlined, AntDesignOutlined } from '@ant-design/icons'
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
@@ -75,13 +75,12 @@
         connectDropTarget(<th {...restProps} index={index} style={style} onDoubleClick={() => this.props.editColumn(column)}>
           <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
             <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
-              {['custom', 'colspan', 'action'].includes(column.type) ?
-                <PlusOutlined className="plus" title="娣诲姞" onClick={() => this.props.addElement(column)} /> : null
-              }
+              {column.type === 'colspan' ? <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.props.addElement(column)} /> : null}
+              {column.type === 'custom' ? <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={() => this.props.addElement(column)} /> : null}
+              {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.props.addElement(column, 'button')} /> : null}
               <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
-              {column.type === 'custom' ? <PasteComponent options={['customCardElement']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
-              {column.type === 'action' ? <PasteComponent options={['action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
-              {column.type === 'custom' || column.type === 'action' ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
+              {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
+              {column.type === 'custom' ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
               <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
               {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
             </div>
@@ -104,13 +103,13 @@
         <th {...restProps} style={style} key={column.uuid} onDoubleClick={() => this.props.editColumn(column)}>
           <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
             <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
-              {['custom', 'colspan'].includes(column.type) ?
-                <PlusOutlined className="plus" title="娣诲姞" onClick={() => this.props.addElement(column)} /> : null
-              }
+              {column.type === 'colspan' ? <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.props.addElement(column)} /> : null}
+              {column.type === 'custom' ? <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={() => this.props.addElement(column)} /> : null}
+              {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.props.addElement(column, 'button')} /> : null}
               <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
-              {column.type === 'custom' ? <PasteComponent options={['customCardElement']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
+              {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
               <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
-              {column && ['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
+              {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
             </div>
           } trigger="hover">
             {children}
@@ -177,12 +176,6 @@
     if (column && column.type === 'custom') {
       return (
         <td style={{padding: 0, ...(column.style || {})}} className={className}>
-          <CardCellComponent cards={config} cardCell={column} elements={column.elements} updateElement={this.updateCard}/>
-        </td>
-      )
-    } else if (column && column.type === 'action') {
-      return (
-        <td style={{padding: 0, textAlign: column.Align, ...(column.style || {})}} className={'action-column ' + className}>
           <CardCellComponent cards={config} cardCell={column} elements={column.elements} updateElement={this.updateCard}/>
         </td>
       )
@@ -301,15 +294,13 @@
     let _columns = fromJS(this.state.columns).toJS()
     let type = item.subType
 
-    if (!['text', 'number', 'textarea', 'custom', 'action', 'formula', 'index', 'colspan'].includes(item.subType)) {
+    if (!['text', 'number', 'textarea', 'custom', 'formula', 'index', 'colspan'].includes(item.subType)) {
       type = 'text'
     }
 
-    let col = { focus: true, uuid: Utils.getuuid(), label: 'label', field: '', type: type, elements: [] }
+    let col = { focus: true, uuid: Utils.getuuid(), Width: 120, label: 'label', field: '', type: type, elements: [] }
     if (col.type === 'colspan') {
       col.subcols = []
-    } else if (col.type === 'action') {
-      col.label = '鎿嶄綔'
     } else if (col.type === 'index') {
       col.label = '搴忓彿'
     }
@@ -364,14 +355,23 @@
   pasteCell = (col, cell, resolve) => {
     resolve({status: true})
     
-    delete cell.copyType
     cell.uuid = Utils.getuuid()
     cell.focus = true
+    
+    if (!cell.eleType) {
+      if (cell.copyType === 'action') {
+        cell.eleType = 'button'
+        cell.width = cell.width || 12
+      } else {
+        cell.eleType = 'text'
+      }
+    }
+    delete cell.copyType
     
     MKEmitter.emit('cardAddElement', col.uuid, cell)
   }
 
-  addElement = (col) => {
+  addElement = (col, type) => {
     let column = fromJS(col).toJS()
 
     if (column.type === 'colspan') {
@@ -384,26 +384,28 @@
       })
       this.updateCol(column)
     } else if (column.type === 'custom') {
-      let newcard = {uuid: Utils.getuuid(), focus: true, width: 24, eleType: 'text', datatype: 'dynamic', style: {paddingLeft: '4px'}}
+      if (type === 'button') {
+        let newcard = {
+          uuid: Utils.getuuid(),
+          focus: true,
+          eleType: 'button',
+          label: 'button',
+          OpenType: 'prompt',
+          class: 'primary',
+          intertype: 'system',
+          execSuccess: 'grid',
+          execError: 'never',
+          show: 'link'
+        }
   
-      // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
-      MKEmitter.emit('cardAddElement', column.uuid, newcard)
-    } else if (column.type === 'action') {
-      let newcard = {
-        uuid: Utils.getuuid(),
-        focus: true,
-        eleType: 'button',
-        label: 'button',
-        OpenType: 'prompt',
-        class: 'primary',
-        intertype: 'system',
-        execSuccess: 'grid',
-        execError: 'never',
-        show: 'link'
+        // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
+        MKEmitter.emit('cardAddElement', column.uuid, newcard)
+      } else {
+        let newcard = {uuid: Utils.getuuid(), focus: true, width: 24, eleType: 'text', datatype: 'dynamic', style: {paddingLeft: '4px'}}
+    
+        // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
+        MKEmitter.emit('cardAddElement', column.uuid, newcard)
       }
-
-      // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
-      MKEmitter.emit('cardAddElement', column.uuid, newcard)
     }
   }
 
@@ -419,9 +421,6 @@
     } else if (col.type === 'custom') {
       col.style = card.style || {}
       col.elements = card.type === 'custom' ? (card.elements || []) : []
-    } else if (col.type === 'action') {
-      col.style = card.style || {}
-      col.elements = card.type === 'action' ? (card.elements || []) : []
     }
 
     window.GLOB.precolumnId = window.GLOB.columnId || ''
diff --git a/src/menu/components/table/edit-table/columns/index.scss b/src/menu/components/table/edit-table/columns/index.scss
index dcf4a5b..613cfb2 100644
--- a/src/menu/components/table/edit-table/columns/index.scss
+++ b/src/menu/components/table/edit-table/columns/index.scss
@@ -74,11 +74,6 @@
         }
       }
     }
-    .action-column {
-      .card-detail-row:empty {
-        min-height: 40px;
-      }
-    }
     tr:hover td {
       background: #ffffff!important;
     }
diff --git a/src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx b/src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx
index b40a192..dd50594 100644
--- a/src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx
+++ b/src/menu/components/table/edit-table/columns/tableIn/customscript/index.jsx
@@ -47,19 +47,37 @@
   }
 
   edit = (record) => {
+    const { type } = this.props
+
     this.setState({
       editItem: record
     })
 
-    this.props.form.setFieldsValue({
-      sql: record.sql,
-      position: record.position || 'back'
-    })
+    if (type === 'fullscreen') {
+      this.props.form.setFieldsValue({
+        sql: record.sql
+      })
+    } else {
+      this.props.form.setFieldsValue({
+        sql: record.sql,
+        position: record.position || 'back'
+      })
+    }
   }
 
   handleConfirm = () => {
+    const { type } = this.props
+    const { editItem } = this.state
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     this.props.form.validateFieldsAndScroll((err, values) => {
+      if (type === 'fullscreen' && err) {
+        notification.warning({
+          top: 92,
+          message: '璇疯緭鍏ql!',
+          duration: 5
+        })
+        return
+      }
       if (!err) {
         if (/^[\s\n]+$/.test(values.sql)) {
           notification.warning({
@@ -71,6 +89,10 @@
         }
         
         values.uuid = this.state.editItem ? this.state.editItem.uuid : ''
+
+        if (type === 'fullscreen' && editItem) {
+          values.status = editItem.status || 'true'
+        }
 
         let _quot = values.sql.match(/'{1}/g)
         let _lparen = values.sql.match(/\({1}/g)
@@ -264,8 +286,8 @@
   }
 
   render() {
-    const { systemScripts, btn } = this.props
-    const { usefulfields } = this.state
+    const { systemScripts, btn, type } = this.props
+    const { usefulfields, editItem } = this.state
     const { getFieldDecorator } = this.props.form
     const formItemLayout = {
       labelCol: {
@@ -278,27 +300,29 @@
       }
     }
 
+    let _type = type || ''
+
     return (
       <Form {...formItemLayout} className="verify-form" id="verify-excelin-custom-scripts">
         <Row gutter={24}>
-          {btn.sheet ? <Col span={8}>
+          {!_type && btn.sheet ? <Col span={8}>
             <Form.Item label={'琛ㄥ悕'} style={{whiteSpace: 'nowrap', margin: 0}}>
               {btn.sheet}
             </Form.Item>
           </Col> : null}
-          <Col span={10}>
+          {!_type ? <Col span={10}>
             <Form.Item label={'鎶ラ敊瀛楁'} style={{margin: 0, whiteSpace: 'nowrap'}}>
               ErrorCode锛堝鍔犲悗缂�NT琛ㄧず鏁版嵁涓嶅洖婊氾紝濡侲NT銆丯NT銆丗NT銆丯MNT锛�, retmsg
             </Form.Item>
-          </Col>
-          {usefulfields ? <Col span={24} className="sqlfield">
+          </Col> : null}
+          {!_type ? <Col span={24} className="sqlfield">
             <Form.Item label={'鍙敤瀛楁'}>
               <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id</span></Tooltip>,&nbsp;
               <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}><span style={{color: '#fa8c16'}}>UserName, FullName, RoleID, mk_departmentcode, mk_organization, mk_user_type, mk_nation, mk_province, mk_city, mk_district, mk_address</span></Tooltip>,&nbsp;
               {usefulfields},data_type锛堟敞锛歫skey涓轰富閿�硷紝鏂板鏃跺墠绔敓鎴愶紱data_type涓烘搷浣滅被鍨嬶紝鏂板 - add銆佷慨鏀� - upt銆佸垹闄� - del锛�
             </Form.Item>
           </Col> : null}
-          <Col span={8} style={{whiteSpace: 'nowrap'}}>
+          {!_type ? <Col span={8} style={{whiteSpace: 'nowrap'}}>
             <Form.Item style={{marginBottom: 0}} label={
               <Tooltip placement="bottomLeft" title={'鑷畾涔夎剼鏈笌榛樿sql浣嶇疆鍏崇郴銆�'}>
                 <QuestionCircleOutlined className="mk-form-tip" />
@@ -315,8 +339,8 @@
                 </Radio.Group>
               )}
             </Form.Item>
-          </Col>
-          <Col span={10}>
+          </Col> : null}
+          {!_type ? <Col span={10}>
             <Form.Item style={{marginBottom: 0}} label={'蹇嵎娣诲姞'}>
               <Select
                 showSearch
@@ -337,10 +361,10 @@
                 )}
               </Select>
             </Form.Item>
-          </Col>
+          </Col> : null}
           <Col span={6} className="add">
             <Button onClick={this.handleConfirm} loading={this.state.loading} className="mk-green" style={{marginBottom: 15, marginLeft: 40}}>
-              淇濆瓨
+              {_type === 'fullscreen' && !editItem ? '娣诲姞' : '淇濆瓨'}
             </Button>
             <Button onClick={this.handleCancel} style={{marginBottom: 15, marginLeft: 10}}>
               鍙栨秷
diff --git a/src/menu/components/table/edit-table/columns/tableIn/index.jsx b/src/menu/components/table/edit-table/columns/tableIn/index.jsx
index e604816..b452acf 100644
--- a/src/menu/components/table/edit-table/columns/tableIn/index.jsx
+++ b/src/menu/components/table/edit-table/columns/tableIn/index.jsx
@@ -2,14 +2,15 @@
 import PropTypes from 'prop-types'
 import { fromJS } from 'immutable'
 import { Form, Tabs, Row, Col, Input, Button, Popconfirm, notification, Modal, message, InputNumber, Radio, Typography } from 'antd'
-import { StopTwoTone, CheckCircleTwoTone, EditOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons'
+import { StopTwoTone, CheckCircleTwoTone, EditOutlined, SwapOutlined, DeleteOutlined, BorderOutlined, CheckCircleOutlined, StopOutlined } from '@ant-design/icons'
 import moment from 'moment'
 
 import Api from '@/api'
 import Utils from '@/utils/utils.js'
-
+import MKEmitter from '@/utils/events.js'
 import UniqueForm from './uniqueform'
 import CustomScript from './customscript'
+import MinView from '@/assets/img/minview.png'
 import asyncComponent from '@/utils/asyncComponent'
 import './index.scss'
 
@@ -25,6 +26,8 @@
   }
 
   state = {
+    visible: false,
+    scriptId: '',
     verify: {},
     fields: [],
     fieldLabel: {},
@@ -125,15 +128,13 @@
         dataIndex: 'position',
         width: '10%',
         render: (text, record) => {
-          let _text = ''
-          if (record.position === 'front') {
-            _text = 'sql鍓�'
-          } else if (record.position === 'init') {
-            _text = '鍒濆鍖�'
+          if (record.position === 'init') {
+            return <span style={{color: 'orange'}}>鍒濆鍖�</span>
+          } else if (record.position === 'front') {
+            return <span style={{color: '#26C281'}}>sql鍓�</span>
           } else {
-            _text = 'sql鍚�'
+            return <span style={{color: '#1890ff'}}>sql鍚�</span>
           }
-          return _text
         }
       },
       {
@@ -322,6 +323,8 @@
       verify.scripts.push(values)
     }
 
+    MKEmitter.emit('editLineId', values.uuid)
+
     this.setState({
       verify: verify
     })
@@ -490,7 +493,7 @@
   }
 
   render() {
-    const { verify, scriptsColumns, uniqueColumns, activeKey, fields } = this.state
+    const { verify, scriptsColumns, uniqueColumns, activeKey, fields, visible } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -579,6 +582,17 @@
               {verify.scripts.length ? <span className="count-tip">{verify.scripts.length}</span> : null}
             </span>
           } key="scripts">
+            <BorderOutlined className="full-scripts" onClick={() => {
+              if (this.scriptsForm && (this.scriptsForm.state.editItem || (this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))))) {
+                notification.warning({
+                  top: 92,
+                  message: '璇蜂繚瀛樿嚜瀹氫箟鑴氭湰锛�',
+                  duration: 5
+                })
+                return
+              }
+              this.setState({visible: true, scriptId: ''})
+            }}/>
             <CustomScript
               btn={verify}
               usefulfields={fields}
@@ -677,6 +691,87 @@
             </Form>
           </TabPane>
         </Tabs>
+        <Modal
+          wrapClassName="model-custom-scripts-modal"
+          title="鑷畾涔夎剼鏈�"
+          visible={visible}
+          width={'95vw'}
+          maskClosable={false}
+          destroyOnClose
+        >
+          <img className="unfull-scripts" src={MinView} onClick={() => this.setState({visible: false, scriptId: ''})} alt=""/>
+          <div className="script-table-wrap">
+            {verify.scripts.map(item => {
+              let title = item.sql.match(/^\s*\/\*.+\*\//)
+              title = title && title[0] ? title[0] : ''
+              let _text = title ? item.sql.replace(title, '') : item.sql
+
+              let position = null
+              if (item.position === 'init') {
+                position = <span style={{color: 'orange'}}>鍒濆鍖�</span>
+              } else if (item.position === 'front') {
+                position = <span style={{color: '#26C281'}}>sql鍓�</span>
+              } else {
+                position = <span style={{color: '#1890ff'}}>sql鍚�</span>
+              }
+
+              if (item.status === 'false') {
+                return (
+                  <div className="script-item" key={item.uuid}>
+                    <div style={{cursor: 'not-allowed'}}>
+                      {title ? <div style={{color: '#a50', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}>{title}</div> : null}
+                      <Paragraph copyable={{ text: item.sql }} ellipsis={{ rows: 4 }}>{_text}</Paragraph>
+                      <div>{position}
+                        <span style={{color: '#ff4d4f', marginLeft: '20px'}}>
+                          绂佺敤
+                          <StopOutlined style={{marginLeft: '5px'}} />
+                        </span>
+                      </div>
+                    </div>
+                    <div style={{height: '24px'}}></div>
+                  </div>
+                )
+              } else {
+                return (
+                  <div className={'script-item ' + (this.state.scriptId === item.uuid ? 'active' : '') } key={item.uuid}>
+                    <div style={{cursor: 'pointer'}} onClick={() => {
+                      this.scriptsFullForm.edit(item)
+                      this.setState({scriptId: item.uuid})
+                    }}>
+                      {title ? <div style={{color: '#a50', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis'}}>{title}</div> : null}
+                      <Paragraph copyable={{ text: item.sql }} ellipsis={{ rows: 4 }}>{_text}</Paragraph>
+                      <div>{position}
+                        <span style={{color: '#26C281', marginLeft: '20px'}}>
+                          鍚敤
+                          <CheckCircleOutlined style={{marginLeft: '5px'}}/>
+                        </span>
+                      </div>
+                    </div>
+                    <div style={{textAlign: 'right'}}>
+                      <span className="operation-btn" onClick={() => this.handleStatus(item, 'scripts')} style={{color: '#8E44AD'}}><SwapOutlined /></span>
+                      <Popconfirm
+                        overlayClassName="popover-confirm"
+                        title="纭畾鍒犻櫎鍚�?"
+                        onConfirm={() => this.handleDelete(item, 'scripts')
+                      }>
+                        <span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span>
+                      </Popconfirm>
+                    </div>
+                  </div>
+                )
+              }
+            })}
+          </div>
+          <CustomScript
+            type="fullscreen"
+            btn={verify}
+            usefulfields={fields}
+            scripts={verify.scripts}
+            systemScripts={this.state.systemScripts}
+            scriptsChange={this.scriptsChange}
+            wrappedComponentRef={(inst) => this.scriptsFullForm = inst}
+          />
+        </Modal>
       </div>
     )
   }
diff --git a/src/menu/components/table/edit-table/columns/tableIn/index.scss b/src/menu/components/table/edit-table/columns/tableIn/index.scss
index 39e908f..737083e 100644
--- a/src/menu/components/table/edit-table/columns/tableIn/index.scss
+++ b/src/menu/components/table/edit-table/columns/tableIn/index.scss
@@ -77,4 +77,142 @@
       z-index: 1;
     }
   }
+  .full-scripts {
+    position: absolute;
+    right: 24px;
+    top: 0px;
+    font-size: 16px;
+    color: #1890ff;
+    z-index: 1;
+  }
+}
+.model-custom-scripts-modal {
+  .ant-modal {
+    top: 30px;
+    .ant-modal-header {
+      padding: 10px 24px;
+    }
+    .ant-modal-footer {
+      display: none;
+    }
+    .ant-modal-close {
+      display: none;
+    }
+    .ant-modal-body {
+      padding: 0;
+      height: calc(100vh - 100px);
+      overflow: hidden;
+      display: flex;
+
+      .script-table-wrap {
+        width: 240px;
+        overflow-y: auto;
+        overflow-x: hidden;
+        height: calc(100vh - 100px);
+
+        .operation-btn {
+          display: inline-block;
+          font-size: 16px;
+          padding: 0 5px;
+          cursor: pointer;
+          margin-left: 5px;
+        }
+
+        .script-item {
+          border-bottom: 1px solid #eeeeee;
+          padding: 15px 10px 5px;
+        }
+        .script-item.active {
+          background-color: #bae7ff;
+        }
+        .ant-typography {
+          margin-bottom: 5px;
+        }
+      }
+
+      .script-table-wrap::-webkit-scrollbar {
+        width: 7px;
+      }
+      .script-table-wrap::-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);
+      }
+      .script-table-wrap::-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);
+      }
+
+      .unfull-scripts {
+        position: absolute;
+        right: 20px;
+        z-index: 2;
+        top: 10px;
+        color: #1890ff;
+        width: 26px;
+        cursor: pointer;
+        padding: 5px;
+    
+      }
+
+      .verify-form {
+        flex: 1;
+        >.ant-row {
+          margin: 0!important;
+          position: unset;
+        }
+        .sql {
+          padding: 0!important;
+          .ant-form-item-label {
+            display: none;
+          }
+          .ant-form-item-control-wrapper {
+            width: 100%;
+          }
+          .CodeMirror {
+            height: calc(100vh - 100px);
+            border-radius: 0;
+          }
+          .code-mirror-area {
+            border-radius: 0;
+            width: calc(95vw - 240px);
+          }
+        }
+        .sqlfield {
+          .ant-form-item {
+            margin-bottom: 5px;
+          }
+          .ant-form-item-control {
+            line-height: 24px;
+          }
+          .ant-form-item-label {
+            line-height: 25px;
+          }
+          .ant-form-item-children {
+            line-height: 22px;
+          }
+          .ant-col-sm-8 {
+            width: 10.5%;
+          }
+          .ant-col-sm-16 {
+            width: 89.5%;
+          }
+        }
+        .add {
+          position: absolute;
+          top: 10px;
+          z-index: 1;
+          .ant-btn {
+            height: 28px;
+          }
+          .mk-green {
+            margin-left: 0!important;
+            margin-right: 10px;
+          }
+        }
+      }
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/menu/components/table/edit-table/index.jsx b/src/menu/components/table/edit-table/index.jsx
index 3cae9f5..6c0dc8d 100644
--- a/src/menu/components/table/edit-table/index.jsx
+++ b/src/menu/components/table/edit-table/index.jsx
@@ -96,11 +96,6 @@
               cell.uuid = Utils.getuuid()
               return cell
             })
-          } else if (col.type === 'action' && col.elements) {
-            col.elements = col.elements.map(cell => {
-              cell.uuid = Utils.getuuid()
-              return cell
-            })
           }
           return col
         })
@@ -220,7 +215,7 @@
   addColumns = () => {
     let card = fromJS(this.state.card).toJS()
 
-    card.cols.push({ focus: true, uuid: Utils.getuuid(), label: 'label', field: '', type: 'text' })
+    card.cols.push({ focus: true, Width: 120, uuid: Utils.getuuid(), label: 'label', field: '', type: 'text' })
 
     this.setState({card})
   }
diff --git a/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx b/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
index 7bf4cd5..e4c73d2 100644
--- a/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
+++ b/src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
@@ -65,13 +65,6 @@
     text: '搴忓彿'
   }]
 
-  if (!card.isSub) {
-    options.push({
-      value: 'action',
-      text: '鎿嶄綔'
-    })
-  }
-
   if (!card.linkurl && (!card.linkmenu || card.linkmenu.length === 0)) {
     card.perspective = ''
   }
@@ -159,6 +152,18 @@
         value: 'false',
         text: '鍚�'
       }]
+    },
+    {
+      type: 'radio',
+      key: 'eval',
+      label: '瑙f瀽',
+      initVal: card.eval || 'false',
+      tooltip: '褰撳叕寮忓唴瀹规秹鍙婅绠楁椂璇烽�夋嫨鈥滄槸鈥濓紝褰撳叕寮忓唴瀹逛负瀛楁鎷兼帴鏃惰閫夋嫨鈥滃惁鈥濄��',
+      required: false,
+      options: [
+        { value: 'true', text: '鏄�' },
+        { value: 'false', text: '鍚�' }
+      ]
     },
     {
       type: 'radio',
@@ -409,18 +414,6 @@
       options: [
         { value: 'blank', text: '鏂扮獥鍙�' },
         { value: 'self', text: '褰撳墠绐楀彛' }
-      ]
-    },
-    {
-      type: 'radio',
-      key: 'eval',
-      label: '瑙f瀽',
-      initVal: card.eval || 'false',
-      tooltip: '褰撳叕寮忓唴瀹规秹鍙婅绠楁椂璇烽�夋嫨鈥滄槸鈥濓紝褰撳叕寮忓唴瀹逛负瀛楁鎷兼帴鏃惰閫夋嫨鈥滃惁鈥濄��',
-      required: false,
-      options: [
-        { value: 'true', text: '鏄�' },
-        { value: 'false', text: '鍚�' }
       ]
     },
     {
diff --git a/src/menu/components/table/normal-table/columns/editColumn/index.jsx b/src/menu/components/table/normal-table/columns/editColumn/index.jsx
index d971c8e..df3913f 100644
--- a/src/menu/components/table/normal-table/columns/editColumn/index.jsx
+++ b/src/menu/components/table/normal-table/columns/editColumn/index.jsx
@@ -25,7 +25,6 @@
 
 class NormalTableColumn extends Component {
   static propTpyes = {
-    visible: PropTypes.bool,
     column: PropTypes.object,
     fields: PropTypes.array,
     submitCol: PropTypes.func,  // 鎻愪氦浜嬩欢
@@ -36,6 +35,8 @@
     visible: false,
     formlist: null
   }
+
+  record = null
 
   UNSAFE_componentWillReceiveProps (nextProps) {
     if (nextProps.column && !is(fromJS(this.props.column), fromJS(nextProps.column))) {
@@ -50,18 +51,16 @@
     })
     
     let formlist = getColumnForm(column, fields)
-    let _options = fromJS(columnTypeOptions[column.type]).toJS()
-    if (column.type === 'text' || column.type === 'number') {
-      if (column.perspective === 'linkmenu') {
-        _options.push('linkmenu', 'linkfields', 'open')
-      } else if (column.perspective === 'linkurl') {
-        _options.push('linkurl', 'linkfields', 'open')
-      }
-    }
+    this.record = {}
+
+    formlist.forEach(item => {
+      this.record[item.key] = item.initVal
+    })
+    
+    let _options = this.getOptions()
 
     this.setState({
       visible: true,
-      type: column.type,
       formlist: formlist.map(item => {
         item.hidden = !_options.includes(item.key)
 
@@ -85,9 +84,29 @@
     }
   }
 
+  getOptions = () => {
+    let _options = fromJS(columnTypeOptions[this.record.type]).toJS()
+
+    if (this.record.type === 'text' || this.record.type === 'number') {
+      if (this.record.perspective === 'linkmenu') {
+        _options.push('linkmenu', 'linkfields', 'open')
+      } else if (this.record.perspective === 'linkurl') {
+        _options.push('linkurl', 'linkfields', 'open')
+      }
+    }
+    
+    if (this.record.type === 'formula' && this.record.eval === 'true') {
+      _options.push('decimal')
+    }
+
+    return _options
+  }
+
   typeChange = (key, value, option) => {
+    this.record[key] = value
+
     if (key === 'type') {
-      let _options = fromJS(columnTypeOptions[value]).toJS()
+      let _options = this.getOptions()
 
       let _field = ''
       if (value === 'formula') {
@@ -95,8 +114,12 @@
       }
 
       this.setState({
-        type: value,
         formlist: this.state.formlist.map(item => {
+          if (item.key === 'decimal' && value === 'formula') {
+            this.record.decimal = ''
+          }
+
+          item.initVal = this.record[item.key]
           item.hidden = !_options.includes(item.key)
 
           return item
@@ -110,8 +133,6 @@
           this.props.form.setFieldsValue({Align: 'center'})
         } else if (value === 'formula' && _field) {
           this.props.form.setFieldsValue({formula: '@' + _field + '@'})
-        } else if (value === 'action') {
-          this.props.form.setFieldsValue({Align: 'center', label: '鎿嶄綔'})
         } else if (value === 'index') {
           this.props.form.setFieldsValue({label: '搴忓彿'})
         }
@@ -129,13 +150,18 @@
         values.type = 'text'
       }
 
-      if (values.type !== this.state.type) {
+      let _type = this.record.type
+      this.record.type = values.type
+
+      if (values.type !== _type) {
         values.perspective = ''
-        let _options = fromJS(columnTypeOptions[values.type]).toJS()
+        this.record.perspective = ''
+
+        let _options = this.getOptions()
 
         this.setState({
-          type: values.type,
           formlist: this.state.formlist.map(item => {
+            item.initVal = this.record[item.key]
             item.hidden = !_options.includes(item.key)
 
             return item
@@ -148,21 +174,12 @@
       }
     } else if (key === 'format' && value === 'percent') {
       this.props.form.setFieldsValue({postfix: '%'})
-    }
-  }
-
-  changeRadio = (key, value) => {
-    if (key === 'perspective') {
-      let _options = fromJS(columnTypeOptions[this.state.type]).toJS()
-
-      if (value === 'linkmenu') {
-        _options.push('linkmenu', 'linkfields', 'open')
-      } else if (value === 'linkurl') {
-        _options.push('linkurl', 'linkfields', 'open')
-      }
+    } else if (['perspective', 'eval'].includes(key)) {
+      let _options = this.getOptions()
 
       this.setState({
         formlist: this.state.formlist.map(item => {
+          item.initVal = this.record[item.key]
           item.hidden = !_options.includes(item.key)
 
           return item
@@ -279,14 +296,10 @@
                   }
                 ]
               })(
-                <Radio.Group onChange={(e) => {this.changeRadio(item.key, e.target.value)}}>
-                  {
-                    item.options.map(option => {
-                      return (
-                        <Radio key={option.value} value={option.value}>{option.text}</Radio>
-                      )
-                    })
-                  }
+                <Radio.Group onChange={(e) => {this.typeChange(item.key, e.target.value)}}>
+                  {item.options.map(option => {
+                    return (<Radio key={option.value} value={option.value}>{option.text}</Radio>)
+                  })}
                 </Radio.Group>
               )}
             </Form.Item>
@@ -406,9 +419,23 @@
   }
 
   handleSubmit = () => {
+    const { fields } = this.props
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     this.props.form.validateFieldsAndScroll((err, values) => {
       if (!err) {
+        // eslint-disable-next-line
+        if (values.type === 'formula' && values.eval !== 'false' && /^[\u4E00-\u9FA50-9a-zA-Z_\s@\+\-\*\/]*$/ig.test(values.formula) && /[\+\-\*\/]/ig.test(values.formula)) {
+          let cols = []
+          fields.forEach(col => {
+            if (/^(Int|Decimal)/ig.test(col.datatype)) {
+              cols.push({reg: new RegExp('@' + col.field + '@', 'ig'), value: `(@${col.field}@)`})
+            }
+          })
+
+          cols.forEach(col => {
+            values.formula = values.formula.replace(col.reg, col.value)
+          })
+        }
         this.setState({visible: false, formlist: null})
         this.props.submitCol(values)
       }
diff --git a/src/menu/components/table/normal-table/columns/index.jsx b/src/menu/components/table/normal-table/columns/index.jsx
index 5362007..47ea9a5 100644
--- a/src/menu/components/table/normal-table/columns/index.jsx
+++ b/src/menu/components/table/normal-table/columns/index.jsx
@@ -3,7 +3,7 @@
 import { is, fromJS } from 'immutable'
 import { DndProvider, DragSource, DropTarget } from 'react-dnd'
 import { Table, Popover, Modal, message, Typography } from 'antd'
-import { PlusOutlined, FileSyncOutlined, EditOutlined, CopyOutlined, DeleteOutlined, FontColorsOutlined, CloseCircleOutlined, AntDesignOutlined } from '@ant-design/icons'
+import { PlusOutlined, PlusSquareOutlined, FileSyncOutlined, EditOutlined, CopyOutlined, DeleteOutlined, FontColorsOutlined, CloseCircleOutlined, AntDesignOutlined } from '@ant-design/icons'
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
@@ -54,7 +54,7 @@
   render() {
     const { connectDragSource, connectDropTarget, moveCol, dropCol, addElement, updateCol, editColumn, pasteCell, changeStyle, deleteCol, index, column, align, fields, children, ...restProps } = this.props
 
-    if (index !== undefined) {
+    if (index !== undefined && column) {
       let style = {cursor: 'move', textAlign: align}
       if (column.Width) {
         style.width = column.Width
@@ -66,18 +66,17 @@
       }
 
       return connectDragSource(
-        connectDropTarget(<th {...restProps} index={index} style={style} onDoubleClick={() => column && this.props.editColumn(column)}>
+        connectDropTarget(<th {...restProps} index={index} style={style} onDoubleClick={() => this.props.editColumn(column)}>
           <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
             <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
-              {column && ['custom', 'colspan', 'action'].includes(column.type) ?
-                <PlusOutlined className="plus" title="娣诲姞" onClick={() => this.props.addElement(column)} /> : null
-              }
+              {column.type === 'colspan' ? <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.props.addElement(column)} /> : null}
+              {column.type === 'custom' ? <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={() => this.props.addElement(column)} /> : null}
+              {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.props.addElement(column, 'button')} /> : null}
               <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
-              {column && column.type === 'custom' ? <PasteComponent options={['customCardElement']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
-              {column && column.type === 'action' ? <PasteComponent options={['action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
-              {column && (column.type === 'custom' || column.type === 'action') ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
+              {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
+              {column.type === 'custom' ? <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={() => this.props.changeStyle(column)}/> : null}
               <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
-              {column && ['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
+              {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
             </div>
           } trigger="hover">
             {children}
@@ -99,13 +98,13 @@
         <th {...restProps} style={style} key={column.uuid} onDoubleClick={() => this.props.editColumn(column)}>
           <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
             <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
-              {column && ['custom', 'colspan'].includes(column.type) ?
-                <PlusOutlined className="plus" title="娣诲姞" onClick={() => this.props.addElement(column)} /> : null
-              }
+              {column.type === 'colspan' ? <PlusOutlined className="plus" title="娣诲姞鍒�" onClick={() => this.props.addElement(column)} /> : null}
+              {column.type === 'custom' ? <PlusOutlined className="plus" title="娣诲姞鍏冪礌" onClick={() => this.props.addElement(column)} /> : null}
+              {column.type === 'custom' ? <PlusSquareOutlined className="plus" title="娣诲姞鎸夐挳" onClick={() => this.props.addElement(column, 'button')} /> : null}
               <EditOutlined className="edit" title="缂栬緫" onClick={() => this.props.editColumn(column)} />
-              {column.type === 'custom' ? <PasteComponent options={['customCardElement']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
+              {column.type === 'custom' ? <PasteComponent options={['customCardElement', 'action']} updateConfig={(res, resolve) => this.props.pasteCell(column, res, resolve)} /> : null}
               <DeleteOutlined className="close" title="鍒犻櫎" onClick={this.deleteCol} />
-              {column && ['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
+              {['text', 'number', 'formula'].includes(column.type) ? <MarkColumn field={column.field || ''} columns={fields} marks={column.marks} onSubmit={this.updateMarks} /> : null }
             </div>
           } trigger="hover">
             {children}
@@ -174,12 +173,6 @@
     if (column && column.type === 'custom') {
       return (
         <td style={{padding: 0, ...(column.style || {})}} className={className}>
-          <CardCellComponent cards={config} cardCell={column} elements={column.elements} updateElement={this.updateCard}/>
-        </td>
-      )
-    } else if (column && column.type === 'action') {
-      return (
-        <td style={{padding: 0, textAlign: column.Align, ...(column.style || {})}} className={'action-column ' + className}>
           <CardCellComponent cards={config} cardCell={column} elements={column.elements} updateElement={this.updateCard}/>
         </td>
       )
@@ -300,8 +293,6 @@
     let col = { focus: true, uuid: Utils.getuuid(), label: 'label', field: '', type: item.subType, elements: [] }
     if (col.type === 'colspan') {
       col.subcols = []
-    } else if (col.type === 'action') {
-      col.label = '鎿嶄綔'
     } else if (col.type === 'index') {
       col.label = '搴忓彿'
     }
@@ -355,18 +346,25 @@
 
   pasteCell = (col, cell, resolve) => {
     resolve({status: true})
-    if (cell.copyType === 'action') {
-      cell.eleType = 'button'
+    
+    cell.uuid = Utils.getuuid()
+    cell.focus = true
+
+    if (!cell.eleType) {
+      if (cell.copyType === 'action') {
+        cell.eleType = 'button'
+        cell.width = cell.width || 12
+      } else {
+        cell.eleType = 'text'
+      }
     }
 
     delete cell.copyType
-    cell.uuid = Utils.getuuid()
-    cell.focus = true
     
     MKEmitter.emit('cardAddElement', col.uuid, cell)
   }
 
-  addElement = (col) => {
+  addElement = (col, type) => {
     let column = fromJS(col).toJS()
 
     if (column.type === 'colspan') {
@@ -379,26 +377,28 @@
       })
       this.updateCol(column)
     } else if (column.type === 'custom') {
-      let newcard = {uuid: Utils.getuuid(), focus: true, width: 24, eleType: 'text', datatype: 'dynamic', style: {paddingLeft: '4px'}}
+      if (type === 'button') {
+        let newcard = {
+          uuid: Utils.getuuid(),
+          focus: true,
+          eleType: 'button',
+          label: 'button',
+          OpenType: 'prompt',
+          class: 'primary',
+          intertype: 'system',
+          execSuccess: 'grid',
+          execError: 'never',
+          show: 'link'
+        }
   
-      // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
-      MKEmitter.emit('cardAddElement', column.uuid, newcard)
-    } else if (column.type === 'action') {
-      let newcard = {
-        uuid: Utils.getuuid(),
-        focus: true,
-        eleType: 'button',
-        label: 'button',
-        OpenType: 'prompt',
-        class: 'primary',
-        intertype: 'system',
-        execSuccess: 'grid',
-        execError: 'never',
-        show: 'link'
+        // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
+        MKEmitter.emit('cardAddElement', column.uuid, newcard)
+      } else {
+        let newcard = {uuid: Utils.getuuid(), focus: true, width: 24, eleType: 'text', datatype: 'dynamic', style: {paddingLeft: '4px'}}
+    
+        // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
+        MKEmitter.emit('cardAddElement', column.uuid, newcard)
       }
-
-      // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
-      MKEmitter.emit('cardAddElement', column.uuid, newcard)
     }
   }
 
@@ -414,9 +414,6 @@
     } else if (col.type === 'custom') {
       col.style = card.style || {}
       col.elements = card.type === 'custom' ? (card.elements || []) : []
-    } else if (col.type === 'action') {
-      col.style = card.style || {}
-      col.elements = card.type === 'action' ? (card.elements || []) : []
     }
 
     window.GLOB.precolumnId = window.GLOB.columnId || ''
diff --git a/src/menu/components/table/normal-table/columns/index.scss b/src/menu/components/table/normal-table/columns/index.scss
index b420128..af1deb4 100644
--- a/src/menu/components/table/normal-table/columns/index.scss
+++ b/src/menu/components/table/normal-table/columns/index.scss
@@ -62,11 +62,6 @@
         }
       }
     }
-    .action-column {
-      .card-detail-row:empty {
-        min-height: 40px;
-      }
-    }
     tr:hover td {
       background: #ffffff!important;
     }
diff --git a/src/menu/components/table/normal-table/index.jsx b/src/menu/components/table/normal-table/index.jsx
index f4d4917..2934bd9 100644
--- a/src/menu/components/table/normal-table/index.jsx
+++ b/src/menu/components/table/normal-table/index.jsx
@@ -106,11 +106,6 @@
               cell.uuid = Utils.getuuid()
               return cell
             })
-          } else if (col.type === 'action' && col.elements) {
-            col.elements = col.elements.map(cell => {
-              cell.uuid = Utils.getuuid()
-              return cell
-            })
           }
           return col
         })
@@ -324,8 +319,13 @@
     let _actions = [...action]
 
     cols.forEach(col => {
-      if (col.type !== 'action') return
-      _actions.push(...col.elements)
+      if (col.type === 'custom') {
+        col.elements.forEach(cell => {
+          if (cell.eleType !== 'button') return
+
+          _actions.push(cell)
+        })
+      }
     })
 
     return getWrapForm(wrap, _actions, columns)
diff --git a/src/menu/modulecell/index.jsx b/src/menu/modulecell/index.jsx
index b8841a6..e88c740 100644
--- a/src/menu/modulecell/index.jsx
+++ b/src/menu/modulecell/index.jsx
@@ -100,8 +100,7 @@
           { subType: 'custom', text: '鑷畾涔夊垪', type: 'col', $init: true },
           { subType: 'colspan', text: '鍚堝苟鍒�', type: 'col', $init: true },
           { subType: 'formula', text: '鍏紡', type: 'col', $init: true },
-          { subType: 'index', text: '搴忓彿', type: 'col', $init: true },
-          { subType: 'action', text: '鎿嶄綔', type: 'col', $init: true }
+          { subType: 'index', text: '搴忓彿', type: 'col', $init: true }
         ]
       }
     ]
diff --git a/src/menu/modulesource/option.jsx b/src/menu/modulesource/option.jsx
index 262dfbe..e79babd 100644
--- a/src/menu/modulesource/option.jsx
+++ b/src/menu/modulesource/option.jsx
@@ -30,7 +30,7 @@
 import mindmap from '@/assets/mobimg/mindmap.png'
 import indent from '@/assets/mobimg/indent.jfif'
 import kapmap from '@/assets/mobimg/kapmap.jfif'
-import xflow from '@/assets/mobimg/xflow.png'
+// import xflow from '@/assets/mobimg/xflow.png'
 import Voucher from '@/assets/mobimg/voucher.png'
 import Account from '@/assets/mobimg/account.png'
 
@@ -66,7 +66,7 @@
   { type: 'menu', url: mindmap, component: 'antvG6', subtype: 'mindmap', title: '鎬濈淮瀵煎浘', width: 24 },
   { type: 'menu', url: indent, component: 'antvG6', subtype: 'indentTree', title: '缂╄繘鏂囦欢鏍�', width: 24 },
   { type: 'menu', url: kapmap, component: 'antvG6', subtype: 'kapmap', title: '鐭ヨ瘑鍥捐氨鏍�', width: 24 },
-  { type: 'menu', url: xflow, component: 'antvX6', subtype: 'xflow', title: '娴佺▼鍥�', width: 24 },
+  // { type: 'menu', url: xflow, component: 'antvX6', subtype: 'xflow', title: '娴佺▼鍥�', width: 24 },
   { type: 'menu', url: chart, component: 'chart', subtype: 'custom', title: '鑷畾涔夊浘琛�', width: 24, forbid: ['billPrint'] },
   { type: 'menu', url: Editor, component: 'editor', subtype: 'brafteditor', title: '瀵屾枃鏈�', width: 24 },
   { type: 'menu', url: SandBox, component: 'code', subtype: 'sandbox', title: '鑷畾涔�', width: 24 },
diff --git a/src/menu/replaceField/index.jsx b/src/menu/replaceField/index.jsx
index 93a303e..df1506a 100644
--- a/src/menu/replaceField/index.jsx
+++ b/src/menu/replaceField/index.jsx
@@ -358,34 +358,32 @@
           if (item.cols) {
             let _update = (cols) => {
               return cols.map(col => {
-                if (col.type === 'action' && col.elements) {
+                if (col.type === 'custom' && col.elements) {
                   col.elements = col.elements.map(m => {
-                    if (m.modal && m.modal.fields) {
-                      m.modal.fields = m.modal.fields.map(col => {
-                        if (col.field && map[col.field.toLowerCase()]) {
-                          col.field = map[col.field.toLowerCase()].FieldName
-                        }
-                        return col
-                      })
-                    }
-                    if (m.verify && m.verify.columns) {
-                      m.verify.columns = m.verify.columns.map(col => {
-                        if (col.Column && map[col.Column.toLowerCase()]) {
-                          col.Column = map[col.Column.toLowerCase()].FieldName
-                        }
-                        return col
-                      })
-                    }
-                    if (m.config && m.config.components) {
-                      m.config.components = _replace(m.config.components)
-                    }
-
-                    return m
-                  })
-                } else if (col.type === 'custom' && col.elements) {
-                  col.elements = col.elements.map(m => {
-                    if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
-                      m.field = map[m.field.toLowerCase()].FieldName
+                    if (m.eleType === 'button') {
+                      if (m.modal && m.modal.fields) {
+                        m.modal.fields = m.modal.fields.map(col => {
+                          if (col.field && map[col.field.toLowerCase()]) {
+                            col.field = map[col.field.toLowerCase()].FieldName
+                          }
+                          return col
+                        })
+                      }
+                      if (m.verify && m.verify.columns) {
+                        m.verify.columns = m.verify.columns.map(col => {
+                          if (col.Column && map[col.Column.toLowerCase()]) {
+                            col.Column = map[col.Column.toLowerCase()].FieldName
+                          }
+                          return col
+                        })
+                      }
+                      if (m.config && m.config.components) {
+                        m.config.components = _replace(m.config.components)
+                      }
+                    } else {
+                      if (m.datatype === 'dynamic' && map[m.field.toLowerCase()]) {
+                        m.field = map[m.field.toLowerCase()].FieldName
+                      }
                     }
 
                     return m
@@ -532,26 +530,28 @@
           if (item.cols) {
             let _update = (cols) => {
               return cols.map(col => {
-                if (col.type === 'action' && col.elements) {
+                if (col.type === 'custom' && col.elements) {
                   col.elements = col.elements.map(m => {
-                    if (m.modal && m.modal.fields) {
-                      m.modal.fields = m.modal.fields.map(col => {
-                        if (col.field && map[col.field.toLowerCase()]) {
-                          col.label = map[col.field.toLowerCase()].FieldDec
-                        }
-                        return col
-                      })
-                    }
-                    if (m.verify && m.verify.columns) {
-                      m.verify.columns = m.verify.columns.map(col => {
-                        if (col.Column && map[col.Column.toLowerCase()]) {
-                          col.Text = map[col.Column.toLowerCase()].FieldDec
-                        }
-                        return col
-                      })
-                    }
-                    if (m.config && m.config.components) {
-                      m.config.components = _replace(m.config.components)
+                    if (m.eleType === 'button') {
+                      if (m.modal && m.modal.fields) {
+                        m.modal.fields = m.modal.fields.map(col => {
+                          if (col.field && map[col.field.toLowerCase()]) {
+                            col.label = map[col.field.toLowerCase()].FieldDec
+                          }
+                          return col
+                        })
+                      }
+                      if (m.verify && m.verify.columns) {
+                        m.verify.columns = m.verify.columns.map(col => {
+                          if (col.Column && map[col.Column.toLowerCase()]) {
+                            col.Text = map[col.Column.toLowerCase()].FieldDec
+                          }
+                          return col
+                        })
+                      }
+                      if (m.config && m.config.components) {
+                        m.config.components = _replace(m.config.components)
+                      }
                     }
 
                     return m
diff --git a/src/menu/transfer/index.jsx b/src/menu/transfer/index.jsx
index 4456af7..6eeecbf 100644
--- a/src/menu/transfer/index.jsx
+++ b/src/menu/transfer/index.jsx
@@ -85,7 +85,7 @@
           })
           tab.components[0].cols = tab.components[0].cols.filter(col => !(col.field && col.Hide === 'true'))
           tab.components[0].cols.forEach(col => {
-            if (col.type !== 'action') return
+            if (col.type !== 'custom') return
             col.elements.forEach(btn => {
               if (btn.OpenType === 'popview' && btn.config) {
                 btn.config.Template = 'CustomPage'
@@ -111,7 +111,7 @@
         })
         item.cols = item.cols.filter(col => !(col.field && col.Hide === 'true'))
         item.cols.forEach(col => {
-          if (col.type !== 'action') return
+          if (col.type !== 'custom') return
           col.elements.forEach(btn => {
             if (btn.OpenType === 'popview' && btn.config) {
               btn.config.Template = 'CustomPage'
diff --git a/src/tabviews/basetable/index.jsx b/src/tabviews/basetable/index.jsx
index e6a783a..816de31 100644
--- a/src/tabviews/basetable/index.jsx
+++ b/src/tabviews/basetable/index.jsx
@@ -316,6 +316,8 @@
             return false
           } else if (col.Hide === 'true') {
             return false
+          } else if (col.type === 'action') {
+            col.type = 'custom'
           }
           
           if (col.type === 'number') {
@@ -334,8 +336,39 @@
               return false
             }
           } else if (col.type === 'custom') {
-            col.elements = col.elements.map(cell => {
-              if (['text', 'number', 'formula'].includes(cell.eleType)) {
+            col.elements = col.elements.filter(cell => {
+              if (cell.eleType === 'button') {
+                if (cell.hidden === 'true') return false
+          
+                cell.logLabel = item.$menuname + '-' + cell.label
+                cell.Ot = cell.Ot || 'requiredSgl'
+                cell.ContainerId = this.state.ContainerId
+                cell.syncComponentId = cell.syncComponent ? (cell.syncComponent.pop() || '') : ''
+                cell.$menuId = item.uuid
+                cell.$MenuID = this.props.MenuID
+                cell.$view = 'popview'
+
+                if (cell.syncComponentId === item.setting.supModule) {
+                  cell.syncComponentId = ''
+                  if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
+                    cell.execSuccess = 'mainline'
+                  }
+                }
+
+                if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) { // 鎵撳嵃鏈鸿缃�
+                  cell = this.getPrinter(cell, item.uuid)
+                }
+
+                if (cell.controlField) {
+                  if (/,/ig.test(cell.controlVal)) {
+                    cell.controlVals = cell.controlVal.split(',')
+                  } else {
+                    cell.controlVals = [(cell.controlVal || '')]
+                  }
+                }
+
+                return skip || permAction[cell.uuid]
+              } else if (['text', 'number', 'formula'].includes(cell.eleType)) {
                 if (!cell.height) {
                   cell.innerHeight = 'auto'
                 }
@@ -346,8 +379,12 @@
                   }
                 }
               }
-              return cell
+              return true
             })
+
+            if (col.elements.length === 0) {
+              return false
+            }
           }
     
           if (col.linkmenu && col.linkmenu.length > 0) {
@@ -399,43 +436,6 @@
           return skip || permAction[cell.uuid]
         })
       }
-
-      item.cols = item.cols.filter(col => {
-        if (col.type !== 'action') return true
-        col.elements = col.elements.filter(cell => {
-          if (cell.hidden === 'true') return false
-          
-          cell.logLabel = item.$menuname + '-' + cell.label
-          cell.Ot = cell.Ot || 'requiredSgl'
-          cell.ContainerId = this.state.ContainerId
-          cell.syncComponentId = cell.syncComponent ? (cell.syncComponent.pop() || '') : ''
-          cell.$menuId = item.uuid
-          cell.$MenuID = this.props.MenuID
-          cell.$view = 'popview'
-
-          if (cell.syncComponentId === item.setting.supModule) {
-            cell.syncComponentId = ''
-            if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
-              cell.execSuccess = 'mainline'
-            }
-          }
-
-          if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) { // 鎵撳嵃鏈鸿缃�
-            cell = this.getPrinter(cell, item.uuid)
-          }
-
-          if (cell.controlField) {
-            if (/,/ig.test(cell.controlVal)) {
-              cell.controlVals = cell.controlVal.split(',')
-            } else {
-              cell.controlVals = [(cell.controlVal || '')]
-            }
-          }
-
-          return skip || permAction[cell.uuid]
-        })
-        return col.elements.length !== 0
-      })
       
       return true
     })
diff --git a/src/tabviews/custom/components/card/cardcellList/index.jsx b/src/tabviews/custom/components/card/cardcellList/index.jsx
index 4c7985a..450e8e9 100644
--- a/src/tabviews/custom/components/card/cardcellList/index.jsx
+++ b/src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -757,6 +757,10 @@
                 // eslint-disable-next-line
                 _val = eval(_val)
               } catch (e) {
+                if (window.debugger) {
+                  console.info(_val)
+                  console.warn(e)
+                }
                 _val = 0
               }
             }
@@ -779,6 +783,10 @@
               // eslint-disable-next-line
               _val = eval(_val)
             } catch (e) {
+              if (window.debugger) {
+                console.info(_val)
+                console.warn(e)
+              }
               _val = ''
             }
           }
@@ -789,6 +797,11 @@
         if (!val && card.noValue === 'hide') { // 绌哄�奸殣钘�
           return null
         }
+
+        if (card.round && typeof(val) === 'number') {
+          val = Math.round(val * card.round) / card.round
+          val = val.toFixed(card.decimal)
+        }
   
         if (val !== '') {
           if (val && typeof(val) === 'string') {
diff --git a/src/tabviews/custom/components/module/voucher/index.jsx b/src/tabviews/custom/components/module/voucher/index.jsx
index d08ab38..f11d8c0 100644
--- a/src/tabviews/custom/components/module/voucher/index.jsx
+++ b/src/tabviews/custom/components/module/voucher/index.jsx
@@ -609,7 +609,7 @@
           sup_data.push(`'${n.uuid}','${item.subject_voucher_code || ''}','${item.voucher_lp || ''}','${n.voucher_sup_lp || ''}','${item.subject_code}','${item.subject_name}','${n.sup_voucher_text || ''}','${direct}',${item.debit || item.credit},'${n.customercode || ''}','${n.customername || ''}','${n.suppliercode || ''}','${n.suppliername || ''}','${n.co_pro_code || ''}','${n.co_pro_name || ''}','${n.workercode || ''}','${n.workername || ''}','${n.project_code || ''}','${n.project_name || ''}','${n.productcode || ''}','${n.productname || ''}','${n.cash_flow_code || ''}','${n.cash_flow_name || ''}','${n.sup_acc_code || ''}','${n.sup_acc_name || ''}','${n.sup_acc_type || ''}','${item.uuid}',0,'${n.lessor_code || ''}','${n.lessor_name || ''}','${n.logistics_code || ''}','${n.logistics_name || ''}'`)
         })
       }
-      return `'${item.uuid}','${item.subject_voucher_code || ''}','${item.voucher_lp || ''}','${item.subject_code}','${item.subject_name}','${item.subject_voucher_text || ''}',${count ? item.fcc_count || 0 : 0},${count ? item.net_unitprice || 0 : 0},'${item.unit}',${item.debit || item.credit},'${direct}','${curr ? item.exratecode : '01010001'}','${curr ? item.exratename : 'CNY'}',${curr ? item.unitratio || 0 : 0},'${item.sup_accounting}',${item.debit ? 1 : -1},${curr ? item.foreign_amount || 0 : 0},0,'${item.local_currency || ''}','${count ? 'Y' : ''}','${curr ? 'Y' : ''}'`
+      return `'${item.uuid}','${item.subject_voucher_code || ''}','${item.voucher_lp || ''}','${item.subject_code}','${item.subject_name}','${item.subject_voucher_text || ''}',${count ? item.fcc_count || 0 : 0},${count ? item.net_unitprice || 0 : 0},'${item.unit}',${item.debit || item.credit},'${direct}','${curr ? item.exratecode : '01010001'}','${curr ? item.exratename : 'CNY'}',${curr ? item.unitratio || 0 : 0},'${item.sup_accounting}',${item.debit ? 1 : -1},${curr ? item.foreign_amount || 0 : 0},0,'${item.local_currency || ''}','${count ? 'Y' : ''}','${curr ? 'Y' : ''}','${item.closing_foreign_exchange || ''}'`
     })
 
     if (type === 'createVoucher') {
@@ -625,7 +625,7 @@
       let curr = item.foreign_currency_type === 'Y'
       let direct = item.debit ? 'debit' : 'credit'
 
-      subject_data.push(`'${item.uuid}','${item.subject_voucher_code || ''}','${item.voucher_lp || ''}','${item.subject_code}','${item.subject_name}','${item.subject_voucher_text || ''}',${count ? item.fcc_count || 0 : 0},${count ? item.net_unitprice || 0 : 0},'${item.unit}',${item.debit || item.credit},'${direct}','${curr ? item.exratecode : '01010001'}','${curr ? item.exratename : 'CNY'}',${curr ? item.unitratio || 0 : 0},'${item.sup_accounting}',${item.debit ? 1 : -1},${curr ? item.foreign_amount || 0 : 0},1,'${item.local_currency || ''}','${count ? 'Y' : ''}','${curr ? 'Y' : ''}'`)
+      subject_data.push(`'${item.uuid}','${item.subject_voucher_code || ''}','${item.voucher_lp || ''}','${item.subject_code}','${item.subject_name}','${item.subject_voucher_text || ''}',${count ? item.fcc_count || 0 : 0},${count ? item.net_unitprice || 0 : 0},'${item.unit}',${item.debit || item.credit},'${direct}','${curr ? item.exratecode : '01010001'}','${curr ? item.exratename : 'CNY'}',${curr ? item.unitratio || 0 : 0},'${item.sup_accounting}',${item.debit ? 1 : -1},${curr ? item.foreign_amount || 0 : 0},1,'${item.local_currency || ''}','${count ? 'Y' : ''}','${curr ? 'Y' : ''}','${item.closing_foreign_exchange || ''}'`)
     })
 
     supMap.forEach(n => {
@@ -893,7 +893,7 @@
           sup_data.push(`'${n.uuid}','${item.subject_voucher_code || ''}','${item.voucher_lp || ''}','${n.voucher_sup_lp || ''}','${item.subject_code}','${item.subject_name}','${n.sup_voucher_text || ''}','${direct}',${item.debit || item.credit || 0},'${n.customercode || ''}','${n.customername || ''}','${n.suppliercode || ''}','${n.suppliername || ''}','${n.co_pro_code || ''}','${n.co_pro_name || ''}','${n.workercode || ''}','${n.workername || ''}','${n.project_code || ''}','${n.project_name || ''}','${n.productcode || ''}','${n.productname || ''}','${n.cash_flow_code || ''}','${n.cash_flow_name || ''}','${n.sup_acc_code || ''}','${n.sup_acc_name || ''}','${n.sup_acc_type || ''}','${item.uuid}',0,'${n.lessor_code || ''}','${n.lessor_name || ''}','${n.logistics_code || ''}','${n.logistics_name || ''}'`)
         })
       }
-      return `'${item.uuid}','${item.subject_voucher_code || ''}','${item.voucher_lp || ''}','${item.subject_code}','${item.subject_name}','${item.subject_voucher_text || ''}',${count ? item.fcc_count || 0 : 0},${count ? item.net_unitprice || 0 : 0},'${item.unit}',${item.debit || item.credit || 0},'${direct}','${curr ? item.exratecode : '01010001'}','${curr ? item.exratename : 'CNY'}',${curr ? item.unitratio || 0 : 0},'${item.sup_accounting}',${item.direct ? 1 : -1},${curr ? item.foreign_amount || 0 : 0},0,'${item.local_currency || ''}','${count ? 'Y' : ''}','${curr ? 'Y' : ''}'`
+      return `'${item.uuid}','${item.subject_voucher_code || ''}','${item.voucher_lp || ''}','${item.subject_code}','${item.subject_name}','${item.subject_voucher_text || ''}',${count ? item.fcc_count || 0 : 0},${count ? item.net_unitprice || 0 : 0},'${item.unit}',${item.debit || item.credit || 0},'${direct}','${curr ? item.exratecode : '01010001'}','${curr ? item.exratename : 'CNY'}',${curr ? item.unitratio || 0 : 0},'${item.sup_accounting}',${item.direct ? 1 : -1},${curr ? item.foreign_amount || 0 : 0},0,'${item.local_currency || ''}','${count ? 'Y' : ''}','${curr ? 'Y' : ''}','${item.closing_foreign_exchange || ''}'`
     })
 
     voucherMap.forEach(item => {
@@ -901,7 +901,7 @@
       let curr = item.foreign_currency_type === 'Y'
       let direct = !item.credit ? 'debit' : 'credit'
 
-      subject_data.push(`'${item.uuid}','${item.subject_voucher_code || ''}','${item.voucher_lp || ''}','${item.subject_code}','${item.subject_name}','${item.subject_voucher_text || ''}',${count ? item.fcc_count || 0 : 0},${count ? item.net_unitprice || 0 : 0},'${item.unit}',${item.debit || item.credit || 0},'${direct}','${curr ? item.exratecode : '01010001'}','${curr ? item.exratename : 'CNY'}',${curr ? item.unitratio || 0 : 0},'${item.sup_accounting}',${item.direct ? 1 : -1},${curr ? item.foreign_amount || 0 : 0},1,'${item.local_currency || ''}','${count ? 'Y' : ''}','${curr ? 'Y' : ''}'`)
+      subject_data.push(`'${item.uuid}','${item.subject_voucher_code || ''}','${item.voucher_lp || ''}','${item.subject_code}','${item.subject_name}','${item.subject_voucher_text || ''}',${count ? item.fcc_count || 0 : 0},${count ? item.net_unitprice || 0 : 0},'${item.unit}',${item.debit || item.credit || 0},'${direct}','${curr ? item.exratecode : '01010001'}','${curr ? item.exratename : 'CNY'}',${curr ? item.unitratio || 0 : 0},'${item.sup_accounting}',${item.direct ? 1 : -1},${curr ? item.foreign_amount || 0 : 0},1,'${item.local_currency || ''}','${count ? 'Y' : ''}','${curr ? 'Y' : ''}','${item.closing_foreign_exchange || ''}'`)
     })
 
     supMap.forEach(n => {
diff --git a/src/tabviews/custom/components/share/normalTable/index.jsx b/src/tabviews/custom/components/share/normalTable/index.jsx
index 33d8d9b..4922254 100644
--- a/src/tabviews/custom/components/share/normalTable/index.jsx
+++ b/src/tabviews/custom/components/share/normalTable/index.jsx
@@ -340,7 +340,16 @@
           // eslint-disable-next-line
           content = eval(content)
         } catch (e) {
+          if (window.debugger) {
+            console.info(content)
+            console.warn(e)
+          }
           content = ''
+        }
+
+        if (col.round && typeof(content) === 'number') {
+          content = Math.round(content * col.round) / col.round
+          content = content.toFixed(col.decimal)
         }
       }
 
@@ -375,14 +384,6 @@
         style = {...style, ...col.style}
       }
 
-      resProps.children = (
-        <CardCellComponent data={record} cards={config} elements={col.elements}/>
-      )
-    } else if (col.type === 'action') {
-      style.padding = '0px'
-      if (col.style) {
-        style = {...style, ...col.style}
-      }
       resProps.children = (
         <CardCellComponent data={record} cards={config} elements={col.elements}/>
       )
@@ -477,7 +478,7 @@
               onCell: record => ({
                 record,
                 col: item,
-                config: item.type === 'custom' || item.type === 'action' ? {setting, columns: fields} : null,
+                config: item.type === 'custom' ? {setting, columns: fields} : null,
                 triggerLink: this.triggerLink
               })
             }
diff --git a/src/tabviews/custom/components/table/edit-table/index.jsx b/src/tabviews/custom/components/table/edit-table/index.jsx
index d0802d5..ad11edd 100644
--- a/src/tabviews/custom/components/table/edit-table/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/index.jsx
@@ -92,8 +92,9 @@
           if (item.subcols.length === 0) {
             return false
           }
-        } else if (item.type === 'action') {
+        } else if (item.type === 'custom') {
           item.elements.forEach(btn => {
+            if (btn.eleType !== 'button') return
             if (btn.funcType === 'addline') {
               setting.addable = true
             }
diff --git a/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx b/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
index fe8a4d0..36e29df 100644
--- a/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
+++ b/src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
@@ -429,7 +429,7 @@
             val = ''
           }
           return (<td className="editing_table_cell">
-            <InputNumber className={err ? 'has-error' : ''} title={err} id={col.uuid + record.$$uuid} defaultValue={val} onChange={(val) => this.onChange(val)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
+            <InputNumber className={err ? 'has-error' : ''} precision={col.decimal || 0} title={err} id={col.uuid + record.$$uuid} defaultValue={val} onChange={(val) => this.onChange(val)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
           </td>)
         } else {
           return (<td className={className + ' pointer'} style={style}>
@@ -466,6 +466,10 @@
           // eslint-disable-next-line
           content = eval(content)
         } catch (e) {
+          if (window.debugger) {
+            console.info(content)
+            console.warn(e)
+          }
           content = ''
         }
       }
@@ -474,6 +478,11 @@
 
       if (col.noValue === 'hide' && content === 0) {
         content = ''
+      }
+
+      if (col.round && typeof(content) === 'number') {
+        content = Math.round(content * col.round) / col.round
+        content = content.toFixed(col.decimal)
       }
 
       if (content !== '') {
@@ -505,14 +514,6 @@
         style = {...style, ...col.style}
       }
 
-      children = (
-        <CardCellComponent data={record} cards={config} elements={col.elements}/>
-      )
-    } else if (col.type === 'action') {
-      style.padding = '0px'
-      if (col.style) {
-        style = {...style, ...col.style}
-      }
       children = (
         <CardCellComponent data={record} cards={config} elements={col.elements}/>
       )
@@ -786,7 +787,7 @@
         }
 
         children = (<>
-          <InputNumber className={err ? 'has-error' : ''} title={err} id={col.uuid + record.$$uuid} defaultValue={_value} onChange={(val) => this.onChange(val)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
+          <InputNumber className={err ? 'has-error' : ''} title={err} precision={col.decimal || 0} id={col.uuid + record.$$uuid} defaultValue={_value} onChange={(val) => this.onChange(val)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
         </>)
       } else {
         let content = ''
@@ -866,6 +867,10 @@
           // eslint-disable-next-line
           content = eval(content)
         } catch (e) {
+          if (window.debugger) {
+            console.info(content)
+            console.warn(e)
+          }
           content = ''
         }
       }
@@ -874,6 +879,11 @@
 
       if (col.noValue === 'hide' && content === 0) {
         content = ''
+      }
+
+      if (col.round && typeof(content) === 'number') {
+        content = Math.round(content * col.round) / col.round
+        content = content.toFixed(col.decimal)
       }
 
       if (content !== '') {
@@ -905,14 +915,6 @@
         style = {...style, ...col.style}
       }
 
-      children = (
-        <CardCellComponent data={record} cards={config} elements={col.elements}/>
-      )
-    } else if (col.type === 'action') {
-      style.padding = '0px'
-      if (col.style) {
-        style = {...style, ...col.style}
-      }
       children = (
         <CardCellComponent data={record} cards={config} elements={col.elements}/>
       )
@@ -1010,7 +1012,7 @@
             onCell: record => ({
               record,
               col: item,
-              config: item.type === 'custom' || item.type === 'action' ? {setting, columns: fields} : null,
+              config: item.type === 'custom' ? {setting, columns: fields} : null,
             })
           }
         }
diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx
index 1ddc4d0..bf7075e 100644
--- a/src/tabviews/custom/index.jsx
+++ b/src/tabviews/custom/index.jsx
@@ -473,53 +473,6 @@
         item.search = Utils.initSearchVal(item.search)
       }
 
-      if (item.type === 'table') {
-        let statFields = []
-        let getCols = (cols) => {
-          return cols.filter(col => {
-            if (col.blacklist && col.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) {
-              return false
-            } else if (col.Hide === 'true') {
-              return false
-            }
-            
-            if (col.type === 'number') {
-              if (col.sum === 'true' && !statFields.includes(col.field)) {
-                statFields.push(col)
-              }
-              if (typeof(col.decimal) === 'number') {
-                col.round = Math.pow(10, col.decimal)
-                if (col.format === 'percent') {
-                  col.decimal = col.decimal > 2 ? col.decimal - 2 : 0
-                }
-              }
-            } else if (col.type === 'colspan') {
-              col.subcols = getCols(col.subcols || [])
-              if (col.subcols.length === 0) {
-                return false
-              }
-            } else if (col.type === 'custom') {
-              col.elements = col.elements.map(cell => {
-                cell = this.resetElement(cell)
-                return cell
-              })
-            }
-      
-            if (col.linkmenu && col.linkmenu.length > 0) {
-              let menu_id = col.linkmenu.pop()
-              col.linkThdMenu = window.GLOB.mkThdMenus.filter(m => m.MenuID === menu_id)[0] || ''
-            } else {
-              col.linkThdMenu = ''
-            }
-
-            return true
-          })
-        }
-        
-        item.cols = getCols(item.cols)
-        item.statFields = statFields
-      }
-
       let mutil = false
       if (item.wrap && item.wrap.supType === 'multi') { // 鏁版嵁鍗″涓婄骇缁勪欢
         mutil = true
@@ -557,7 +510,86 @@
         })
       }
 
-      if (item.type === 'card' || item.type === 'carousel' || item.type === 'timeline') {
+      if (item.type === 'table') {
+        let statFields = []
+        let getCols = (cols) => {
+          return cols.filter(col => {
+            if (col.blacklist && col.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) {
+              return false
+            } else if (col.Hide === 'true') {
+              return false
+            } else if (col.type === 'action') {
+              col.type = 'custom'
+            }
+            
+            if (col.type === 'number') {
+              if (col.sum === 'true' && !statFields.includes(col.field)) {
+                statFields.push(col)
+              }
+              if (typeof(col.decimal) === 'number') {
+                col.round = Math.pow(10, col.decimal)
+                if (col.format === 'percent') {
+                  col.decimal = col.decimal > 2 ? col.decimal - 2 : 0
+                }
+              }
+            } else if (col.type === 'formula') {
+              if (typeof(col.decimal) === 'number') {
+                col.round = Math.pow(10, col.decimal)
+              }
+            } else if (col.type === 'colspan') {
+              col.subcols = getCols(col.subcols || [])
+              if (col.subcols.length === 0) {
+                return false
+              }
+            } else if (col.type === 'custom') {
+              col.elements = col.elements.filter(cell => {
+                if (cell.eleType === 'button') {
+                  if (cell.hidden === 'true') return false
+
+                  cell = this.resetButton(item, cell, popview)
+
+                  if (cell.syncComponentId === item.setting.supModule) {
+                    cell.syncComponentId = ''
+                    if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
+                      cell.execSuccess = 'mainline'
+                    }
+                  }
+
+                  if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) { // 鎵撳嵃鏈鸿缃�
+                    cell = this.getPrinter(cell, item.uuid)
+                  }
+
+                  return skip || permAction[cell.uuid]
+                } else {
+                  cell = this.resetElement(cell)
+                }
+                return true
+              })
+
+              if (col.elements.length === 0) {
+                return false
+              }
+            }
+      
+            if (col.linkmenu && col.linkmenu.length > 0) {
+              let menu_id = col.linkmenu.pop()
+              col.linkThdMenu = window.GLOB.mkThdMenus.filter(m => m.MenuID === menu_id)[0] || ''
+            } else {
+              col.linkThdMenu = ''
+            }
+
+            return true
+          })
+        }
+        
+        item.cols = getCols(item.cols)
+        item.statFields = statFields
+
+        if (item.subtype === 'editable') {
+          item.submit.logLabel = item.$menuname + '-鎻愪氦'
+          item.submit.$menuId = item.uuid
+        }
+      } else if (item.type === 'card' || item.type === 'carousel' || item.type === 'timeline') {
         item.subcards && item.subcards.forEach(card => {
           if (card.style.boxShadow) {
             delete card.style.hShadow
@@ -644,34 +676,6 @@
 
           return cell.eleType !== 'button' || skip || permAction[cell.uuid]
         })
-      } else if (item.type === 'table') {
-        item.cols = item.cols.filter(col => {
-          if (col.type !== 'action') return true
-          col.elements = col.elements.filter(cell => {
-            if (cell.hidden === 'true') return false
-
-            cell = this.resetButton(item, cell, popview)
-
-            if (cell.syncComponentId === item.setting.supModule) {
-              cell.syncComponentId = ''
-              if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
-                cell.execSuccess = 'mainline'
-              }
-            }
-
-            if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) { // 鎵撳嵃鏈鸿缃�
-              cell = this.getPrinter(cell, item.uuid)
-            }
-
-            return skip || permAction[cell.uuid]
-          })
-          return col.elements.length !== 0
-        })
-
-        if (item.subtype === 'editable') {
-          item.submit.logLabel = item.$menuname + '-鎻愪氦'
-          item.submit.$menuId = item.uuid
-        }
       } else if (item.type === 'form') {
         item.subcards = item.subcards.map(group => {
           group.subButton.uuid = group.uuid
@@ -805,6 +809,8 @@
         if (cell.format === 'percent') {
           cell.decimal = cell.decimal > 2 ? cell.decimal - 2 : 0
         }
+      } else if (cell.eleType === 'formula' && typeof(cell.decimal) === 'number') {
+        cell.round = Math.pow(10, cell.decimal)
       }
     } else if (cell.eleType === 'icon') {
       if (!cell.innerHeight) { // 鍏煎
diff --git a/src/tabviews/custom/popview/index.jsx b/src/tabviews/custom/popview/index.jsx
index a48c356..6dccc71 100644
--- a/src/tabviews/custom/popview/index.jsx
+++ b/src/tabviews/custom/popview/index.jsx
@@ -302,53 +302,6 @@
         item.search = Utils.initSearchVal(item.search)
       }
 
-      if (item.type === 'table') {
-        let statFields = []
-        let getCols = (cols) => {
-          return cols.filter(col => {
-            if (col.blacklist && col.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) {
-              return false
-            } else if (col.Hide === 'true') {
-              return false
-            }
-            
-            if (col.type === 'number') {
-              if (col.sum === 'true' && !statFields.includes(col.field)) {
-                statFields.push(col)
-              }
-              if (typeof(col.decimal) === 'number') {
-                col.round = Math.pow(10, col.decimal)
-                if (col.format === 'percent') {
-                  col.decimal = col.decimal > 2 ? col.decimal - 2 : 0
-                }
-              }
-            } else if (col.type === 'colspan') {
-              col.subcols = getCols(col.subcols || [])
-              if (col.subcols.length === 0) {
-                return false
-              }
-            } else if (col.type === 'custom') {
-              col.elements = col.elements.map(cell => {
-                cell = this.resetElement(cell)
-                return cell
-              })
-            }
-      
-            if (col.linkmenu && col.linkmenu.length > 0) {
-              let menu_id = col.linkmenu.pop()
-              col.linkThdMenu = window.GLOB.mkThdMenus.filter(m => m.MenuID === menu_id)[0] || ''
-            } else {
-              col.linkThdMenu = ''
-            }
-
-            return true
-          })
-        }
-        
-        item.cols = getCols(item.cols)
-        item.statFields = statFields
-      }
-
       let mutil = false
       if (item.wrap && item.wrap.supType === 'multi') { // 鏁版嵁鍗″涓婄骇缁勪欢
         mutil = true
@@ -381,7 +334,81 @@
         })
       }
 
-      if (item.type === 'card' || item.type === 'carousel' || item.type === 'timeline') {
+      if (item.type === 'table') {
+        let statFields = []
+        let getCols = (cols) => {
+          return cols.filter(col => {
+            if (col.blacklist && col.blacklist.filter(v => roleId.indexOf(v) > -1).length > 0) {
+              return false
+            } else if (col.Hide === 'true') {
+              return false
+            } else if (col.type === 'action') {
+              col.type = 'custom'
+            }
+            
+            if (col.type === 'number') {
+              if (col.sum === 'true' && !statFields.includes(col.field)) {
+                statFields.push(col)
+              }
+              if (typeof(col.decimal) === 'number') {
+                col.round = Math.pow(10, col.decimal)
+                if (col.format === 'percent') {
+                  col.decimal = col.decimal > 2 ? col.decimal - 2 : 0
+                }
+              }
+            } else if (col.type === 'formula') {
+              if (typeof(col.decimal) === 'number') {
+                col.round = Math.pow(10, col.decimal)
+              }
+            } else if (col.type === 'colspan') {
+              col.subcols = getCols(col.subcols || [])
+              if (col.subcols.length === 0) {
+                return false
+              }
+            } else if (col.type === 'custom') {
+              col.elements = col.elements.filter(cell => {
+                if (cell.eleType === 'button') {
+                  if (cell.hidden === 'true' || cell.OpenType === 'popview') return false
+            
+                  cell = this.resetButton(item, cell, Tab)
+
+                  if (cell.syncComponentId === item.setting.supModule) {
+                    cell.syncComponentId = ''
+                    if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
+                      cell.execSuccess = 'mainline'
+                    }
+                  }
+                } else {
+                  cell = this.resetElement(cell)
+                }
+
+                return true
+              })
+
+              if (col.elements.length === 0) {
+                return false
+              }
+            }
+      
+            if (col.linkmenu && col.linkmenu.length > 0) {
+              let menu_id = col.linkmenu.pop()
+              col.linkThdMenu = window.GLOB.mkThdMenus.filter(m => m.MenuID === menu_id)[0] || ''
+            } else {
+              col.linkThdMenu = ''
+            }
+
+            return true
+          })
+        }
+        
+        item.cols = getCols(item.cols)
+        item.statFields = statFields
+
+        if (item.subtype === 'editable') {
+          item.submit.logLabel = item.$menuname + '-鎻愪氦'
+          item.submit.$menuId = item.uuid
+        }
+      } else if (item.type === 'card' || item.type === 'carousel' || item.type === 'timeline') {
         item.subcards && item.subcards.forEach(card => {
           if (card.style.boxShadow) {
             delete card.style.hShadow
@@ -456,30 +483,6 @@
 
           return true
         })
-      } else if (item.type === 'table') {
-        item.cols = item.cols.filter(col => {
-          if (col.type !== 'action') return true
-          col.elements = col.elements.filter(cell => {
-            if (cell.hidden === 'true' || cell.OpenType === 'popview') return false
-            
-            cell = this.resetButton(item, cell, Tab)
-
-            if (cell.syncComponentId === item.setting.supModule) {
-              cell.syncComponentId = ''
-              if (cell.execSuccess === 'line' || cell.execSuccess === 'grid') {
-                cell.execSuccess = 'mainline'
-              }
-            }
-
-            return true
-          })
-          return col.elements.length !== 0
-        })
-
-        if (item.subtype === 'editable') {
-          item.submit.logLabel = item.$menuname + '-鎻愪氦'
-          item.submit.$menuId = item.uuid
-        }
       } else if (item.type === 'form') {
         item.subcards = item.subcards.map(group => {
           group.subButton.uuid = group.uuid
@@ -605,6 +608,8 @@
         if (cell.format === 'percent') {
           cell.decimal = cell.decimal > 2 ? cell.decimal - 2 : 0
         }
+      } else if (cell.type === 'formula' && typeof(cell.decimal) === 'number') {
+        cell.round = Math.pow(10, cell.decimal)
       }
     } else if (cell.eleType === 'icon') {
       if (!cell.innerHeight) { // 鍏煎
diff --git a/src/tabviews/zshare/actionList/normalbutton/index.jsx b/src/tabviews/zshare/actionList/normalbutton/index.jsx
index 6416c17..457964c 100644
--- a/src/tabviews/zshare/actionList/normalbutton/index.jsx
+++ b/src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -2125,7 +2125,7 @@
     param.secretkey = Utils.encrypt(param.LText, param.timestamp)
 
     Api.genericInterface(param).then(res => {
-      // res.send_data = [{openid: 'o2E7gvoSFvQRG7I8_gZxf4y3ONkQ', send_id: '222333344', first: '鎮ㄧ殑缂磋垂淇℃伅濡備笅', keyword1: '010000000001', keyword2: '2022骞�07鏈�03鏃�', keyword3: '渚涙殩缂磋垂', keyword4: '20鍏�', keyword5: '鎴愬姛', remark: '鎰熻阿鎮ㄧ殑浣跨敤锛�'}]
+      // res.send_data = [{openid: 'o2E7gvoSFvQRG7I8_gZxf4y3ONkQ', send_id: '245dd33344', first: '鎮ㄧ殑缂磋垂淇℃伅濡備笅', p1: '010000000001', p2: '2022骞�07鏈�03鏃�', p3: '渚涙殩缂磋垂', p4: '20鍏�', p5: '鎴愬姛', remark: '鎰熻阿鎮ㄧ殑浣跨敤锛�'}]
       if (!res.status) {
         notification.warning({
           top: 92,
@@ -2162,7 +2162,7 @@
       }
       
       verify.wxNoteKeys.forEach(item => {
-        _param.data[item.key] = {value: '', color: item.color}
+        _param.data[item.key] = {value: '', color: '#000000'}
       })
 
       let params = sends.map(item => {
diff --git a/src/tabviews/zshare/settingcomponent/index.jsx b/src/tabviews/zshare/settingcomponent/index.jsx
index 70fbc77..c3c366a 100644
--- a/src/tabviews/zshare/settingcomponent/index.jsx
+++ b/src/tabviews/zshare/settingcomponent/index.jsx
@@ -143,29 +143,36 @@
             })
           })
         } else if (item.type === 'table') {
-          item.cols && item.cols.forEach(col => {
-            if (col.type !== 'action') return
-            col.elements && col.elements.forEach(cell => {
-              cell.$expanded = false
-              if (cell.OpenType === 'funcbutton' && cell.funcType === 'print') {
+          let loopCol = (cols) => {
+            cols.forEach(col => {
+              if (col.type === 'colspan') {
+                loopCol(col.subcols)
+              } else if (col.type === 'custom') {
+                col.elements.forEach(cell => {
+                  if (cell.eleType !== 'button') return
+                  cell.$expanded = false
+                  if (cell.OpenType === 'funcbutton' && cell.funcType === 'print') {
 
-                cell.$port = cell.verify ? cell.verify.linkUrl : ''
-                if (cell.verify && cell.verify.printerTypeList && cell.verify.printerTypeList.length > 0) {
-                  cell.verify.printerTypeList = cell.verify.printerTypeList.map(_cell => {
-                    _cell.uuid = _cell.uuid || _cell.key
-                    _cell.parentId = cell.uuid
-                    _cell.$port = cell.$port
+                    cell.$port = cell.verify ? cell.verify.linkUrl : ''
+                    if (cell.verify && cell.verify.printerTypeList && cell.verify.printerTypeList.length > 0) {
+                      cell.verify.printerTypeList = cell.verify.printerTypeList.map(_cell => {
+                        _cell.uuid = _cell.uuid || _cell.key
+                        _cell.parentId = cell.uuid
+                        _cell.$port = cell.$port
 
-                    return _cell
-                  })
-                  cell.$expanded = true
-                }
-                printbtns.push(cell)
+                        return _cell
+                      })
+                      cell.$expanded = true
+                    }
+                    printbtns.push(cell)
+                  }
+
+                  _comp.action.push({...cell, $line: true, ...(userConfig[cell.uuid] || {})})
+                })
               }
-
-              _comp.action.push({...cell, $line: true, ...(userConfig[cell.uuid] || {})})
             })
-          })
+          }
+          loopCol(item.cols)
         } 
         
         if (_comp.action.length > 0) {
diff --git a/src/templates/comtableconfig/updatetable/index.jsx b/src/templates/comtableconfig/updatetable/index.jsx
index 0523a29..e2a7d87 100644
--- a/src/templates/comtableconfig/updatetable/index.jsx
+++ b/src/templates/comtableconfig/updatetable/index.jsx
@@ -279,8 +279,9 @@
                 }
               })
               tab.components[0].cols.forEach(col => {
-                if (col.type !== 'action') return
+                if (col.type !== 'custom') return
                 col.elements.forEach(btn => {
+                  if (btn.eleType !== 'button') return
                   if (btn.OpenType === 'popview') {
                     if (menus[btn.uuid]) {
                       let mainTb = {name: '涓昏〃', uuid: Utils.getuuid(), useMSearch: 'false'}
@@ -330,8 +331,9 @@
               }
             })
             item.cols.forEach(col => {
-              if (col.type !== 'action') return
+              if (col.type !== 'custom') return
               col.elements.forEach(btn => {
+                if (btn.eleType !== 'button') return
                 if (btn.OpenType === 'popview') {
                   if (menus[btn.uuid]) {
                     let mainTb = {name: '涓昏〃', uuid: Utils.getuuid(), useMSearch: 'false'}
@@ -450,8 +452,9 @@
                 }
               })
               tab.components[0].cols.forEach(col => {
-                if (col.type !== 'action') return
+                if (col.type !== 'custom') return
                 col.elements.forEach(btn => {
+                  if (btn.eleType !== 'button') return
                   if (btn.OpenType === 'popview' && btn.config && btn.config.components[0]) {
                     this.setTbForm(btn.config.components[0], menus, errors, tab.components[0].name + '-' + btn.label)
                   } else if (btn.OpenType === 'pop' || (btn.OpenType === 'funcbutton' && btn.funcType === 'print' && btn.execMode === 'pop')) {
@@ -487,8 +490,9 @@
               }
             })
             item.cols.forEach(col => {
-              if (col.type !== 'action') return
+              if (col.type !== 'custom') return
               col.elements.forEach(btn => {
+                if (btn.eleType !== 'button') return
                 if (btn.OpenType === 'popview' && btn.config && btn.config.components[0]) {
                   this.setTbForm(btn.config.components[0], menus, errors, item.name + '-' + btn.label)
                 } else if (btn.OpenType === 'pop' || (btn.OpenType === 'funcbutton' && btn.funcType === 'print' && btn.execMode === 'pop')) {
@@ -531,8 +535,9 @@
       }
     })
     item.cols.forEach(col => {
-      if (col.type !== 'action') return
+      if (col.type !== 'custom') return
       col.elements.forEach(btn => {
+        if (btn.eleType !== 'button') return
         if (btn.OpenType === 'pop' || (btn.OpenType === 'funcbutton' && btn.funcType === 'print' && btn.execMode === 'pop')) {
           if (menus[btn.uuid]) {
             btn.modal = {
@@ -580,8 +585,9 @@
             }
           })
           tab.components[0].cols.forEach(col => {
-            if (col.type !== 'action') return
+            if (col.type !== 'custom') return
             col.elements.forEach(btn => {
+              if (btn.eleType !== 'button') return
               if (btn.OpenType === 'popview' && btn.config) {
                 btn.config.$tables = getTables(btn.config.components[0])
               }
@@ -597,8 +603,9 @@
           }
         })
         item.cols.forEach(col => {
-          if (col.type !== 'action') return
+          if (col.type !== 'custom') return
           col.elements.forEach(btn => {
+            if (btn.eleType !== 'button') return
             if (btn.OpenType === 'popview' && btn.config) {
               btn.config.$tables = getTables(btn.config.components[0])
             }
@@ -1169,7 +1176,7 @@
         marks: [],
         isSub: false,
         uuid: Utils.getuuid(),
-        type: 'action',
+        type: 'custom',
         Width: 120,
         elements: colbtns,
         style: {paddingTop: '12px', paddingLeft: '8px', paddingBottom: '12px', paddingRight: '8px'}
@@ -1237,10 +1244,10 @@
     })
 
     _card.cols.forEach(col => {
-      if (col.type !== 'action') return
+      if (col.type !== 'custom') return
 
       col.elements.forEach(cell => {
-        if (cell.hidden === 'true') return
+        if (cell.hidden === 'true' || cell.eleType !== 'button') return
         if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
           if (!cell.modal || cell.modal.fields.length === 0) {
             _card.errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
diff --git a/src/templates/zshare/codemirror/index.scss b/src/templates/zshare/codemirror/index.scss
index 737e334..bcd1d5a 100644
--- a/src/templates/zshare/codemirror/index.scss
+++ b/src/templates/zshare/codemirror/index.scss
@@ -117,6 +117,16 @@
     bottom: 20px;
   }
 }
+.model-custom-scripts-modal .code-mirror-wrap:not(.mk-fullscreen), .model-custom-view-scripts-modal .code-mirror-wrap:not(.mk-fullscreen) {
+  .anticon-swap {
+    position: absolute;
+    z-index: 11;
+    left: auto;
+    right: 10px;
+    top: auto;
+    bottom: 20px;
+  }
+}
 .mk-mirror-font {
   z-index: 1200!important;
 }
\ No newline at end of file
diff --git a/src/templates/zshare/verifycard/baseform/index.jsx b/src/templates/zshare/verifycard/baseform/index.jsx
index a0f5892..7910852 100644
--- a/src/templates/zshare/verifycard/baseform/index.jsx
+++ b/src/templates/zshare/verifycard/baseform/index.jsx
@@ -5,10 +5,7 @@
 import { QuestionCircleOutlined } from '@ant-design/icons'
 
 import Api from '@/api'
-import asyncComponent from '@/utils/asyncComponent'
 import './index.scss'
-
-const ColorSketch = asyncComponent(() => import('@/mob/colorsketch'))
 
 class BillCodeForm extends Component {
   static propTpyes = {
@@ -26,7 +23,6 @@
   }
 
   componentDidMount() {
-    const { verify } = this.props
     let wxTemps = sessionStorage.getItem('wxTemplates')
 
     if (window.GLOB.WXAppID && window.GLOB.nginx && !wxTemps) {
@@ -38,21 +34,22 @@
           Api.wxNginxRequest(`cgi-bin/template/get_all_private_template?access_token=${wxtoken}`, 'get').then(res => {
             let temps = []
             if (res.template_list) {
-              temps = res.template_list.filter(item => item.primary_industry)
-              let selectTemp = temps.filter(item => item.template_id === verify.wxTemplateId)[0]
+              temps = res.template_list.filter(item => {
+                if (!item.primary_industry) return false
+                if (item.content) {
+                  item.content = item.content.replace('{{first.DATA}}\n', '').replace('\n{{remark.DATA}}', '')
+                }
 
-              if (selectTemp) {
-                selectTemp.content = selectTemp.content.replace(/\r\n|\n/g, '<br/>')
-                selectTemp.example = selectTemp.example.replace(/\r\n|\n/g, '<br/>')
-              }
-
-              this.setState({wxTemps: temps, selectTemp})
+                return true
+              })
             }
-
+            
             sessionStorage.setItem('wxTemplates', JSON.stringify(temps))
             localStorage.setItem('wxTemplates', JSON.stringify(temps))
 
             localStorage.removeItem('wxTemplates')
+
+            this.resetTemps(temps)
           })
         } else {
           sessionStorage.setItem('wxTemplates', JSON.stringify([]))
@@ -75,15 +72,27 @@
     } else if (wxTemps) {
       wxTemps = JSON.parse(wxTemps)
 
-      let selectTemp = wxTemps.filter(item => item.template_id === verify.wxTemplateId)[0]
-
-      if (selectTemp) {
-        selectTemp.content = selectTemp.content.replace(/\r\n|\n/g, '<br/>')
-        selectTemp.example = selectTemp.example.replace(/\r\n|\n/g, '<br/>')
-      }
-  
-      this.setState({wxTemps, selectTemp})
+      this.resetTemps(wxTemps)
     }
+  }
+
+  resetTemps = (wxTemps) => {
+    const { verify } = this.props
+
+    let sysTemps = [{"template_id":"UdGBwbjFKnIBzW2TalsdJkwZ9R2LvaAozWZ-yo2Dn00","title":"缂磋垂閫氱煡","primary_industry":"IT绉戞妧","deputy_industry":"IT杞欢涓庢湇鍔�","content":"{{first.DATA}}\n鍙楃悊缂栧彿锛歿{keyword1.DATA}}\n缂磋垂鏃堕棿锛歿{keyword2.DATA}}\n缂磋垂绫诲埆锛歿{keyword3.DATA}}\n缂磋垂閲戦锛歿{keyword4.DATA}}\n缂磋垂缁撴灉锛歿{keyword5.DATA}}\n{{remark.DATA}}","example":"鎮ㄧ殑缂磋垂淇℃伅濡備笅\r\n鍙楃悊缂栧彿锛�010000000001\r\n缂磋垂鏃堕棿锛�2018骞�07鏈�23鏃r\n缂磋垂绫诲埆锛氫緵鏆栫即璐筡r\n缂磋垂閲戦锛�20鍏僜r\n缂磋垂缁撴灉锛氭垚鍔焅r\n鎰熻阿鎮ㄧ殑浣跨敤锛�"}]
+    
+    sysTemps = []
+
+    let _wxTemps = [...wxTemps, ...sysTemps]
+
+    let selectTemp = _wxTemps.filter(item => item.template_id === verify.wxTemplateId)[0]
+
+    if (selectTemp) {
+      selectTemp.content = selectTemp.content.replace(/\r\n|\n/g, '<br/>')
+      selectTemp.example = selectTemp.example.replace(/\r\n|\n/g, '<br/>')
+    }
+
+    this.setState({wxTemps: _wxTemps, selectTemp})
   }
 
   handleConfirm = () => {
@@ -165,21 +174,10 @@
 
     let index = 1
     _verify.wxNoteKeys = keys.map(key => {
-      let item = {
-        key: key,
-        color: '#000000',
-        readonly: false
-      }
-      if (key === 'first') {
-        item.value = 'first'
-        item.readonly = true
-      } else if (key === 'remark') {
-        item.value = 'remark'
-        item.readonly = true
-      } else {
-        item.value = 'p' + index
-        index++
-      }
+      let item = { key: key }
+      
+      item.value = 'p' + index
+      index++
 
       return item
     })
@@ -195,20 +193,6 @@
     _verify.wxNoteKeys = _verify.wxNoteKeys.map(m => {
       if (m.key === key) {
         m.value = val
-      }
-
-      return m
-    })
-
-    this.props.onChange(_verify)
-  }
-
-  onWxNoteColorChange = (key, val) => {
-    let _verify = fromJS(this.props.verify).toJS()
-
-    _verify.wxNoteKeys = _verify.wxNoteKeys.map(m => {
-      if (m.key === key) {
-        m.color = val
       }
 
       return m
@@ -413,9 +397,9 @@
               <Input placeholder="" autoComplete="off" value={verify.wxNoteLinkMenuId || ''} onChange={(e) => {this.onOptionChange(e.target.value, 'wxNoteLinkMenuId')}}/>
             </Form.Item>
           </Col> : null}
-          {verify.wxNote === 'true' && verify.wxNoteKeys ? verify.wxNoteKeys.map(item => <Col span={8} key={item.key}>
-            <Form.Item className="mk-note-keyword" label={item.key} required>
-              <Select value={item.value} disabled={item.readonly} onSelect={(val) => this.onWxNoteKeyChange(item.key, val)}>
+          {verify.wxNote === 'true' && verify.wxNoteKeys ? verify.wxNoteKeys.map((item, index) => <Col span={8} key={'mk' + index}>
+            <Form.Item label={item.key} required>
+              <Select value={item.value} onSelect={(val) => this.onWxNoteKeyChange(item.key, val)}>
                 <Select.Option value="p1">p1</Select.Option>
                 <Select.Option value="p2">p2</Select.Option>
                 <Select.Option value="p3">p3</Select.Option>
@@ -427,7 +411,6 @@
                 <Select.Option value="p9">p9</Select.Option>
                 <Select.Option value="p10">p10</Select.Option>
               </Select>
-              <ColorSketch value={item.color || '#ffffff'} onChange={(val, hex) => {this.onWxNoteColorChange(item.key, hex)}} />
             </Form.Item>
           </Col>) : null}
           {selectTemp && verify.wxNoteKeys ? <Col span={24} className="wx-note">
@@ -449,7 +432,7 @@
                 <div>
                   <p>openid:&nbsp;&nbsp;"鎺ユ敹鑰卭penid",</p>
                   <p>send_id:&nbsp;&nbsp;"闃查噸鍏d",</p>
-                  {verify.wxNoteKeys.map(item => <p>{item.value}:&nbsp;&nbsp;"=&gt; {item.key}",</p>)}
+                  {verify.wxNoteKeys.map((item, i) => <p key={'index' + i}>{item.value}:&nbsp;&nbsp;"=&gt; {item.key}",</p>)}
                   <p>bid:&nbsp;&nbsp;"璺宠浆灏忕▼搴忔椂锛屽彲浣滀负BID銆�"</p>
                 </div>
               </div>
diff --git a/src/templates/zshare/verifycard/baseform/index.scss b/src/templates/zshare/verifycard/baseform/index.scss
index 4cd6283..8625b9f 100644
--- a/src/templates/zshare/verifycard/baseform/index.scss
+++ b/src/templates/zshare/verifycard/baseform/index.scss
@@ -1,29 +1,3 @@
-.mk-note-keyword {
-  .ant-select {
-    width: 50%;
-    .ant-select-selection {
-      border-radius: 4px 0px 0px 4px;
-    }
-  }
-  .color-sketch-block {
-    width: 50%;
-    display: inline-block;
-    vertical-align: top;
-    position: relative;
-    top: 4px;
-    .color-sketch-block-box {
-      width: calc(100% - 75px);
-      height: 32px;
-      border-radius: 0px 4px 4px 0px;
-      .color-sketch-block-inner {
-        border-radius: 0px 4px 4px 0px;
-      }
-    }
-    .color-sketch-value {
-      width: 75px;
-    }
-  }
-}
 .wx-note {
   display: flex;
   .note-wrap {
diff --git a/src/utils/utils-custom.js b/src/utils/utils-custom.js
index 9763056..2fde239 100644
--- a/src/utils/utils-custom.js
+++ b/src/utils/utils-custom.js
@@ -517,73 +517,40 @@
           })
         }
       } else if (item.type === 'table' && item.cols) {
-        let loopCol = (col) => {
-          col.subcols = col.subcols.map(c => {
-            c.uuid = md5(commonId + c.uuid)
-  
-            if (c.type === 'colspan' && c.subcols) {
-              c = loopCol(c)
-            } else if (c.type === 'custom' && c.elements) {
-              c.elements = c.elements.map(cell => {
-                cell.uuid = this.getuuid()
+        let loopCol = (cols) => {
+          return cols.map(col => {
+            if (col.type === 'action') {
+              col.type = 'custom'
+            }
 
-                return cell
-              })
-            } else if (c.type === 'action' && c.elements) {
-              c.elements = c.elements.map(cell => {
+            col.uuid = md5(commonId + col.uuid)
+  
+            if (col.type === 'colspan' && col.subcols) {
+              col.subcols = loopCol(col.subcols)
+            } else if (col.type === 'custom' && col.elements) {
+              col.elements = col.elements.map(cell => {
                 cell.uuid = md5(commonId + cell.uuid)
 
-                if (clear && cell.pageTemplate === 'linkpage' && cell.linkmenu) {
-                  cell.pageTemplate = ''
-                  cell.linkmenu = ''
-                }
+                if (cell.eleType === 'button') {
+                  if (clear && cell.pageTemplate === 'linkpage' && cell.linkmenu) {
+                    cell.pageTemplate = ''
+                    cell.linkmenu = ''
+                  }
 
-                this.resetBtn(cell, commonId)
+                  this.resetBtn(cell, commonId)
+                }
 
                 return cell
               })
-            }
-            return c
-          })
-  
-          return col
-        }
-
-        item.cols = item.cols.map(col => {
-          col.uuid = md5(commonId + col.uuid)
-  
-          if (col.type === 'colspan' && col.subcols) {
-            col = loopCol(col)
-          } else if (col.type === 'custom' && col.elements) {
-            col.elements = col.elements.map(cell => {
-              cell.uuid = this.getuuid()
-              return cell
-            })
-          } else if (col.type === 'action' && col.elements) {
-            col.elements = col.elements.map(cell => {
-              cell.uuid = md5(commonId + cell.uuid)
-              this.resetBtn(cell, commonId)
-              return cell
-            })
-          }
-          return col
-        })
-
-        if (item.subtype === 'editable') {
-          item.cols = item.cols.map(col => {
-            if (col.editable === 'true' && col.enter) {
+            } else if (col.editable === 'true' && col.enter) {
               col.enter = md5(commonId + col.enter)
-            } else if (col.type === 'colspan' && col.subcols) {
-              col.subcols = col.subcols.map(c => {
-                if (c.editable === 'true' && c.enter) {
-                  c.enter = md5(commonId + c.enter)
-                }
-                return c
-              })
             }
+
             return col
           })
         }
+
+        item.cols = loopCol(item.cols)
       } else if (item.type === 'form') {
         item.subcards = item.subcards.map(cell => {
           cell.uuid = this.getuuid()
@@ -831,63 +798,43 @@
         })
       }
     } else if (item.type === 'table' && item.cols) {
-      let loopCol = (col) => {
-        col.subcols = col.subcols.map(c => {
-          c.uuid = this.getuuid()
+      let loopCol = (cols) => {
+        return cols.map(col => {
+          if (col.type === 'action') {
+            col.type = 'custom'
+          }
 
-          if (c.type === 'colspan' && c.subcols) {
-            c = loopCol(c)
-          } else if (c.type === 'custom' && c.elements) {
-            c.elements = c.elements.map(cell => {
-              cell.uuid = this.getuuid()
+          col.uuid = md5(commonId + col.uuid)
+
+          if (col.type === 'colspan' && col.subcols) {
+            col.subcols = loopCol(col.subcols)
+          } else if (col.type === 'custom' && col.elements) {
+            if (sessionStorage.getItem('editMenuType') === 'popview') {
+              col.elements = col.elements.filter(c => c.eleType !== 'button' || (c.OpenType !== 'popview' && c.OpenType !== 'funcbutton'))
+            }
+            col.elements = col.elements.map(cell => {
+              cell.uuid = md5(commonId + cell.uuid)
+              if (cell.eleType === 'button') {
+                if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+                  if (cell.modal && cell.modal.fields.length > 0) {
+                    cell.modal.fields = cell.modal.fields.map(m => {
+                      m.uuid = this.getuuid()
+                      return m
+                    })
+                  }
+                }
+              }
               return cell
             })
-          }
-          return c
-        })
-
-        return col
-      }
-
-      item.cols = item.cols.map(col => {
-        col.uuid = md5(commonId + col.uuid)
-
-        if (col.type === 'colspan' && col.subcols) {
-          col = loopCol(col)
-        } else if (col.type === 'custom' && col.elements) {
-          col.elements = col.elements.map(cell => {
-            cell.uuid = this.getuuid()
-            return cell
-          })
-        } else if (col.type === 'action' && col.elements) {
-          if (sessionStorage.getItem('editMenuType') === 'popview') {
-            col.elements = col.elements.filter(c => c.OpenType !== 'popview' && c.OpenType !== 'funcbutton')
-          }
-          col.elements = col.elements.map(cell => {
-            cell.uuid = md5(commonId + cell.uuid)
-            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-              if (cell.modal && cell.modal.fields.length > 0) {
-                cell.modal.fields = cell.modal.fields.map(m => {
-                  m.uuid = this.getuuid()
-                  return m
-                })
-              }
-            }
-
-            return cell
-          })
-        }
-        return col
-      })
-
-      if (item.subtype === 'editable') {
-        item.cols = item.cols.map(col => {
-          if (col.editable === 'true' && col.enter) {
+          } else if (col.editable === 'true' && col.enter) { // 鍙紪杈戣〃
             col.enter = md5(commonId + col.enter)
           }
+
           return col
         })
       }
+
+      item.cols = loopCol(item.cols)
     } else if (item.type === 'form') {
       item.subcards = item.subcards.map(cell => {
         cell.uuid = this.getuuid()
@@ -1094,23 +1041,31 @@
     })
   }
 
-  config.cols && config.cols.forEach(col => {
-    if (col.type === 'action') {
-      col.elements.forEach(cell => {
-        if (['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
-          action.push(cell)
-        } else if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) {
-          action.push(cell)
-        } else if (cell.OpenType === 'popview') {
-          if (pops) {
-            pops.push({...cell, parentId: config.uuid})
-          } else if (cell.config && cell.config.$tables) {
-            tables.push(...cell.config.$tables)
-          }
+  if (config.cols) {
+    let loopCol = (cols) => {
+      cols.forEach(col => {
+        if (col.type === 'colspan') {
+          loopCol(col.subcols)
+        } else if (col.type === 'custom') {
+          col.elements.forEach(cell => {
+            if (cell.eleType !== 'button') return
+            if (['form', 'pop', 'prompt', 'exec', 'excelIn', 'excelOut'].includes(cell.OpenType)) {
+              action.push(cell)
+            } else if (cell.OpenType === 'funcbutton' && cell.funcType === 'print' && cell.verify) {
+              action.push(cell)
+            } else if (cell.OpenType === 'popview') {
+              if (pops) {
+                pops.push({...cell, parentId: config.uuid})
+              } else if (cell.config && cell.config.$tables) {
+                tables.push(...cell.config.$tables)
+              }
+            }
+          })
         }
       })
     }
-  })
+    loopCol(config.cols)
+  }
 
   config.elements && config.elements.forEach(cell => {
     if (cell.eleType !== 'button') return
@@ -1394,27 +1349,27 @@
 
   if (card.$c_cl) {
     card.cols.forEach(col => {
-      if (col.type === 'action') {
+      if (col.type === 'custom') {
         col.elements.forEach(cell => {
-          if (cell.hidden === 'true') return
-          if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
-            if (!cell.modal || cell.modal.fields.length === 0) {
-              errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+          if (cell.eleType === 'button') {
+            if (cell.hidden === 'true') return
+            if (cell.OpenType === 'pop' || (cell.OpenType === 'funcbutton' && cell.execMode === 'pop')) {
+              if (!cell.modal || cell.modal.fields.length === 0) {
+                errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑琛ㄥ崟灏氭湭娣诲姞`})
+              }
+            } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
+              errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
+            } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
+              errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
             }
-          } else if (cell.OpenType === 'excelIn' && (!cell.verify || !cell.verify.sheet || !cell.verify.columns || cell.verify.columns.length === 0)) {
-            errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎叆鍒楁湭璁剧疆锛乣})
-          } else if (cell.OpenType === 'excelOut' && (!cell.verify || !cell.verify.columns || cell.verify.columns.length === 0)) {
-            errors.push({ level: 0, detail: `鎸夐挳鈥�${cell.label}鈥濅腑瀵煎嚭鍒楁湭璁剧疆锛乣})
-          }
 
-          if (doubleClick === cell.uuid) {
-            doubleClick = ''
-          }
-        })
-      } else if (col.type === 'custom') {
-        col.elements.forEach(cell => {
-          if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
-            errors.push({ level: 1, detail: `鏄剧ず鍒椻��${col.label}鈥濅腑鍔ㄦ�佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+            if (doubleClick === cell.uuid) {
+              doubleClick = ''
+            }
+          } else {
+            if (cell.datatype === 'dynamic' && cell.field && !columns.includes(cell.field)) {
+              errors.push({ level: 1, detail: `鏄剧ず鍒椻��${col.label}鈥濅腑鍔ㄦ�佸瓧娈碘��${cell.field}鈥濇棤鏁坄})
+            }
           }
         })
       } else if (col.field && !columns.includes(col.field)) {
diff --git a/src/views/billprint/index.jsx b/src/views/billprint/index.jsx
index 1757a88..de28f47 100644
--- a/src/views/billprint/index.jsx
+++ b/src/views/billprint/index.jsx
@@ -333,19 +333,27 @@
 
           if (component.type === 'table') {
             let getColumns = (cols) => {
-              return cols.map(item => {
+              return cols.filter(item => {
                 if (item.type === 'colspan') {
                   item.subcols = getColumns(item.subcols)
+                  if (item.subcols.length === 0) {
+                    return false
+                  }
                 } else if (item.type === 'custom') {
-                  item.elements = item.elements.map(cell => {
+                  item.elements = item.elements.filter(cell => {
+                    if (cell.eleType === 'button') return false
+
                     cell = this.resetElement(cell)
                     return cell
                   })
+                  if (item.elements.length === 0) {
+                    return false
+                  }
                 } else {
                   item.IsSort = 'false'
                 }
           
-                return item
+                return true
               })
             }
             component.cols = getColumns(component.cols)
diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx
index 57e7d08..10235d1 100644
--- a/src/views/menudesign/index.jsx
+++ b/src/views/menudesign/index.jsx
@@ -370,6 +370,8 @@
       _btn.config.MenuID = _btn.uuid
       _btn.config.ParentId = card.uuid
       _btn.config.MenuName = _btn.label
+
+      _btn.config.components = this.updateComponents(_btn.config.components || [])
     } else {
       _btn.config = {
         uuid: _btn.uuid,
@@ -485,6 +487,7 @@
           })
           this.updatePage(config)
         } else {
+          config.components = this.updateComponents(config.components)
           this.setState({
             oriConfig: fromJS(config).toJS(),
             config: config
@@ -498,6 +501,27 @@
           duration: 5
         })
       }
+    })
+  }
+
+  updateComponents = (components) => { // 鍏煎鎬у崌绾� table
+    return components.map(item => {
+      if (item.type === 'tabs') {
+        item.subtabs.forEach(tab => {
+          tab.components = this.updateComponents(tab.components)
+        })
+      } else if (item.type === 'group') {
+        item.components = this.updateComponents(item.components)
+      } else if (item.type === 'table') {
+        item.cols = item.cols.map(col => {
+          if (col.type === 'action') {
+            col.type = 'custom'
+          }
+          return col
+        })
+      }
+
+      return item
     })
   }
 
@@ -519,6 +543,13 @@
 
       if (item.subtype === 'tablecard') { // 鍏煎
         item.type = 'card'
+      } else if (item.type === 'table') {
+        item.cols = item.cols.map(col => {
+          if (col.type === 'action') {
+            col.type = 'custom'
+          }
+          return col
+        })
       }
 
       delete item.tabId
@@ -556,15 +587,23 @@
       })
     })
 
-    config.cols && config.cols.forEach(col => {
-      if (col.type === 'action') {
-        col.elements.forEach(cell => {
-          if (cell.OpenType === 'popview' && popbtns[cell.uuid]) {
-            cell.config = popbtns[cell.uuid]
+    if (config.cols) {
+      let loopCol = (cols) => {
+        cols.forEach(col => {
+          if (col.type === 'colspan') {
+            loopCol(col.subcols)
+          } else if (col.type === 'custom') {
+            col.elements.forEach(cell => {
+              if (cell.eleType !== 'button') return
+              if (cell.OpenType === 'popview' && popbtns[cell.uuid]) {
+                cell.config = popbtns[cell.uuid]
+              }
+            })
           }
         })
       }
-    })
+      loopCol(config.cols)
+    }
 
     config.elements && config.elements.forEach(cell => {
       if (cell.eleType !== 'button') return
@@ -720,14 +759,20 @@
             _sort++
           })
         } else if (item.type === 'table') {
-          item.cols && item.cols.forEach(col => {
-            if (col.type !== 'action') return
-            col.elements.forEach(btn => {
-              if (btn.hidden === 'true') return
-              buttons.push(`select '${btn.uuid}' as menuid, '${item.name + '-' + btn.label}' as menuname, '${_sort * 10}' as Sort, '${config.uuid}' as parentid, 40 as Type`)
-              _sort++
+          let loopCol = (cols) => {
+            cols.forEach(col => {
+              if (col.type === 'colspan') {
+                loopCol(col.subcols)
+              } else if (col.type === 'custom') {
+                col.elements.forEach(cell => {
+                  if (cell.eleType !== 'button' || cell.hidden === 'true') return
+                  buttons.push(`select '${cell.uuid}' as menuid, '${item.name + '-' + cell.label}' as menuname, '${_sort * 10}' as Sort, '${config.uuid}' as parentid, 40 as Type`)
+                  _sort++
+                })
+              }
             })
-          })
+          }
+          loopCol(item.cols)
         }
       })
     }
diff --git a/src/views/mobdesign/index.jsx b/src/views/mobdesign/index.jsx
index 1504072..404d210 100644
--- a/src/views/mobdesign/index.jsx
+++ b/src/views/mobdesign/index.jsx
@@ -232,6 +232,8 @@
       _btn.config.MenuID = _btn.uuid
       _btn.config.ParentId = card.uuid
       _btn.config.MenuName = _btn.label
+
+      _btn.config.components = this.updateComponents(_btn.config.components || [])
     } else {
       _btn.config = {
         uuid: _btn.uuid,
@@ -298,15 +300,23 @@
       })
     })
 
-    config.cols && config.cols.forEach(col => {
-      if (col.type === 'action') {
-        col.elements.forEach(cell => {
-          if (cell.OpenType === 'popview' && popbtns[cell.uuid]) {
-            cell.config = popbtns[cell.uuid]
+    if (config.cols) {
+      let loopCol = (cols) => {
+        cols.forEach(col => {
+          if (col.type === 'colspan') {
+            loopCol(col.subcols)
+          } else if (col.type === 'custom') {
+            col.elements.forEach(cell => {
+              if (cell.eleType !== 'button') return
+              if (cell.OpenType === 'popview' && popbtns[cell.uuid]) {
+                cell.config = popbtns[cell.uuid]
+              }
+            })
           }
         })
       }
-    })
+      loopCol(config.cols)
+    }
 
     config.elements && config.elements.forEach(cell => {
       if (cell.eleType !== 'button') return
@@ -604,6 +614,8 @@
           this.setState({
             needUpdate: true
           })
+        } else {
+          config.components = this.updateComponents(config.components)
         }
 
         let navItem = null
@@ -823,6 +835,8 @@
           this.setState({
             needUpdate: true
           })
+        } else {
+          config.components = this.updateComponents(config.components)
         }
 
         config.enabled = false
@@ -921,6 +935,27 @@
     })
   }
 
+  updateComponents = (components) => { // 鍏煎鎬у崌绾� table
+    return components.map(item => {
+      if (item.type === 'tabs') {
+        item.subtabs.forEach(tab => {
+          tab.components = this.updateComponents(tab.components)
+        })
+      } else if (item.type === 'group') {
+        item.components = this.updateComponents(item.components)
+      } else if (item.type === 'table') {
+        item.cols = item.cols.map(col => {
+          if (col.type === 'action') {
+            col.type = 'custom'
+          }
+          return col
+        })
+      }
+
+      return item
+    })
+  }
+
   collectTB = (components) => {
     return components.map(item => {
       if (item.type === 'tabs') {
@@ -939,6 +974,13 @@
 
       if (item.subtype === 'tablecard') { // 鍏煎
         item.type = 'card'
+      } else if (item.type === 'table') {
+        item.cols = item.cols.map(col => {
+          if (col.type === 'action') {
+            col.type = 'custom'
+          }
+          return col
+        })
       }
 
       delete item.tabId
@@ -1081,17 +1123,22 @@
               title: btn.label,
             })
           })
-          item.cols && item.cols.forEach(col => {
-            if (col.type !== 'action') return
-            col.elements.forEach(btn => {
-              if (btn.hidden === 'true') return
-
-              m.children.push({
-                key: btn.uuid,
-                title: btn.label,
-              })
+          let loopCol = (cols) => {
+            cols.forEach(col => {
+              if (col.type === 'colspan') {
+                loopCol(col.subcols)
+              } else if (col.type === 'custom') {
+                col.elements.forEach(cell => {
+                  if (cell.eleType !== 'button' || cell.hidden === 'true') return
+                  m.children.push({
+                    key: cell.uuid,
+                    title: cell.label,
+                  })
+                })
+              }
             })
-          })
+          }
+          loopCol(item.cols)
         }
 
         list.push(m)
@@ -1226,16 +1273,23 @@
               menus.push(menuObj[btn.openmenu])
             }
           })
-          item.cols && item.cols.forEach(col => {
-            if (col.type !== 'action') return
-            col.elements.forEach(btn => {
-              if (btn.linkmenu && menuObj[btn.linkmenu]) {
-                menus.push(menuObj[btn.linkmenu])
-              } else if (btn.openmenu && menuObj[btn.openmenu]) {
-                menus.push(menuObj[btn.openmenu])
+          let loopCol = (cols) => {
+            cols.forEach(col => {
+              if (col.type === 'colspan') {
+                loopCol(col.subcols)
+              } else if (col.type === 'custom') {
+                col.elements.forEach(cell => {
+                  if (cell.eleType !== 'button') return
+                  if (cell.linkmenu && menuObj[cell.linkmenu]) {
+                    menus.push(menuObj[cell.linkmenu])
+                  } else if (cell.openmenu && menuObj[cell.openmenu]) {
+                    menus.push(menuObj[cell.openmenu])
+                  }
+                })
               }
             })
-          })
+          }
+          loopCol(item.cols)
         }
       })
     }
@@ -1299,7 +1353,7 @@
             return cols.map(col => {
               if (col.type === 'colspan') {
                 col.subcols = getCols(col.subcols || [])
-              } else if (col.type === 'custom' || col.type === 'action') {
+              } else if (col.type === 'custom') {
                 col.elements = col.elements.map(cell => {
                   cell.miniStyle = this.transferStyle(cell.style)
                   return cell
diff --git a/src/views/pcdesign/index.jsx b/src/views/pcdesign/index.jsx
index b6b2760..76e490b 100644
--- a/src/views/pcdesign/index.jsx
+++ b/src/views/pcdesign/index.jsx
@@ -365,6 +365,8 @@
       _btn.config.MenuID = _btn.uuid
       _btn.config.ParentId = card.uuid
       _btn.config.MenuName = _btn.label
+
+      _btn.config.components = this.updateComponents(_btn.config.components || [])
     } else {
       _btn.config = {
         uuid: _btn.uuid,
@@ -420,15 +422,23 @@
       })
     })
 
-    config.cols && config.cols.forEach(col => {
-      if (col.type === 'action') {
-        col.elements.forEach(cell => {
-          if (cell.OpenType === 'popview' && popbtns[cell.uuid]) {
-            cell.config = popbtns[cell.uuid]
+    if (config.cols) {
+      let loopCol = (cols) => {
+        cols.forEach(col => {
+          if (col.type === 'colspan') {
+            loopCol(col.subcols)
+          } else if (col.type === 'custom') {
+            col.elements.forEach(cell => {
+              if (cell.eleType !== 'button') return
+              if (cell.OpenType === 'popview' && popbtns[cell.uuid]) {
+                cell.config = popbtns[cell.uuid]
+              }
+            })
           }
         })
       }
-    })
+      loopCol(config.cols)
+    }
 
     config.elements && config.elements.forEach(cell => {
       if (cell.eleType !== 'button') return
@@ -556,6 +566,8 @@
           this.setState({
             needUpdate: true
           })
+        } else {
+          config.components = this.updateComponents(config.components)
         }
 
         let navItem = null
@@ -581,6 +593,27 @@
     this.getAppMenus()
   }
 
+  updateComponents = (components) => { // 鍏煎鎬у崌绾� table
+    return components.map(item => {
+      if (item.type === 'tabs') {
+        item.subtabs.forEach(tab => {
+          tab.components = this.updateComponents(tab.components)
+        })
+      } else if (item.type === 'group') {
+        item.components = this.updateComponents(item.components)
+      } else if (item.type === 'table') {
+        item.cols = item.cols.map(col => {
+          if (col.type === 'action') {
+            col.type = 'custom'
+          }
+          return col
+        })
+      }
+
+      return item
+    })
+  }
+
   collectTB = (components) => {
     return components.map(item => {
       if (item.type === 'tabs') {
@@ -599,6 +632,13 @@
 
       if (item.subtype === 'tablecard') { // 鍏煎
         item.type = 'card'
+      } else if (item.type === 'table') {
+        item.cols = item.cols.map(col => {
+          if (col.type === 'action') {
+            col.type = 'custom'
+          }
+          return col
+        })
       }
 
       delete item.tabId
@@ -913,17 +953,22 @@
               title: btn.label,
             })
           })
-          item.cols.forEach(col => {
-            if (col.type !== 'action') return
-            col.elements.forEach(btn => {
-              if (btn.hidden === 'true') return
-              
-              m.children.push({
-                key: btn.uuid,
-                title: btn.label,
-              })
+          let loopCol = (cols) => {
+            cols.forEach(col => {
+              if (col.type === 'colspan') {
+                loopCol(col.subcols)
+              } else if (col.type === 'custom') {
+                col.elements.forEach(cell => {
+                  if (cell.eleType !== 'button' || cell.hidden === 'true') return
+                  m.children.push({
+                    key: cell.uuid,
+                    title: cell.label,
+                  })
+                })
+              }
             })
-          })
+          }
+          loopCol(item.cols)
         }
 
         list.push(m)
@@ -1039,16 +1084,23 @@
               menus.push(menuObj[btn.openmenu])
             }
           })
-          item.cols && item.cols.forEach(col => {
-            if (col.type !== 'action') return
-            col.elements.forEach(btn => {
-              if (btn.linkmenu && menuObj[btn.linkmenu]) {
-                menus.push(menuObj[btn.linkmenu])
-              } else if (btn.openmenu && menuObj[btn.openmenu]) {
-                menus.push(menuObj[btn.openmenu])
+          let loopCol = (cols) => {
+            cols.forEach(col => {
+              if (col.type === 'colspan') {
+                loopCol(col.subcols)
+              } else if (col.type === 'custom') {
+                col.elements.forEach(cell => {
+                  if (cell.eleType !== 'button') return
+                  if (cell.linkmenu && menuObj[cell.linkmenu]) {
+                    menus.push(menuObj[cell.linkmenu])
+                  } else if (cell.openmenu && menuObj[cell.openmenu]) {
+                    menus.push(menuObj[cell.openmenu])
+                  }
+                })
               }
             })
-          })
+          }
+          loopCol(item.cols)
         }
       })
     }
diff --git a/src/views/tabledesign/index.jsx b/src/views/tabledesign/index.jsx
index 18311e8..507484b 100644
--- a/src/views/tabledesign/index.jsx
+++ b/src/views/tabledesign/index.jsx
@@ -235,6 +235,26 @@
       _btn.config.MenuID = _btn.uuid
       _btn.config.ParentId = card.uuid
       _btn.config.MenuName = _btn.label
+      _btn.config.components = _btn.config.components || []
+      _btn.config.components.forEach(item => {
+        if (item.type === 'tabs') {
+          item.subtabs.forEach(tab => {
+            tab.components[0].cols = tab.components[0].cols.map(col => {
+              if (col.type === 'action') {
+                col.type = 'custom'
+              }
+              return col
+            })
+          })
+        } else if (item.cols) {
+          item.cols = item.cols.map(col => {
+            if (col.type === 'action') {
+              col.type = 'custom'
+            }
+            return col
+          })
+        }
+      })
     } else {
       _btn.config = {
         uuid: _btn.uuid,
@@ -263,6 +283,21 @@
   submitPopConfig = (btnconfig) => {
     let config = fromJS(this.state.config).toJS()
 
+    let loopCol = (cols) => {
+      cols.forEach(col => {
+        if (col.type === 'colspan') {
+          loopCol(col.subcols)
+        } else if (col.type === 'custom') {
+          col.elements.forEach(cell => {
+            if (cell.eleType !== 'button') return
+            if (cell.OpenType === 'popview' && cell.uuid === btnconfig.uuid) {
+              cell.config = btnconfig
+            }
+          })
+        }
+      })
+    }
+
     config.components.forEach(item => {
       if (item.type === 'tabs') {
         item.subtabs.forEach(tab => {
@@ -273,14 +308,8 @@
               btn.config = btnconfig
             }
           })
-          tab.components[0].cols.forEach(col => {
-            if (col.type !== 'action') return
-            col.elements.forEach(btn => {
-              if (btn.OpenType === 'popview' && btn.uuid === btnconfig.uuid) {
-                btn.config = btnconfig
-              }
-            })
-          })
+
+          loopCol(tab.components[0].cols)
 
           tab.components[0].$tables = getTables(tab.components[0])
         })
@@ -290,14 +319,8 @@
             btn.config = btnconfig
           }
         })
-        item.cols.forEach(col => {
-          if (col.type !== 'action') return
-          col.elements.forEach(btn => {
-            if (btn.OpenType === 'popview' && btn.uuid === btnconfig.uuid) {
-              btn.config = btnconfig
-            }
-          })
-        })
+
+        loopCol(item.cols)
 
         item.$tables = getTables(item)
       }
@@ -407,8 +430,20 @@
             if (item.type === 'tabs') {
               item.subtabs.forEach(tab => {
                 tab.components[0].name = tab.label
+                tab.components[0].cols = tab.components[0].cols.map(col => {
+                  if (col.type === 'action') {
+                    col.type = 'custom'
+                  }
+                  return col
+                })
               })
             } else {
+              item.cols = item.cols.map(col => {
+                if (col.type === 'action') {
+                  col.type = 'custom'
+                }
+                return col
+              })
               item.name = '涓昏〃'
             }
           })
@@ -457,15 +492,22 @@
             buttons.push(`select '${btn.uuid}' as menuid, '${btn.label}' as menuname, '${_s * 10}' as Sort, '${tab.components[0].uuid}' as parentid, 60 as Type`)
             _s++
           })
-          tab.components[0].cols.forEach(col => {
-            if (col.type !== 'action') return
-            col.elements.forEach(btn => {
-              if (btn.hidden === 'true') return
 
-              buttons.push(`select '${btn.uuid}' as menuid, '${btn.label}' as menuname, '${_s * 10}' as Sort, '${tab.components[0].uuid}' as parentid, 60 as Type`)
-              _s++
+          let loopCol = (cols) => {
+            cols.forEach(col => {
+              if (col.type === 'colspan') {
+                loopCol(col.subcols)
+              } else if (col.type === 'custom') {
+                col.elements.forEach(cell => {
+                  if (cell.eleType !== 'button' || cell.hidden === 'true') return
+                  buttons.push(`select '${cell.uuid}' as menuid, '${cell.label}' as menuname, '${_s * 10}' as Sort, '${tab.components[0].uuid}' as parentid, 60 as Type`)
+                  _s++
+                })
+              }
             })
-          })
+          }
+
+          loopCol(tab.components[0].cols)
         })
       } else {
         if (item.$tables) {
@@ -477,15 +519,22 @@
           buttons.push(`select '${btn.uuid}' as menuid, '${btn.label}' as menuname, '${_sort * 10}' as Sort, '${config.uuid}' as parentid, 40 as Type`)
           _sort++
         })
-        item.cols.forEach(col => {
-          if (col.type !== 'action') return
-          col.elements.forEach(btn => {
-            if (btn.hidden === 'true') return
 
-            buttons.push(`select '${btn.uuid}' as menuid,  '${btn.label}' as menuname, '${_sort * 10}' as Sort, '${config.uuid}' as parentid, 40 as Type`)
-            _sort++
+        let loopCol = (cols) => {
+          cols.forEach(col => {
+            if (col.type === 'colspan') {
+              loopCol(col.subcols)
+            } else if (col.type === 'custom') {
+              col.elements.forEach(cell => {
+                if (cell.eleType !== 'button' || cell.hidden === 'true') return
+                buttons.push(`select '${cell.uuid}' as menuid,  '${cell.label}' as menuname, '${_sort * 10}' as Sort, '${config.uuid}' as parentid, 40 as Type`)
+                _sort++
+              })
+            }
           })
-        })
+        }
+
+        loopCol(item.cols)
       }
     })
 
diff --git a/src/views/tabledesign/source.jsx b/src/views/tabledesign/source.jsx
index eb08829..5e43351 100644
--- a/src/views/tabledesign/source.jsx
+++ b/src/views/tabledesign/source.jsx
@@ -231,12 +231,6 @@
       label: '搴忓彿',
       subType: 'index',
       $init: true
-    },
-    {
-      type: 'col',
-      label: '鎿嶄綔',
-      subType: 'action',
-      $init: true
     }
   ],
   tabItems: [

--
Gitblit v1.8.0