From 7449eee8fa9f8a251e9c4e9162030f1e004bae0f Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期四, 15 十月 2020 09:17:04 +0800
Subject: [PATCH] 2020-10-15

---
 src/components/tabview/index.jsx                                               |    4 
 src/menu/components/chart/antv-bar/chartcompile/index.jsx                      |   18 
 src/templates/zshare/modalform/index.jsx                                       |  191 +--
 src/tabviews/custom/components/chart/antv-bar-line/index.jsx                   |    7 
 src/menu/components/chart/antv-bar/chartcompile/index.scss                     |    4 
 src/tabviews/custom/components/chart/antv-bar-line/index.scss                  |   13 
 src/tabviews/custom/components/tabs/antv-tabs/index.jsx                        |    2 
 src/tabviews/zshare/normalTable/index.jsx                                      |   11 
 src/templates/formtabconfig/index.jsx                                          |   44 
 src/menu/components/card/cardcellcomponent/index.scss                          |    4 
 src/menu/components/card/cardcellcomponent/dragaction/action.jsx               |    9 
 src/menu/components/card/cardcellcomponent/dragaction/index.jsx                |   11 
 src/templates/comtableconfig/index.jsx                                         |   30 
 src/menu/components/tabs/antv-tabs/index.scss                                  |    2 
 src/templates/sharecomponent/searchcomponent/index.jsx                         |   18 
 src/templates/treepageconfig/index.jsx                                         |    8 
 src/locales/zh-CN/model.js                                                     |    2 
 src/menu/components/card/cardcellcomponent/dragaction/card.jsx                 |    6 
 src/menu/components/chart/antv-bar/index.scss                                  |   23 
 src/menu/components/chart/antv-bar/index.jsx                                   |  157 ++
 src/templates/modalconfig/index.jsx                                            |   62 -
 src/locales/en-US/model.js                                                     |    2 
 src/templates/menuconfig/editthdmenu/index.jsx                                 |   13 
 src/menu/searchcomponent/index.jsx                                             |    1 
 src/tabviews/commontable/index.jsx                                             |    3 
 src/tabviews/custom/components/card/data-card/index.scss                       |    1 
 src/templates/modalconfig/dragelement/card.jsx                                 |   18 
 src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx                 |   14 
 src/templates/modalconfig/index.scss                                           |    1 
 src/menu/components/card/cardcellcomponent/index.jsx                           |   32 
 src/templates/zshare/formconfig.jsx                                            |   71 +
 src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx |   11 
 src/templates/calendarconfig/index.jsx                                         |   31 
 src/tabviews/custom/components/tabs/antv-tabs/index.scss                       |    2 
 src/templates/subtableconfig/index.jsx                                         |   30 
 src/menu/modalconfig/index.scss                                                |  295 ++++++
 src/templates/modalconfig/source.jsx                                           |   24 
 src/menu/modalconfig/index.jsx                                                 | 1401 +++++++++++++++++++++++++++++
 src/menu/components/tabs/antv-tabs/index.jsx                                   |   23 
 src/templates/zshare/modalform/modaleditable/index.jsx                         |  141 +-
 src/templates/sharecomponent/searchcomponent/searchform/index.jsx              |   28 
 41 files changed, 2,274 insertions(+), 494 deletions(-)

diff --git a/src/components/tabview/index.jsx b/src/components/tabview/index.jsx
index e4e25b2..ba0c4c4 100644
--- a/src/components/tabview/index.jsx
+++ b/src/components/tabview/index.jsx
@@ -206,6 +206,7 @@
   }
 
   render () {
+    const { menuType } = this.props
     const { tabviews } = this.state
     let view = tabviews.filter(tab => tab.selected)[0]
     this.resetWindow(view)
@@ -235,7 +236,7 @@
                     key={view.MenuID}
                   >
                     {this.selectcomponent(view)}
-                    {options.sysType !== 'cloud' && !['CommonTable', 'TreePage', 'ManageTable', 'CalendarPage'].includes(view.type) ?
+                    {options.sysType !== 'cloud' && menuType !== 'HS' && !['CommonTable', 'TreePage', 'ManageTable', 'CalendarPage'].includes(view.type) ?
                       <Button
                         icon="copy"
                         shape="circle"
@@ -264,6 +265,7 @@
 
 const mapStateToProps = (state) => {
   return {
+    menuType: state.editLevel,
     tabviews: state.tabviews,
     collapse: state.collapse,
     isiframe: state.isiframe
diff --git a/src/locales/en-US/model.js b/src/locales/en-US/model.js
index f3aec6a..c929fca 100644
--- a/src/locales/en-US/model.js
+++ b/src/locales/en-US/model.js
@@ -201,7 +201,7 @@
   'header.form.leftPicRightText': '宸﹀浘鍙虫枃',
   'model.form.selectItem.error': '涓嬫媺閫夐」璁剧疆閿欒锛�',
   'header.form.request.method': '璇锋眰鏂瑰紡',
-  'header.form.readonly': '鏄惁鍙',
+  'header.form.readonly': '鍙',
   'header.form.queryType': '鏌ヨ绫诲瀷',
   'header.form.query': '鏌ヨ',
   'header.form.statistics': '缁熻',
diff --git a/src/locales/zh-CN/model.js b/src/locales/zh-CN/model.js
index 036056b..95bdf87 100644
--- a/src/locales/zh-CN/model.js
+++ b/src/locales/zh-CN/model.js
@@ -201,7 +201,7 @@
   'header.form.leftPicRightText': '宸﹀浘鍙虫枃',
   'model.form.selectItem.error': '涓嬫媺閫夐」璁剧疆閿欒锛�',
   'header.form.request.method': '璇锋眰鏂瑰紡',
-  'header.form.readonly': '鏄惁鍙',
+  'header.form.readonly': '鍙',
   'header.form.queryType': '鏌ヨ绫诲瀷',
   'header.form.query': '鏌ヨ',
   'header.form.statistics': '缁熻',
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/action.jsx b/src/menu/components/card/cardcellcomponent/dragaction/action.jsx
index 3568be8..0ebf81e 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/action.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/action.jsx
@@ -3,7 +3,7 @@
 import { Icon, Popover, Button } from 'antd'
 import './index.scss'
 
-const Card = ({ id, cardIds, card, moveCard, findCard, editCard, delCard, profileCard, changeStyle }) => {
+const Card = ({ id, cardIds, card, moveCard, findCard, editCard, delCard, profileCard, changeStyle, doubleClickCard }) => {
   const originalIndex = findCard(id).index
   const [{ isDragging }, drag] = useDrag({
     item: { type: 'action', id, originalIndex },
@@ -53,7 +53,6 @@
         className={'mk-btn mk-' + card.class}
         icon={card.icon}
         style={card.btnstyle}
-        // onDoubleClick={() => doubleClickCard(id)}
       >
         {card.label}
       </Button>
@@ -69,8 +68,10 @@
         {hasProfile ? <Icon className="profile" title="setting" type="profile" onClick={() => profileCard(id)} /> : null}
       </div>
     } trigger="hover">
-      <div ref={node => drag(drop(node))} className={'ant-col card-button-cell ant-col-' + card.width} style={_style}>
-        {btnElement}
+      <div ref={node => drag(drop(node))} className={'ant-col card-button-cell ant-col-' + card.width} onDoubleClick={() => doubleClickCard(id)}>
+        <div style={_style}>
+          {btnElement}
+        </div>
       </div>
     </Popover>
   )
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
index ea6fb70..35078a7 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
@@ -96,8 +96,10 @@
         <Icon className="style" title="璋冩暣鏍峰紡" onClick={() => changeStyle(id)} type="font-colors" />
       </div>
     } trigger="hover">
-      <div ref={node => drag(drop(node))} className={'ant-col card-cell ant-col-' + card.width} style={_style}>
-        {getContent()}
+      <div ref={node => drag(drop(node))} className={'ant-col card-cell ant-col-' + card.width}>
+        <div style={_style}>
+          {getContent()}
+        </div>
       </div>
     </Popover>
   )
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/index.jsx b/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
index 88955b9..0c879f2 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/index.jsx
@@ -7,7 +7,7 @@
 import Action from './action'
 import './index.scss'
 
-const Container = ({list, handleList, handleMenu, deleteMenu, profileAction, handleStyle }) => {
+const Container = ({list, handleList, handleMenu, deleteMenu, profileAction, handleStyle, handleSubConfig }) => {
   const [cards, setCards] = useState(list)
   const moveCard = (id, atIndex) => {
     const { card, index } = findCard(id)
@@ -42,6 +42,14 @@
     profileAction(card)
   }
 
+  const doubleClickCard = id => {
+    const { card } = findCard(id)
+    console.log(card)
+    if (card.OpenType === 'pop') {
+      handleSubConfig(card)
+    }
+  }
+
   const delCard = id => {
     const { card } = findCard(id)
     deleteMenu(card)
@@ -68,6 +76,7 @@
               editCard={editCard}
               changeStyle={changeStyle}
               profileCard={profileCard}
+              doubleClickCard={doubleClickCard}
               delCard={delCard}
               findCard={findCard}
             />
diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx
index e408ef6..3c7c241 100644
--- a/src/menu/components/card/cardcellcomponent/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/index.jsx
@@ -8,21 +8,24 @@
 import options from '@/store/options.js'
 import zhCN from '@/locales/zh-CN/model.js'
 import enUS from '@/locales/en-US/model.js'
+import asyncComponent from '@/utils/asyncComponent'
 import { getCardCellForm } from './formconfig'
 import { getActionForm } from '@/menu/actioncomponent/formconfig'
 
 import MKEmitter from '@/utils/events.js'
 import ElementForm from './elementform'
 import DragElement from './dragaction'
-import ActionForm from '@/menu/actioncomponent/actionform'
-import CreateFunc from '@/templates/zshare/createfunc'
-import VerifyCard from '@/templates/zshare/verifycard'
-import VerifyPrint from '@/menu/actioncomponent/verifyprint'
-import VerifyExcelIn from '@/menu/actioncomponent/verifyexcelin'
-import VerifyExcelOut from '@/menu/actioncomponent/verifyexcelout'
 import './index.scss'
 
 const { confirm } = Modal
+
+const ActionForm = asyncComponent(() => import('@/menu/actioncomponent/actionform'))
+const CreateFunc = asyncComponent(() => import('@/templates/zshare/createfunc'))
+const VerifyCard = asyncComponent(() => import('@/templates/zshare/verifycard'))
+const VerifyPrint = asyncComponent(() => import('@/menu/actioncomponent/verifyprint'))
+const VerifyExcelIn = asyncComponent(() => import('@/menu/actioncomponent/verifyexcelin'))
+const VerifyExcelOut = asyncComponent(() => import('@/menu/actioncomponent/verifyexcelout'))
+// const ModalConfig = asyncComponent(() => import('@/menu/modalconfig'))
 
 class CardCellComponent extends Component {
   static propTpyes = {
@@ -480,6 +483,10 @@
     })
   }
 
+  handleSubConfig = (item) => {
+    console.log(item)
+  }
+
   render() {
     const { cards } = this.props
     const { elements, visible, actvisible, profVisible, card, dict } = this.state
@@ -492,8 +499,21 @@
           handleMenu={this.handleElement}
           handleStyle={this.handleStyle}
           profileAction={this.profileAction}
+          handleSubConfig={this.handleSubConfig}
           deleteMenu={this.deleteElement}
         />
+          {/* <ModalConfig
+            menu={this.state.editMenu}
+            editTab={this.state.editTab}
+            tabConfig={this.state.tabConfig}
+            editSubTab={this.state.editSubTab}
+            subTabConfig={this.state.subTabConfig}
+            btnTab={this.state.btnTab}
+            btnTabConfig={this.state.btnTabConfig}
+            editAction={this.state.editAction}
+            subConfig={this.state.subConfig}
+            handleView={this.handleView}
+          /> */}
         {/* 缂栬緫鎸夐挳锛氬鍒躲�佺紪杈� */}
         <Modal
           title={'缂栬緫鍏冪礌'}
diff --git a/src/menu/components/card/cardcellcomponent/index.scss b/src/menu/components/card/cardcellcomponent/index.scss
index 7d08668..83c954a 100644
--- a/src/menu/components/card/cardcellcomponent/index.scss
+++ b/src/menu/components/card/cardcellcomponent/index.scss
@@ -31,8 +31,8 @@
       }
     }
   }
-  .card-cell:hover {
-    box-shadow: 0px 0px 1px #d8d8d8;
+  .card-cell:hover, .card-button-cell:hover {
+    box-shadow: 0px 0px 1px #1890ff;
   }
   .ant-slider {
     margin: 0px;
diff --git a/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
index 4ef5044..b517422 100644
--- a/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
@@ -287,6 +287,20 @@
       initVal: card.correction,
       forbid: !['bar'].includes(card.chartType),
       required: false
+    }, {
+      type: 'color',
+      key: 'color',
+      label: '鑹茬郴',
+      initVal: card.color || 'rgba(0, 0, 0, 0.85)',
+      tooltip: '鍧愭爣杞村強绀轰緥绛夋彁绀烘枃瀛椾娇鐢ㄧ殑棰滆壊銆�',
+      required: false,
+      options: [{
+        value: 'black',
+        text: '榛戣壊'
+      }, {
+        value: 'white',
+        text: '鐧借壊'
+      }]
     }
   ]
 }
diff --git a/src/menu/components/chart/antv-bar/chartcompile/index.jsx b/src/menu/components/chart/antv-bar/chartcompile/index.jsx
index d708a36..e7295d0 100644
--- a/src/menu/components/chart/antv-bar/chartcompile/index.jsx
+++ b/src/menu/components/chart/antv-bar/chartcompile/index.jsx
@@ -5,6 +5,7 @@
 
 import { getBarOrLineChartOptionForm } from './formconfig'
 import { minkeColorSystem, colorTransform } from '@/utils/option.js'
+import ColorSketch from '@/mob/colorsketch'
 import './index.scss'
 
 const { TabPane } = Tabs
@@ -215,6 +216,23 @@
             </Form.Item>
           </Col>
         )
+      } else if (item.type === 'color') {
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.tooltip ?
+              <Tooltip placement="topLeft" title={item.tooltip}>
+                <Icon type="question-circle" />
+                {item.label}
+              </Tooltip> : item.label
+            }>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal
+              })(
+                <ColorSketch />
+              )}
+            </Form.Item>
+          </Col>
+        )
       }
     })
     return fields
diff --git a/src/menu/components/chart/antv-bar/chartcompile/index.scss b/src/menu/components/chart/antv-bar/chartcompile/index.scss
index 9dd5c31..58e64f2 100644
--- a/src/menu/components/chart/antv-bar/chartcompile/index.scss
+++ b/src/menu/components/chart/antv-bar/chartcompile/index.scss
@@ -22,6 +22,10 @@
         .ant-tabs-nav-wrap {
           text-align: center;
         }
+        .color-sketch-block {
+          position: relative;
+          top: 5px;
+        }
       }
     }
   }
diff --git a/src/menu/components/chart/antv-bar/index.jsx b/src/menu/components/chart/antv-bar/index.jsx
index c3e22df..a0656da 100644
--- a/src/menu/components/chart/antv-bar/index.jsx
+++ b/src/menu/components/chart/antv-bar/index.jsx
@@ -84,7 +84,7 @@
         name: _plot.name,
         subtype: card.subtype,
         setting: { interType: 'system' },
-        style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' },
+        style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px', fontSize: '16px' },
         columns: [],
         scripts: [],
         search: [],
@@ -105,6 +105,7 @@
   componentDidMount () {
     this.viewrender()
     MKEmitter.addListener('tabsChange', this.handleTabsChange)
+    MKEmitter.addListener('submitStyle', this.getStyle)
   }
 
   shouldComponentUpdate (nextProps, nextState) {
@@ -119,6 +120,7 @@
       return
     }
     MKEmitter.removeListener('tabsChange', this.handleTabsChange)
+    MKEmitter.removeListener('submitStyle', this.getStyle)
   }
 
   handleTabsChange = (parentId) => {
@@ -170,7 +172,8 @@
 
   linerender = () => {
     const { card } = this.state
-    let plot = {...card.plot, height: card.plot.height - 70} // 鍘婚櫎title鎵�鍗犵┖闂�
+    let plot = {...card.plot, height: card.plot.height - 80} // 鍘婚櫎title鎵�鍗犵┖闂�
+    let color = plot.color || 'rgba(0, 0, 0, 0.85)'
 
     let transfield = {}
     card.columns.forEach(col => {
@@ -212,6 +215,31 @@
       })
   
       chart.data(dv.rows)
+
+      chart.axis(X_axis, {
+        label: {
+          style: {
+            fill: color,
+          }
+        },
+        line: {
+          style: {
+            fill: color,
+          }
+        }
+      })
+      chart.axis('value', {
+        grid: {
+          style: {
+            fill: color,
+          }
+        },
+        label: {
+          style: {
+            fill: color,
+          }
+        }
+      })
   
       if (plot.coordinate !== 'polar') {
         chart.scale(X_axis, {
@@ -226,7 +254,12 @@
         chart.legend(false)
       } else {
         chart.legend({
-          position: plot.legend
+          position: plot.legend,
+          itemName: {
+            style: {
+              fill: color,
+            }
+          }
         })
       }
   
@@ -275,7 +308,8 @@
 
   customrender = (data, transfield) => {
     const { card } = this.state
-    let plot = {...card.plot, height: card.plot.height - 70} // 鍘婚櫎title鎵�鍗犵┖闂�
+    let plot = {...card.plot, height: card.plot.height - 80} // 鍘婚櫎title鎵�鍗犵┖闂�
+    let color = plot.color || 'rgba(0, 0, 0, 0.85)'
 
     let barfields = []
     let fields = []
@@ -327,6 +361,31 @@
 
     chart.data(dv.rows)
 
+    chart.axis(plot.Xaxis, {
+      label: {
+        style: {
+          fill: color,
+        }
+      },
+      line: {
+        style: {
+          fill: color,
+        }
+      }
+    })
+    chart.axis('value', {
+      grid: {
+        style: {
+          fill: color,
+        }
+      },
+      label: {
+        style: {
+          fill: color,
+        }
+      }
+    })
+
     if (plot.coordinate !== 'polar' && barfields.length === 0) {
       chart.scale(plot.Xaxis, {
         range: [0, 1]
@@ -340,6 +399,11 @@
         custom: true,
         position: plot.legend,
         items: legends,
+        itemName: {
+          style: {
+            fill: color,
+          }
+        }
       })
     }
 
@@ -347,7 +411,7 @@
       chart.tooltip(false)
     } else {
       chart.tooltip({
-        shared: true
+        shared: true,
       })
     }
 
@@ -424,7 +488,8 @@
 
   barrender = () => {
     const { card } = this.state
-    let plot = {...card.plot, height: card.plot.height - 70}
+    let plot = {...card.plot, height: card.plot.height - 80}
+    let color = plot.color || 'rgba(0, 0, 0, 0.85)'
 
     let transfield = {}
     card.columns.forEach(col => {
@@ -466,30 +531,30 @@
   
       chart.data(dv.rows)
 
-      // chart.axis(X_axis, {
-      //   label: {
-      //     style: {
-      //       fill: '#ffffff',
-      //     }
-      //   },
-      //   line: {
-      //     style: {
-      //       fill: '#ffffff',
-      //     }
-      //   }
-      // })
-      // chart.axis('value', {
-      //   grid: {
-      //     style: {
-      //       fill: '#ffffff',
-      //     }
-      //   },
-      //   label: {
-      //     style: {
-      //       fill: '#ffffff',
-      //     }
-      //   }
-      // })
+      chart.axis(X_axis, {
+        label: {
+          style: {
+            fill: color,
+          }
+        },
+        line: {
+          style: {
+            fill: color,
+          }
+        }
+      })
+      chart.axis('value', {
+        grid: {
+          style: {
+            fill: color,
+          }
+        },
+        label: {
+          style: {
+            fill: color,
+          }
+        }
+      })
   
       chart.scale('value', {
         nice: true
@@ -500,11 +565,11 @@
       } else {
         chart.legend({
           position: plot.legend,
-          // itemName: {
-          //   style: {
-          //     fill: '#ffffff',
-          //   }
-          // }
+          itemName: {
+            style: {
+              fill: color,
+            }
+          }
         })
       }
   
@@ -639,6 +704,26 @@
     MKEmitter.emit('addButton', card.uuid, newcard)
   }
 
+  changeStyle = () => {
+    const { card } = this.state
+
+    MKEmitter.emit('changeStyle', [card.uuid], ['font', 'background', 'border', 'padding', 'margin'], card.style)
+  }
+
+  getStyle = (comIds, style) => {
+    const { card } = this.state
+
+    if (comIds.length !== 1 || comIds[0] !== card.uuid) return
+
+    let _card = {...card, style}
+
+    this.setState({
+      card: _card
+    })
+    
+    this.props.updateConfig(_card)
+  }
+
   render() {
     const { card } = this.state
 
@@ -655,6 +740,7 @@
               <Icon className="plus" title="娣诲姞鎼滅储" onClick={this.addSearch} type="plus-circle" />
               <Icon className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton} type="plus-square" />
               <ChartCompileForm config={card} dict={this.state.dict} plotchange={this.updateComponent}/>
+              <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
               <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
               <SettingComponent config={card} updateConfig={this.updateComponent}/>
             </div>
@@ -670,7 +756,6 @@
           updateaction={this.updateComponent}
         />
         <div className="canvas" id={card.uuid}></div>
-        
       </div>
     )
   }
diff --git a/src/menu/components/chart/antv-bar/index.scss b/src/menu/components/chart/antv-bar/index.scss
index 6df8cc0..1f6b481 100644
--- a/src/menu/components/chart/antv-bar/index.scss
+++ b/src/menu/components/chart/antv-bar/index.scss
@@ -2,10 +2,13 @@
   position: relative;
   box-sizing: border-box;
   background: #ffffff;
+  border-style: solid;
+  border-width: 0;
   
   .canvas {
     margin: 0px;
-    padding: 10px 15px;
+    padding: 15px;
+    letter-spacing: 0px;
   }
 
   .chart-header {
@@ -13,19 +16,26 @@
     height: 45px;
     border-bottom: 1px solid #e8e8e8;
     overflow: hidden;
-    padding-right: 40px;
+    padding-right: 35px;
+    text-decoration: inherit;
+    font-weight: inherit;
+    font-style: inherit;
 
     >.anticon-tool {
       position: absolute;
-      right: 0px;
-      top: 0px;
+      right: 1px;
+      top: 1px;
       font-size: 16px;
-      padding: 10px;
+      padding: 5px;
       cursor: pointer;
+      color: rgba(0, 0, 0, 0.85);
+      background: #ffffff;
     }
 
     .chart-title {
-      font-size: 16px;
+      text-decoration: inherit;
+      font-weight: inherit;
+      font-style: inherit;
       float: left;
       line-height: 45px;
       margin-left: 10px;
@@ -37,6 +47,7 @@
     right: 0px;
     z-index: 4;
     padding-top: 10px;
+    font-size: 16px;
   
     .ant-row .anticon-plus {
       float: right;
diff --git a/src/menu/components/tabs/antv-tabs/index.jsx b/src/menu/components/tabs/antv-tabs/index.jsx
index f1d986c..a32e8fb 100644
--- a/src/menu/components/tabs/antv-tabs/index.jsx
+++ b/src/menu/components/tabs/antv-tabs/index.jsx
@@ -71,6 +71,7 @@
 
   componentDidMount () {
     MKEmitter.addListener('tabsChange', this.handleTabsChange)
+    MKEmitter.addListener('submitStyle', this.getStyle)
   }
 
   /**
@@ -81,6 +82,27 @@
       return
     }
     MKEmitter.removeListener('tabsChange', this.handleTabsChange)
+    MKEmitter.addListener('submitStyle', this.getStyle)
+  }
+
+  changeStyle = () => {
+    const { tabs } = this.state
+
+    MKEmitter.emit('changeStyle', [tabs.uuid], ['background', 'border', 'padding', 'margin'], tabs.style)
+  }
+
+  getStyle = (comIds, style) => {
+    const { tabs } = this.state
+
+    if (comIds.length !== 1 || comIds[0] !== tabs.uuid) return
+
+    let _card = {...tabs, style}
+
+    this.setState({
+      tabs: _card
+    })
+    
+    this.props.updateConfig(_card)
   }
 
   handleTabsChange = (parentId) => {
@@ -230,6 +252,7 @@
               <div className="mk-popover-control">
                 <Icon className="plus" title="娣诲姞鏍囩" type="plus" onClick={this.tabAdd} />
                 <SettingComponent config={tabs} updateConfig={this.updateComponent} />
+                <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
                 <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(tabs.uuid)} />
               </div>
             } trigger="hover">
diff --git a/src/menu/components/tabs/antv-tabs/index.scss b/src/menu/components/tabs/antv-tabs/index.scss
index a9acc8a..f8455e8 100644
--- a/src/menu/components/tabs/antv-tabs/index.scss
+++ b/src/menu/components/tabs/antv-tabs/index.scss
@@ -2,6 +2,8 @@
   position: relative;
   box-sizing: border-box;
   background: #ffffff;
+  border-style: solid;
+  border-width: 0;
 
   .ant-tabs-tabpane-active {
     min-height: 200px;
diff --git a/src/menu/modalconfig/index.jsx b/src/menu/modalconfig/index.jsx
new file mode 100644
index 0000000..3f5e59e
--- /dev/null
+++ b/src/menu/modalconfig/index.jsx
@@ -0,0 +1,1401 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import {connect} from 'react-redux'
+import { is, fromJS } from 'immutable'
+import { DndProvider } from 'react-dnd'
+import HTML5Backend from 'react-dnd-html5-backend'
+import moment from 'moment'
+import { Button, Card, Modal, Collapse, notification, Select, List, Icon, Empty, Popover } from 'antd'
+
+import Api from '@/api'
+import Utils from '@/utils/utils.js'
+import zhCN from '@/locales/zh-CN/model.js'
+import enUS from '@/locales/en-US/model.js'
+import { getModalForm } from '@/templates/zshare/formconfig'
+import { queryTableSql } from '@/utils/option.js'
+
+import ModalForm from '@/templates/zshare/modalform'
+import DragElement from '@/templates/modalconfig/dragelement'
+import SourceElement from '@/templates/modalconfig/dragelement/source'
+import SettingForm from '@/templates/modalconfig/settingform'
+import GroupForm from '@/templates/modalconfig/groupform'
+import EditCard from '@/templates/modalconfig/editcard'
+import MenuForm from '@/templates/modalconfig/menuform'
+import EditComponent from '@/templates/zshare/editcomponent'
+import { BaseConfig, SearchItems } from '@/templates/modalconfig/source'
+import './index.scss'
+
+const { Panel } = Collapse
+const { Option } = Select
+const { confirm } = Modal
+const CommonDict = localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
+
+class ComModalConfig extends Component {
+  static propTpyes = {
+    menu: PropTypes.any,
+    editTab: PropTypes.any,
+    editSubTab: PropTypes.any,
+    tabConfig: PropTypes.any,
+    subTabConfig: PropTypes.any,
+    btnTab: PropTypes.any,
+    btnTabConfig: PropTypes.any,
+    editAction: PropTypes.object,
+    subConfig: PropTypes.any,
+    handleView: PropTypes.func
+  }
+
+  state = {
+    menu: null,            // 涓婄骇鑿滃崟锛屼笁绾ц彍鍗曟垨鏍囩
+    dict: CommonDict,      // 瀛楀吀
+    config: null,          // 椤甸潰閰嶇疆锛屽寘鎷ā鏉跨被鍨嬨�佹ā鎬佹璁剧疆銆佹坊鍔犺〃鍚嶃�佽〃鍗曞垪琛�
+    visible: false,        // 琛ㄥ崟缂栬緫妯℃�佹锛屾樉绀烘帶鍒�
+    modalType: null,       // 琛ㄥ崟缂栬緫绫诲瀷锛岀紪杈戞垨澶嶅埗
+    tableVisible: false,   // 鏁版嵁琛ㄥ瓧娈靛垪琛ㄦā鎬佹锛屾樉绀烘帶鍒�
+    tableColumns: [],      // 琛ㄦ牸瀛楁鍚嶅垪琛�
+    fields: null,          // 琛ㄥ崟锛屽彲閫夊瓧娈碉紙鍘婚噸鍚庯級
+    modalformlist: null,   // 鍩烘湰淇℃伅琛ㄥ崟瀛楁
+    formlist: null,        // 琛ㄥ崟缂栬緫妯℃�佹锛屽彲缂栬緫瀛楁
+    card: null,            // 缂栬緫鍏冪礌
+    menuloading: false,    // 鑿滃崟淇濆瓨涓�
+    closeloading: false,   // 鑿滃崟淇濆瓨涓�
+    settingVisible: false, // 鍏ㄥ眬閰嶇疆妯℃�佹
+    closeVisible: false,   // 鍏抽棴妯℃�佹
+    tables: [],            // 鍙敤琛ㄥ悕
+    selectedTables: [],    // 宸查�夎〃鍚�
+    originConfig: null,    // 鍘熷鑿滃崟
+    groupVisible: false,   // 鍏ㄥ眬閰嶇疆妯℃�佹
+    curgroup: null,        // 褰撳墠缁勶紝鏂板缓鎴栫紪杈�
+    sources: null,         // 琛ㄥ崟绫诲瀷
+    sqlVerifing: false,    // sql楠岃瘉
+    openEdition: ''        // 缂栬緫鐗堟湰鏍囪锛岄槻姝㈠浜烘搷浣�
+  }
+
+  /**
+   * @description 鏁版嵁棰勫鐞�
+   * 1銆佹寜閽厤缃瓨鍦ㄦ椂浣跨敤鎸夐挳閰嶇疆锛屼笉瀛樺湪鏃朵娇鐢ㄩ粯璁ら厤缃紙绀轰緥锛�
+   * 2銆佹ā鎬佹鏍囬涓嶅瓨鍦ㄦ椂锛屼娇鐢ㄦ寜閽爣棰�
+   * 3銆佽缃凡閫夎〃
+   * 4銆佽缃寜閽熀鏈俊鎭�
+   */
+  UNSAFE_componentWillMount () {
+    const {menu, editAction, tabConfig, subTabConfig, subConfig} = this.props
+
+    let _config = ''
+    let _tab = subTabConfig ? subTabConfig : tabConfig
+
+    let _menu = { // 涓婄骇鑿滃崟鏄笁绾ц彍鍗曟垨鏍囩椤�
+      type: _tab ? _tab.Template : menu.type,
+      tables: _tab ? _tab.tables : menu.LongParam.tables,
+      MenuID: _tab ? _tab.uuid : menu.MenuID,
+      MenuNo: _tab ? _tab.tabNo : menu.MenuNo,
+      MenuName: _tab ? _tab.tabName : menu.MenuName
+    }
+
+    if (subConfig) {
+      _config = subConfig
+    } else {
+      _config = JSON.parse(JSON.stringify(BaseConfig))
+    }
+
+    if (!_config.setting.title) {
+      _config.setting.title = editAction.label
+    }
+
+    // 涓昏彍鍗曞凡鏈夐�夋嫨鐨勮〃鍚嶏紝妯℃�佹娌℃湁琛ㄥ悕鏃讹紝澶嶅埗涓昏彍鍗曡〃鍚�
+    _config.tables = _config.tables.length === 0 ? _menu.tables : _config.tables
+
+    let _source = JSON.parse(JSON.stringify(SearchItems))
+    if (!!this.props.editTab) {
+      _source.push({
+        type: 'form',
+        label: this.state.dict['header.form.linkMain'],
+        subType: 'linkMain',
+        url: ''
+      })
+    }
+
+    this.setState({
+      openEdition: editAction.open_edition || '',
+      menu: _menu,
+      source: _source,
+      config: _config,
+      selectedTables: _config.tables || [],
+      originConfig: JSON.parse(JSON.stringify(_config)),
+      modalformlist: [
+        {
+          type: 'text',
+          key: 'supMenu',
+          label: this.state.dict['model.super'] + this.state.dict['model.menu'],
+          initVal: _menu.MenuName,
+          required: true,
+          readonly: true
+        },
+        {
+          type: 'text',
+          key: 'btnName',
+          label: '鎸夐挳鍚嶇О',
+          initVal: editAction.label,
+          required: true,
+          readonly: true
+        }
+      ]
+    })
+  }
+
+  /**
+   * @description 鑾峰彇鏁版嵁琛ㄤ俊鎭�
+   * 1銆佽幏鍙栫郴缁熶腑鍏ㄩ儴琛ㄥ悕
+   * 2銆佹牴鎹凡閫夎〃鍚嶏紝鑾峰彇琛ㄦ牸瀛楁鍒楄〃
+   */
+  componentDidMount () {
+    let param = {
+      func: 'sPC_Get_SelectedList',
+      LText: queryTableSql,
+      obj_name: 'data',
+      arr_field: 'TbName,Remark'
+    }
+
+    param.LText = Utils.formatOptions(param.LText)
+    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+
+    param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp) // 浜戠鏁版嵁楠岃瘉
+
+    Api.getSystemConfig(param).then(res => {
+      if (res.status) {
+        this.setState({
+          tables: res.data
+        })
+      } else {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 10
+        })
+      }
+    })
+
+    let deffers = this.state.selectedTables.map(item => {
+      return new Promise(resolve => {
+        Api.getSystemConfig({func: 'sPC_Get_FieldName', TBName: item.TbName}).then(res => {
+          res.TBName = item.TbName
+          resolve(res)
+        })
+      })
+    })
+
+    // 鑾峰彇瀛楁鍚庢暟鎹鐞嗭紝鏍规嵁绫诲瀷鍒嗕负text銆乶umber銆乨atetime銆乨ate
+    Promise.all(deffers).then(response => {
+      let _columns = []
+      response.forEach(res => {
+        if (res.status) {
+          let tabmsg = {
+            tableName: res.TBName,
+            columns: res.FDName.map(item => {
+              let _type = item.FieldType.toLowerCase()
+              let _decimal = 0
+              if (/^nvarchar/.test(_type)) {
+                _type = 'text'
+              } else if (/^int/.test(_type)) {
+                _type = 'number'
+              } else if (/^decimal/.test(_type)) {
+                _decimal = _type.split(',')[1]
+                _decimal = parseInt(_decimal)
+                _type = 'number'
+              } else if (/^datetime/.test(_type)) {
+                _type = 'datetime'
+              } else if (/^date/.test(_type)) {
+                _type = 'date'
+              } else {
+                _type = 'text'
+              }
+  
+              return {
+                field: item.FieldName,
+                label: item.FieldDec,
+                type: _type,
+                decimal: _decimal
+              }
+            })
+          }
+          _columns.push(tabmsg)
+        } else {
+          notification.warning({
+            top: 92,
+            message: res.message,
+            duration: 10
+          })
+        }
+      })
+
+      this.setState({
+        tableColumns: _columns
+      })
+    })
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  // 椤甸潰杩斿洖
+  handleViewBack = () => {
+    const {menu, editTab, editSubTab, tabConfig, subTabConfig, btnTab, btnTabConfig} = this.props
+
+    let _view = (subTabConfig && subTabConfig.Template) || (tabConfig && tabConfig.Template) || menu.LongParam.Template
+    
+    let param = {
+      editMenu: menu,
+      editTab: editTab,
+      tabConfig: tabConfig,
+      editSubTab: editSubTab,
+      subTabConfig: subTabConfig,
+      btnTab: btnTab,
+      btnTabConfig: btnTabConfig,
+      editAction: null,
+      subConfig: subTabConfig || tabConfig || null,
+      tabview: _view
+    }
+
+    this.props.handleView(param)
+  }
+
+  /**
+   * @description 琛ㄥ崟鍙樺寲
+   * 1銆佽〃鍗曟嫋鎷芥坊鍔犳椂锛屾鏌ユ槸鍚﹀瓨鍦ㄧず渚嬭〃鍗曪紝濡傚瓨鍦ㄥ垯鍘婚櫎绀轰緥
+   * 2銆佽〃鍗曠Щ鍔ㄥ悗锛屼繚瀛樼Щ鍔ㄥ悗鐨勯『搴�
+   * 3銆佹柊澧炶〃鍗曟椂锛岀洿鎺ユ墦寮�缂栬緫妗�
+   */
+  handleList = (list, group, elementId, newcard) => {
+    let _config = JSON.parse(JSON.stringify(this.state.config))
+
+    if (!group && !elementId) {
+      // 娌℃湁鍒嗙粍鏃讹紙鎷栨嫿娣诲姞锛�
+      if (list.length > _config.fields.length) {
+        _config.fields = list.filter(item => !item.origin)
+  
+        this.setState({
+          config: _config
+        }, () => {
+          this.handleForm(newcard)
+        })
+      } else {
+        _config.fields = list
+        this.setState({config: _config})
+      }
+    } else if (group && !elementId) {
+      // 瀛樺湪鍒嗙粍鏃讹紝鎷栨嫿娣诲姞
+      if (list.length > group.sublist.length) {
+        group.sublist = list
+        _config.groups = _config.groups.map(item => {
+          if (item.uuid === group.uuid) {
+            return group
+          } else {
+            return item
+          }
+        })
+  
+        this.setState({
+          config: _config
+        }, () => {
+          this.handleForm(newcard)
+        })
+      } else {
+        group.sublist = list
+        _config.groups = _config.groups.map(item => {
+          if (item.uuid === group.uuid) {
+            return group
+          } else {
+            return item
+          }
+        })
+        this.setState({config: _config})
+      }
+    } else if (group && elementId) {
+      // 淇敼宸叉湁鍏冪礌鐨勫垎缁�
+      let element = null
+      _config.groups.forEach(item => {
+        item.sublist = item.sublist.filter(cell => {
+          if (cell.uuid !== elementId) {
+            return true
+          } else {
+            element = cell
+            return false
+          }
+        })
+      })
+
+      group.sublist.push(element)
+
+      _config.groups = _config.groups.map(item => {
+        if (item.uuid === group.uuid) {
+          return group
+        } else {
+          return item
+        }
+      })
+
+      this.setState({
+        config: _config
+      })
+    }
+  }
+
+  /**
+   * @description 琛ㄥ崟缂栬緫
+   * 1銆佹樉绀虹紪杈戝脊绐�-visible
+   * 2銆佷繚瀛樼紪杈戦」-card
+   * 3銆佽缃紪杈戝弬鏁伴」-formlist
+   */
+  handleForm = (_card, type) => {
+    const {menu, tabConfig, subTabConfig} = this.props
+    let card = JSON.parse(JSON.stringify(_card))
+
+    if (type === 'copy') {
+      card.originUuid = card.uuid
+      card.uuid = Utils.getuuid()
+      card.focus = true
+
+      // 澶嶅埗鍒板壀鍒囨澘
+      let oInput = document.createElement('input')
+      let val = JSON.parse(JSON.stringify(card))
+      val.copyType = 'form'
+      val.uuid = Utils.getuuid()
+
+      delete val.originUuid
+
+      oInput.value = window.btoa(window.encodeURIComponent(JSON.stringify(val)))
+      document.body.appendChild(oInput)
+      oInput.select()
+      document.execCommand('Copy')
+      oInput.className = 'oInput'
+      oInput.style.display = 'none'
+      document.body.removeChild(oInput)
+    }
+
+    const { config } = this.state
+    let _inputfields = []
+    let _linkableFields = []
+    let _linksupFields = [{
+      value: '',
+      text: '绌�'
+    }]
+    let _formfields = []
+
+    // 璁剧疆涓嬫媺鑿滃崟鍙叧鑱斿瓧娈�(涓婄骇涓庝笅绾�)
+    if (config.groups.length > 0) {
+      config.groups.forEach(group => {
+        let sublist = group.sublist.filter(item => item.type === 'text' || item.type === 'number')
+        _inputfields = [..._inputfields, ...sublist]
+
+        let suplist = group.sublist.filter(item => item.type === 'select' || item.type === 'link')
+        _formfields = [..._formfields, ...suplist]
+      })
+    } else {
+      _inputfields = config.fields.filter(item => item.type === 'text' || item.type === 'number')
+      
+      _formfields = config.fields.filter(item => item.type === 'select' || item.type === 'link')
+    }
+
+    let uniq = new Map()
+    uniq.set(card.field, true)
+    _formfields.forEach(item => {
+      if (item.field && !uniq.has(item.field)) {
+        uniq.set(item.field, true)
+
+        _linkableFields.push({
+          value: item.field,
+          text: item.label + ' (琛ㄥ崟)'
+        })
+        _linksupFields.push({
+          value: item.field,
+          text: item.label
+        })
+      }
+    })
+
+    if (subTabConfig) {
+      subTabConfig.columns.forEach(col => {
+        if (col.field && !uniq.has(col.field)) {
+          uniq.set(col.field, true)
+
+          _linkableFields.push({
+            value: col.field,
+            text: col.label + ' (鏄剧ず鍒�)'
+          })
+        }
+      })
+    } else if (tabConfig) {
+      tabConfig.columns.forEach(col => {
+        if (col.field && !uniq.has(col.field)) {
+          uniq.set(col.field, true)
+
+          _linkableFields.push({
+            value: col.field,
+            text: col.label + ' (鏄剧ず鍒�)'
+          })
+        }
+      })
+    } else if (menu.LongParam) {
+      menu.LongParam.columns.forEach(col => {
+        if (col.field && !uniq.has(col.field)) {
+          uniq.set(col.field, true)
+
+          _linkableFields.push({
+            value: col.field,
+            text: col.label + ' (鏄剧ず鍒�)'
+          })
+        }
+      })
+    }
+
+    if (card.linkSubField && card.linkSubField.length > 0) {
+      let fields = _inputfields.map(item => item.field)
+      card.linkSubField = card.linkSubField.filter(item => fields.includes(item))
+    }
+
+    let roleList = []
+    if (this.props.sysRoles && this.props.sysRoles.length > 0) {
+      roleList = this.props.sysRoles.map(role => {
+        return {
+          uuid: role.uuid,
+          field: role.value,
+          label: role.text
+        }
+      })
+    }
+
+    this.setState({
+      visible: true,
+      modalType: type,
+      card: card,
+      formlist: getModalForm(card, _inputfields, _linkableFields, _linksupFields, !!this.props.editTab, roleList)
+    })
+  }
+
+  /**
+   * @description 缂栬緫鍚庢彁浜�
+   * 1銆佽幏鍙栫紪杈戝悗鐨勮〃鍗曚俊鎭�
+   * 2銆佸幓闄ゅ彲鑳藉瓨鍦ㄧ殑绀轰緥琛ㄥ崟
+   * 3銆侀�氳繃loading鍒锋柊
+   */
+  handleSubmit = () => {
+    const { card, modalType } = this.state
+
+    this.formRef.handleConfirm().then(res => {
+      let _config = JSON.parse(JSON.stringify(this.state.config))
+      let fieldrepet = false // 瀛楁閲嶅
+      let labelrepet = false // 鎻愮ず鏂囧瓧閲嶅
+
+      if (modalType === 'copy' && card.originUuid) {
+        if (_config.groups.length > 0) {
+          _config.groups = _config.groups.map(group => {
+            let _index = null
+            group.sublist.forEach((item, index) => {
+              if (item.uuid === card.originUuid) {
+                _index = index
+              }
+
+              if (item.uuid !== res.uuid && item.field === res.field) {
+                fieldrepet = true
+              } else if (item.uuid !== res.uuid && item.label === res.label) {
+                labelrepet = true
+              }
+            })
+
+            if (_index !== null) {
+              group.sublist.splice(_index + 1, 0, res)
+            }
+
+            return group
+          })
+        } else {
+          let _index = null
+          _config.fields.forEach((item, index) => {
+            if (item.uuid === card.originUuid) {
+              _index = index
+            }
+
+            if (item.uuid !== res.uuid && item.field === res.field) {
+              fieldrepet = true
+            } else if (item.uuid !== res.uuid && item.label === res.label) {
+              labelrepet = true
+            }
+          })
+
+          _config.fields.splice(_index + 1, 0, res)
+        }
+      } else {
+        if (_config.groups.length > 0) {
+          _config.groups.forEach(group => {
+            group.sublist = group.sublist.map(item => {
+              if (item.uuid !== res.uuid && item.field === res.field) {
+                fieldrepet = true
+              } else if (item.uuid !== res.uuid && item.label === res.label) {
+                labelrepet = true
+              }
+
+              if (item.uuid === res.uuid) {
+                return res
+              } else {
+                return item
+              }
+            })
+          })
+        } else {
+          _config.fields = _config.fields.map(item => {
+            if (item.uuid !== res.uuid && item.field === res.field) {
+              fieldrepet = true
+            } else if (item.uuid !== res.uuid && item.label === res.label) {
+              labelrepet = true
+            }
+
+            if (item.uuid === res.uuid) {
+              return res
+            } else {
+              return item
+            }
+          })
+        }
+      }
+
+      if (fieldrepet) {
+        notification.warning({
+          top: 92,
+          message: '瀛楁宸插瓨鍦紒',
+          duration: 10
+        })
+        return
+      } else if (labelrepet) {
+        notification.warning({
+          top: 92,
+          message: '鍚嶇О宸插瓨鍦紒',
+          duration: 10
+        })
+        return
+      }
+
+      _config.fields = _config.fields.filter(item => !item.origin)
+
+      if ((res.type === 'select' || res.type === 'multiselect' || res.type === 'link') && res.resourceType === '1' && /\s/.test(res.dataSource)) {
+        this.setState({
+          sqlVerifing: true
+        })
+
+        let param = {
+          func: 's_debug_sql',
+          LText: res.dataSource
+        }
+
+        param.LText = param.LText.replace(/@\$|\$@/ig, '')
+        
+        param.LText = Utils.formatOptions(param.LText)
+        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+        param.secretkey = Utils.encrypt(param.LText, param.timestamp)
+
+        if (window.GLOB.mainSystemApi && res.database === 'sso') {
+          param.rduri = window.GLOB.mainSystemApi
+        }
+        
+        Api.getLocalConfig(param).then(result => {
+          if (result.status) {
+            this.setState({
+              sqlVerifing: false,
+              config: _config,
+              modalType: null,
+              card: null,
+              visible: false
+            })
+          } else {
+            this.setState({sqlVerifing: false})
+            
+            Modal.error({
+              title: result.message
+            })
+          }
+        })
+      } else {
+        this.setState({
+          config: _config,
+          modalType: null,
+          card: null,
+          visible: false
+        })
+      }
+    })
+  }
+
+  /**
+   * @description 琛ㄥ崟鍒犻櫎骞跺埛鏂�
+   */
+  closeForm = (card) => {
+    let _this = this
+
+    confirm({
+      content: `纭畾鍒犻櫎<<${card.label}>>鍚楋紵`,
+      onOk() {
+        let _config = JSON.parse(JSON.stringify(_this.state.config))
+
+        if (_config.groups.length > 0) {
+          _config.groups.forEach(group => {
+            group.sublist = group.sublist.filter(item => !(item.uuid === card.uuid))
+          })
+        } else {
+          _config.fields = _config.fields.filter(item => !(item.uuid === card.uuid))
+        }
+
+        _this.setState({
+          config: _config,
+        })
+      },
+      onCancel() {}
+    })
+  }
+
+  submitConfig = () => {
+    const { editAction } = this.props
+    const { config, menu, openEdition } = this.state
+
+    if ((!config.groups[0] && !config.fields[0]) || (config.fields[0] && config.fields[0].origin)) {
+      notification.warning({
+        top: 92,
+        message: '璇锋坊鍔犺〃鍗�',
+        duration: 10
+      })
+      return
+    }
+
+    let _LongParam = ''
+    let _config = {...config, tables: this.state.selectedTables}
+
+    try {
+      _LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(_config)))
+    } catch (e) {
+      notification.warning({
+        top: 92,
+        message: '缂栬瘧閿欒',
+        duration: 10
+      })
+      return
+    }
+
+    let param = {
+      func: 'sPC_ButtonParam_AddUpt',
+      ParentID: menu.MenuID,
+      MenuID: editAction.uuid,
+      MenuNo: menu.MenuNo,
+      Template: 'Modal',
+      MenuName: editAction.label,
+      PageParam: JSON.stringify({Template: 'Modal'}),
+      LongParam: _LongParam
+    }
+
+    if (openEdition) {
+      param.open_edition = openEdition
+    }
+
+    if (this.state.closeVisible) {
+      this.setState({
+        closeloading: true
+      })
+    } else {
+      this.setState({
+        menuloading: true
+      })
+    }
+
+    Api.getSystemConfig(param).then(response => {
+      if (response.status) {
+        this.setState({
+          openEdition: response.open_edition || '',
+          menuloading: false,
+          closeloading: false,
+          closeVisible: false,
+          originConfig: _config,
+          config: _config
+        })
+        notification.success({
+          top: 92,
+          message: '淇濆瓨鎴愬姛',
+          duration: 2
+        })
+      } else {
+        this.setState({
+          closeloading: false,
+          menuloading: false
+        })
+        notification.warning({
+          top: 92,
+          message: response.message,
+          duration: 10
+        })
+      }
+    })
+  }
+
+  cancelConfig = () => {
+    const { config, originConfig } = this.state
+    let _this = this
+
+    let isOrigin = config.fields.filter(item => item.origin).length > 0
+    if (isOrigin) {
+      confirm({
+        content: '灏氭湭鎻愪氦锛岀‘瀹氭斁寮冧繚瀛樺悧锛�',
+        onOk() {
+          _this.handleViewBack()
+        },
+        onCancel() {}
+      })
+    } else {
+
+      if (!is(fromJS(config), fromJS(originConfig))) {
+        this.setState({
+          closeVisible: true
+        })
+      } else {
+        this.handleViewBack()
+      }
+    }
+  }
+
+  /**
+   * @description 閫氳繃琛ㄥ瓧娈垫坊鍔犺〃鍗�
+   * 1銆佹鏌ユ槸鍚﹀凡閫夎〃鍚嶏紝涓洪�夋椂璀﹀憡鎻愮ず
+   * 2銆佽〃瀛楁鍚嶉�氳繃map鍘婚噸
+   * 3銆佹鏌ヨ〃鍗曚腑鐨勫凡閫夊瓧娈碉紝骞舵爣璁板凡閫�
+   */
+  queryField = () => {
+    const {selectedTables, tableColumns, config} = this.state
+    if (selectedTables.length === 0) {
+      notification.warning({
+        top: 92,
+        message: '璇烽�夋嫨琛ㄥ悕锛�',
+        duration: 10
+      })
+      return
+    }
+
+    let columns = new Map()
+    tableColumns.forEach(table => {
+      table.columns.forEach(column => {
+        columns.set(column.field, column)
+      })
+    })
+
+    if (config.groups.length > 1) {
+      config.groups.forEach(group => {
+        group.sublist.forEach(item => {
+          if (columns.has(item.field)) {
+            columns.set(item.field, {...item, selected: true})
+          }
+        })
+      })
+    } else {
+      config.fields.forEach(item => {
+        if (columns.has(item.field)) {
+          columns.set(item.field, {...item, selected: true})
+        }
+      })
+    }
+
+    this.setState({
+      tableVisible: true,
+      fields: [...columns.values()]
+    })
+  }
+
+  /**
+   * @description 閫夋嫨瀛楁鍚庢彁浜�
+   * 1銆佹病鏈夊彲閫夊瓧娈垫椂锛岀洿鎺ュ叧闂�
+   * 2銆佽幏鍙栧凡閫夊瓧娈�
+   * 3銆佷笌宸叉湁瀛楁瀵规瘮
+   * 4銆佹坊鍔犳柊澧炲瓧娈�
+   */
+  addFieldSubmit = () => {
+    if (!this.state.fields || this.state.fields.length === 0) {
+      this.setState({
+        tableVisible: false
+      })
+    }
+
+    let _config = JSON.parse(JSON.stringify(this.state.config))
+
+    let cards = this.refs.searchcard.state.selectCards
+    let columns = new Map()
+    cards.forEach(card => {
+      columns.set(card.field, card)
+    })
+
+    if (_config.groups.length > 1) {
+      _config.groups.forEach(group => {
+        let items = []
+        group.sublist.forEach(item => {
+          if (columns.has(item.field)) {
+            let cell = columns.get(item.field)
+    
+            if (cell.selected && cell.type === item.type) { // 鏁版嵁閫夋嫨鐘舵�佸強绫诲瀷鏈慨鏀规椂锛岀洿鎺ユ坊鍔�
+              items.push(item)
+            } else if (cell.selected) {                     // 鏁版嵁绫诲瀷淇敼鏃讹紝閲嶇疆绫诲瀷鍙婂垵濮嬪��
+              item.type = cell.type
+              item.initval = ''
+              items.push(item)
+            }
+            columns.delete(item.field)
+          } else if (!item.origin) {                        // 杩囨护绀轰緥椤�
+            items.push(item)
+          }
+        })
+        group.sublist = items
+      })
+      
+      let _columns = [...columns.values()]
+  
+      let _additems = _columns.map(item => { // 寰幆娣诲姞鏂板瀛楁
+        return {
+          uuid: Utils.getuuid(),
+          label: item.label,
+          field: item.field,
+          initval: '',
+          type: item.type,
+          resourceType: '0',
+          setAll: 'false',
+          options: [],
+          dataSource: '',
+          linkField: '',
+          valueField: '',
+          valueText: '',
+          orderBy: '',
+          orderType: 'asc',
+          decimal: 0,
+          min: '',
+          max: '',
+          readonly: 'false',
+          required: 'true'
+        }
+      })
+      _config.groups[_config.groups.length - 1].sublist = [..._config.groups[_config.groups.length - 1].sublist, ..._additems]
+
+    } else {
+      let items = []
+      _config.fields.forEach(item => {
+        if (columns.has(item.field)) {
+          let cell = columns.get(item.field)
+  
+          if (cell.selected && cell.type === item.type) { // 鏁版嵁閫夋嫨鐘舵�佸強绫诲瀷鏈慨鏀规椂锛岀洿鎺ユ坊鍔�
+            items.push(item)
+          } else if (cell.selected) {                     // 鏁版嵁绫诲瀷淇敼鏃讹紝閲嶇疆绫诲瀷鍙婂垵濮嬪��
+            item.type = cell.type
+            item.initval = ''
+            items.push(item)
+          }
+          columns.delete(item.field)
+        } else if (!item.origin) {                        // 杩囨护绀轰緥椤�
+          items.push(item)
+        }
+      })
+  
+      let _columns = [...columns.values()]
+  
+      _columns.forEach(item => { // 寰幆娣诲姞鏂板瀛楁
+        if (item.selected) {
+          let newcard = {
+            uuid: Utils.getuuid(),
+            label: item.label,
+            field: item.field,
+            initval: '',
+            type: item.type,
+            resourceType: '0',
+            setAll: 'false',
+            options: [],
+            dataSource: '',
+            linkField: '',
+            valueField: '',
+            valueText: '',
+            orderBy: '',
+            orderType: 'asc',
+            readonly: 'false',
+            required: 'true'
+          }
+  
+          items.push(newcard)
+        }
+      })
+  
+      _config.fields = items
+    }
+
+    this.setState({
+      config: _config
+    })
+    notification.success({
+      top: 92,
+      message: '娣诲姞鎴愬姛',
+      duration: 2
+    })
+  }
+
+  /**
+   * @description 娣诲姞琛ㄥ悕
+   * 1銆佽幏鍙栬〃淇℃伅
+   * 2銆佹楠屾槸鍚﹀凡缁忔坊鍔狅紝宸叉坊鍔犳椂璺宠繃
+   * 3銆侀�氳繃琛ㄥ悕鑾峰彇瀛楁闆嗭紝骞惰缃暟鎹被鍨�
+   */
+  onTableChange = (value) => {
+    const {tables, selectedTables, tableColumns} = this.state
+
+    let _table = tables.filter(item => item.TbName === value)[0]
+    let isSelected = !!selectedTables.filter(cell => cell.TbName === value)[0]
+
+    if (isSelected) return
+
+    this.setState({
+      selectedTables: [...selectedTables, _table]
+    })
+    Api.getSystemConfig({func: 'sPC_Get_FieldName', TBName: value}).then(res => {
+      if (res.status) {
+        let tabmsg = {
+          tableName: _table.name,
+          columns: res.FDName.map(item => {
+            let _type = item.FieldType.toLowerCase()
+            let _decimal = 0
+            if (/^nvarchar/.test(_type)) {
+              _type = 'text'
+            } else if (/^int/.test(_type)) {
+              _type = 'number'
+            } else if (/^decimal/.test(_type)) {
+              _decimal = _type.split(',')[1]
+              _decimal = parseInt(_decimal)
+              _type = 'number'
+            } else if (/^datetime/.test(_type)) {
+              _type = 'datetime'
+            } else if (/^date/.test(_type)) {
+              _type = 'date'
+            } else {
+              _type = 'text'
+            }
+
+            return {
+              field: item.FieldName,
+              label: item.FieldDec,
+              type: _type,
+              decimal: _decimal
+            }
+          })
+        }
+        this.setState({
+          tableColumns: [...tableColumns, tabmsg]
+        })
+      } else {
+        notification.warning({
+          top: 92,
+          message: res.message,
+          duration: 10
+        })
+      }
+    })
+  }
+
+  /**
+   * @description 鍒犻櫎琛ㄥ悕锛屽垹闄ゅ搴斿瓧娈甸泦
+   */
+  deleteTable = (table) => {
+    const {selectedTables, tableColumns} = this.state
+
+    this.setState({
+      selectedTables: selectedTables.filter(item => item.TbName !== table.TbName),
+      tableColumns: tableColumns.filter(item => item.tableName !== table.TbName)
+    })
+  }
+
+  /**
+   * @description 鍏ㄥ眬璁剧疆妯℃�佹
+   */
+  changeSetting = () => {
+    this.setState({
+      settingVisible: true
+    })
+  }
+
+  /**
+   * @description 淇濆瓨鍏ㄥ眬璁剧疆
+   */
+  settingSave = () => {
+    const {config} = this.state
+    this.settingRef.handleConfirm().then(res => {
+      this.setState({
+        config: {...config, setting: res},
+        settingVisible: false
+      })
+    })
+  }
+
+  handleGroup = (group) => {
+    let curgroup = ''
+
+    if (group) {
+      curgroup = group
+    } else {
+      curgroup = {
+        isnew: true,
+        label: '',
+        default: false,
+        uuid: Utils.getuuid(),
+        sublist: []
+      }
+    }
+
+    this.setState({
+      groupVisible: true,
+      curgroup: curgroup
+    })
+  }
+
+  closeGroup = (group) => {
+    let _this = this
+
+    confirm({
+      content: `纭畾鍒犻櫎鍒嗙粍<<${group.label}>>鍚楋紵`,
+      onOk() {
+        let _config = JSON.parse(JSON.stringify(_this.state.config))
+        _config.groups = _config.groups.filter(item => !(item.uuid === group.uuid))
+        let _length = _config.groups.length
+        
+        if (_length === 1) {
+          _config.fields = [...group.sublist, ..._config.groups[0].sublist]
+          _config.groups = []
+        } else {
+          _config.groups[_length - 1].sublist = [...group.sublist, ..._config.groups[_length - 1].sublist]
+        }
+
+        _this.setState({
+          config: _config
+        })
+      },
+      onCancel() {}
+    })
+  }
+
+  handleGroupSave = () => {
+    let _group = JSON.parse(JSON.stringify(this.state.curgroup))
+    let config = JSON.parse(JSON.stringify(this.state.config))
+
+    this.groupRef.handleConfirm().then(res => {
+      _group = {..._group, ...res.target}
+
+      if (_group.isnew) {
+        delete _group.isnew
+        config.groups.unshift(_group)
+
+        if (config.groups.length > 1) {
+          config.groups = config.groups.map(item => {
+            if (item.default) {
+              return res.default
+            } else {
+              return item
+            }
+          })
+        } else {
+          config.groups.push(res.default)
+        }
+      } else {
+        config.groups = config.groups.map(item => {
+          if (item.uuid === _group.uuid) {
+            return _group
+          } else if (item.default) {
+            return res.default
+          } else {
+            return item
+          }
+        })
+      }
+
+      config.fields = []
+
+      config.groups = config.groups.sort((a, b) => {
+        return a.sort - b.sort
+      })
+      
+      this.setState({
+        groupVisible: false,
+        curgroup: '',
+        config: config
+      })
+    })
+  }
+
+  editModalCancel = () => {
+    const { config, card } = this.state
+
+    if (card.focus) {
+      let _config = null
+      if (config.groups.length > 0) {
+        let _groups = config.groups.map(group => {
+          group.sublist = group.sublist.filter(item => item.uuid !== card.uuid)
+          return group
+        })
+        _config = {...config, groups: _groups}
+      } else {
+        let _fields = config.fields.filter(item => item.uuid !== card.uuid)
+        _config = {...config, fields: _fields}
+      }
+
+      this.setState({
+        card: null,
+        config: _config,
+        visible: false
+      })
+    } else {
+      this.setState({
+        card: null,
+        visible: false
+      })
+    }
+  }
+
+  /**
+   * @description 缂栬緫鍔熻兘瀹屾垚鏇存柊锛屽寘鎷В鍐绘寜閽�佺矘璐淬�佹浛鎹㈢瓑
+   */
+  updateConfig = (res) => {
+    if (res.type === 'paste') {
+      this.setState({
+        config: res.content
+      })
+    }
+  }
+
+  render () {
+    const { config, source } = this.state
+
+    return (
+      <div className="modal-form-board">
+        <DndProvider backend={HTML5Backend}>
+          <div className="tools">
+            <Collapse accordion defaultActiveKey="1" bordered={false}>
+              <Panel header={this.state.dict['header.menu.basedata']} key="0" id="modal-basedata">
+                <MenuForm
+                  dict={this.state.dict}
+                  formlist={this.state.modalformlist}
+                />
+                <div className="ant-col ant-form-item-label">
+                  <label title={this.state.dict['header.menu.table.add']}>
+                    {this.state.dict['header.menu.table.add']}
+                  </label>
+                </div>
+                <Select
+                  showSearch
+                  showArrow={false}
+                  className="tables"
+                  style={{ width: '100%' }}
+                  optionFilterProp="children"
+                  value={this.state.dict['header.menu.table.placeholder']}
+                  onChange={this.onTableChange}
+                  getPopupContainer={() => document.getElementById('modal-basedata')}
+                  filterOption={(input, option) => {
+                    return option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
+                  }}
+                > 
+                  {this.state.tables.map((table, index) => (
+                    <Option key={index} title={table.TbName} value={table.TbName}>{table.Remark}</Option>
+                  ))}
+                </Select>
+                {this.state.selectedTables.length > 0 && <List
+                  size="small"
+                  bordered
+                  dataSource={this.state.selectedTables}
+                  renderItem={(item, index) => <List.Item key={index} title={item.Remark + ' (' + item.TbName + ')'}>
+                    {item.Remark + ' (' + item.TbName + ')'}
+                    <Icon type="close" onClick={() => this.deleteTable(item)}/>
+                    <div className="bottom-mask"></div>
+                  </List.Item>}
+                />}
+              </Panel>
+              <Panel header={this.state.dict['header.menu.form']} key="1">
+                <div className="search-element">
+                  {source.map((item, index) => {
+                    return (<SourceElement key={index} content={item}/>)
+                  })}
+                </div>
+                <Button type="primary" block onClick={() => this.queryField()}>{this.state.dict['header.menu.form.add']}</Button>
+                <Button type="primary" block onClick={() => this.handleGroup()}>{this.state.dict['header.menu.group.add']}</Button>
+              </Panel>
+            </Collapse>
+          </div>
+          <div className="setting">
+            <Card title={this.state.dict['header.menu.form.configurable']} bordered={false} extra={
+              <div>
+                <EditComponent dict={this.state.dict} type="form" config={this.state.config} refresh={this.updateConfig}/>
+                <Button type="primary" onClick={this.submitConfig} loading={this.state.menuloading}>{this.state.dict['model.save']}</Button>
+                <Button onClick={this.cancelConfig}>{this.state.dict['model.back']}</Button>
+              </div>
+            } style={{ width: '100%' }}>
+              <Icon type="setting" onClick={this.changeSetting} />
+              <div className="ant-modal-content" style={{width: config.setting.width + '%'}}>
+                <button type="button" className="ant-modal-close">
+                  <span className="ant-modal-close-x"><Icon type="close"/></span>
+                </button>
+                <div className="ant-modal-header">
+                  <div className="ant-modal-title">{config.setting.title}</div>
+                </div>
+                <div className="ant-modal-body">
+                  <div className="modal-form">
+                    {config.groups.length > 0 &&
+                      config.groups.map(group => {
+                        return (
+                          <div key={group.uuid}>
+                            <div className="group-title">
+                              {!group.default ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+                                <div className="mk-popover-control">
+                                  <Icon className="edit" type="edit" onClick={() => {this.handleGroup(group)}} />
+                                  <Icon className="edit close" type="close" onClick={() => {this.closeGroup(group)}} />
+                                </div>
+                              } trigger="hover">
+                                <span>{group.label}</span>
+                              </Popover> : null}
+                              {group.default ? <span style={{color: '#bcbcbc'}}>{group.label}</span> : null}
+                            </div>
+                            <DragElement
+                              group={group}
+                              list={group.sublist}
+                              setting={config.setting}
+                              placeholder={this.state.dict['header.form.modal.placeholder']}
+                              handleList={this.handleList}
+                              handleForm={this.handleForm}
+                              closeForm={this.closeForm}
+                            />
+                          </div>
+                        )
+                      })
+                    }
+                    {config.groups.length === 0 ?
+                      <DragElement
+                        list={config.fields}
+                        setting={config.setting}
+                        placeholder={this.state.dict['header.form.modal.placeholder']}
+                        handleList={this.handleList}
+                        handleForm={this.handleForm}
+                        closeForm={this.closeForm}
+                      /> : null
+                    }
+                  </div>
+                </div>
+                <div className="ant-modal-footer">
+                  <div>
+                    <button type="button" className="ant-btn">
+                      <span>{this.state.dict['model.cancel']}</span>
+                    </button>
+                    <button type="button" className="ant-btn ant-btn-primary">
+                      <span>{this.state.dict['model.confirm']}</span>
+                    </button>
+                  </div>
+                  <div className="action-mask"></div>
+                </div>
+              </div>
+            </Card>
+          </div>
+        </DndProvider>
+        <Modal
+          title={this.state.modalType !== 'copy' ? this.state.dict['model.edit'] : this.state.dict['header.modal.form.copy']}
+          visible={this.state.visible}
+          width={700}
+          onCancel={this.editModalCancel}
+          onOk={this.handleSubmit}
+          confirmLoading={this.state.sqlVerifing}
+          destroyOnClose
+        >
+          {<ModalForm
+            dict={this.state.dict}
+            card={this.state.card}
+            formlist={this.state.formlist}
+            inputSubmit={this.handleSubmit}
+            wrappedComponentRef={(inst) => this.formRef = inst}
+          />}
+        </Modal>
+        <Modal
+          wrapClassName="modal-fields"
+          title={this.state.dict['model.edit']}
+          visible={this.state.tableVisible}
+          width={'65vw'}
+          maskClosable={false}
+          style={{minWidth: '900px', maxWidth: '1200px'}}
+          onOk={this.addFieldSubmit}
+          cancelText={this.state.dict['model.close']}
+          onCancel={() => { this.setState({ tableVisible: false }) }}
+          destroyOnClose
+        >
+          {this.state.fields && this.state.fields.length > 0 ?
+            <EditCard data={this.state.fields} ref="searchcard" type="search" /> : null
+          }
+          {(!this.state.fields || this.state.fields.length === 0) &&
+            <Empty />
+          }
+        </Modal>
+        <Modal
+          title={this.state.dict['model.edit']}
+          visible={this.state.settingVisible}
+          width={700}
+          maskClosable={false}
+          onOk={this.settingSave}
+          onCancel={() => { this.setState({ settingVisible: false }) }}
+          destroyOnClose
+        >
+          <SettingForm
+            config={config}
+            dict={this.state.dict}
+            isSubTab={!!this.props.editTab}
+            inputSubmit={this.settingSave}
+            wrappedComponentRef={(inst) => this.settingRef = inst}
+          />
+        </Modal>
+        <Modal
+          bodyStyle={{textAlign: 'center', color: '#000000', fontSize: '16px'}}
+          closable={false}
+          maskClosable={false}
+          visible={this.state.closeVisible}
+          onCancel={() => { this.setState({closeVisible: false}) }}
+          footer={[
+            <Button key="save" className="mk-btn mk-green" loading={this.state.closeloading} onClick={this.submitConfig}>{this.state.dict['model.save']}</Button>,
+            <Button key="confirm" className="mk-btn mk-yellow" onClick={this.handleViewBack}>{this.state.dict['model.notsave']}</Button>,
+            <Button key="cancel" onClick={() => { this.setState({closeVisible: false}) }}>{this.state.dict['model.cancel']}</Button>
+          ]}
+          destroyOnClose
+        >
+          {this.state.dict['header.menu.config.placeholder']}
+        </Modal>
+        <Modal
+          title={this.state.dict['header.menu.group.manage']}
+          visible={this.state.groupVisible}
+          width={700}
+          maskClosable={false}
+          onOk={this.handleGroupSave}
+          onCancel={() => { this.setState({ groupVisible: false }) }}
+          destroyOnClose
+        >
+          <GroupForm
+            config={config}
+            dict={this.state.dict}
+            group={this.state.curgroup}
+            inputSubmit={this.handleGroupSave}
+            wrappedComponentRef={(inst) => this.groupRef = inst}
+          />
+        </Modal>
+      </div>
+    )
+  }
+}
+
+const mapStateToProps = (state) => {
+  return {
+    sysRoles: state.sysRoles
+  }
+}
+
+const mapDispatchToProps = () => {
+  return {}
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(ComModalConfig)
\ No newline at end of file
diff --git a/src/menu/modalconfig/index.scss b/src/menu/modalconfig/index.scss
new file mode 100644
index 0000000..1576160
--- /dev/null
+++ b/src/menu/modalconfig/index.scss
@@ -0,0 +1,295 @@
+.modal-form-board {
+  position: fixed;
+  z-index: 1070;
+  padding-top: 48px;
+  top: 0px;
+  left: 0px;
+  right: 0px;
+  bottom: 0px;
+  background: rgba(0, 0, 0, 0.35);
+  display: flex;
+  .tools {
+    flex: 1;
+    background: #ffffff;
+    border-right: 1px solid #d9d9d9;
+    height: 100%;
+    overflow-y: auto;
+    padding-bottom: 30px;
+    .ant-collapse-item {
+      border: 0;
+    }
+    .ant-input-search {
+      margin-top: 10px;
+    }
+    .ant-collapse-item.ant-collapse-item-active {
+      border-bottom: 1px solid #d9d9d9;
+    }
+    .ant-collapse .ant-collapse-header {
+      padding: 11px 16px 10px 40px;
+      border-bottom: 1px solid #d9d9d9;
+      background: #1890ff;
+      color: #ffffff;
+    }
+    .ant-collapse-content-box {
+      .ant-form-item {
+        margin-bottom: 10px;
+        .ant-form-item-label {
+          text-align: left;
+          height: 25px;
+          line-height: 25px;
+        }
+      }
+      .ant-btn {
+        margin-bottom: 10px;
+      }
+    }
+    .search-element {
+      padding-top: 10px;
+      li {
+        padding: 0px 16px 10px;
+        div {
+          cursor: move;
+        }
+      }
+    }
+    .tables {
+      .ant-select-selection-selected-value {
+        opacity: 0.4!important;
+      }
+    }
+    .ant-list {
+      margin-top: 20px;
+      .ant-list-item {
+        display: -webkit-box;
+        padding-right: 20px;
+        position: relative;
+        padding-left: 5px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        -webkit-line-clamp: 2;
+        -webkit-box-orient: vertical;
+        width: 100%;
+        .anticon {
+          position: absolute;
+          top: 0px;
+          right: 0px;
+          padding: 3px 3px 10px 10px;
+          cursor: pointer;
+        }
+        .bottom-mask {
+          position: absolute;
+          width: 100%;
+          height: 8px;
+          bottom: 0;
+          left: 0;
+          background: #ffffff;
+          border-radius: 8px;
+        }
+      }
+    }
+  }
+  .tools::-webkit-scrollbar {
+    width: 4px;
+  }
+  .tools::-webkit-scrollbar-thumb {
+    border-radius: 5px;
+    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.08);
+    background: rgba(0, 0, 0, 0.08);
+  }
+  .tools::-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);
+  }
+  .setting {
+    position: relative;
+    width: calc(100vw - 235px);
+    height: 100%;
+    overflow-y: hidden;
+    background: #ffffff;
+    .ant-card-head {
+      min-height: 44px;
+    }
+    .ant-card-head-title {
+      padding: 5px 0;
+      color: #1890ff;
+    }
+    .ant-card-extra {
+      padding: 5px 0;
+      button {
+        margin-left: 20px;
+      }
+    }
+    .ant-card-body {
+      position: relative;
+      padding: 0;
+      .ant-modal-content {
+        max-width: 95%;
+        margin: 0 auto;
+        margin-top: 30px;
+        .ant-modal-header {
+          position: relative;
+          z-index: 10;
+          background: transparent;
+        }
+        .ant-modal-close {
+          opacity: 0.3;
+        }
+        .ant-modal-footer {
+          position: relative;
+          button {
+            opacity: 0.3;
+          }
+        }
+        .action-mask {
+          position: absolute;
+          top: 0px;
+          left: 0px;
+          right: 0px;
+          bottom: 0px;
+        }
+      }
+
+      .modal-form {
+        padding: 0px 24px;
+        min-height: 87px;
+        .group-title {
+          position: relative;
+          min-height: 22px;
+          margin-bottom: 10px;
+          padding-top: 10px;
+          border-bottom: 1px solid #e8e8e8;
+
+          span {
+            padding: 0 5px 5px;
+          }
+        }
+        > .ant-row {
+          min-height: 120px;
+        }
+        .ant-row .ant-col-6 {
+          padding: 0 12px!important;
+        }
+        .ant-row.ant-form-item .ant-col {
+          padding: 0;
+        }
+        .textarea2, .textarea4 {
+          padding-left: 7px;
+        }
+        .page-card {
+          position: relative;
+          background: #ffffff;
+          border-radius: 2px;
+          margin-bottom: 15px;
+          .ant-form-item {
+            cursor: move;
+            display: flex;
+            margin-bottom: 0px;
+            .ant-form-item-label {
+              overflow: visible;
+              position: relative;
+              height: 40px;
+              label {
+                width: 100%;
+                cursor: move;
+                overflow: hidden;
+                display: inline-block;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+              }
+            }
+            .ant-form-item-control-wrapper {
+              .ant-select {
+                width: 100%;
+                margin-top: 4px;
+              }
+              .ant-calendar-picker {
+                width: 100%;
+                margin-top: 4px;
+              }
+              .ant-input-number {
+                width: 100%;
+                margin-top: 4px;
+              }
+              .input-mask {
+                position: absolute;
+                top: 0;
+                left: 0;
+                right: 0;
+                bottom: 0;
+                opacity: 0;
+              }
+            }
+            .ant-col-cuslabel {
+              width: 10.5%;
+            }
+            .ant-col-cuswrap {
+              width: 89.5%;
+            }
+          }
+        }
+        .ant-calendar-picker {
+          min-width: 100px!important;
+        }
+      }
+      > .anticon-setting {
+        position: absolute;
+        font-size: 16px;
+        right: 15px;
+        top: 10px;
+      }
+      .paste-Icon {
+        position: absolute;
+        font-size: 16px;
+        right: 15px;
+        top: 65px;
+      }
+    }
+  }
+  .setting:hover {
+    overflow-y: auto;
+  }
+  .setting::-webkit-scrollbar {
+    width: 7px;
+  }
+  .setting::-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);
+  }
+  .setting::-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);
+  }
+}
+
+.modal-fields {
+  .ant-modal {
+    top: 50px;
+    padding-bottom: 5px;
+    .ant-modal-body {
+      max-height: calc(100vh - 190px);
+      overflow-y: auto;
+      .ant-empty {
+        margin: 15vh 8px;
+      }
+    }
+    .ant-modal-body::-webkit-scrollbar {
+      width: 7px;
+    }
+    .ant-modal-body::-webkit-scrollbar-thumb {
+      border-radius: 5px;
+      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
+      background: rgba(0, 0, 0, 0.13);
+    }
+    .ant-modal-body::-webkit-scrollbar-track {
+      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
+      border-radius: 3px;
+      border: 1px solid rgba(0, 0, 0, 0.07);
+      background: rgba(0, 0, 0, 0);
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/menu/searchcomponent/index.jsx b/src/menu/searchcomponent/index.jsx
index 0556145..327004c 100644
--- a/src/menu/searchcomponent/index.jsx
+++ b/src/menu/searchcomponent/index.jsx
@@ -21,7 +21,6 @@
 class SearchComponent extends Component {
   static propTpyes = {
     config: PropTypes.object,        // 閰嶇疆淇℃伅
-    // optionLibs: PropTypes.any,       // 涓嬫媺瀛楀吀
     updatesearch: PropTypes.func     // 鏇存柊
   }
 
diff --git a/src/tabviews/commontable/index.jsx b/src/tabviews/commontable/index.jsx
index e03963f..64a04a3 100644
--- a/src/tabviews/commontable/index.jsx
+++ b/src/tabviews/commontable/index.jsx
@@ -908,6 +908,7 @@
   }
 
   render() {
+    const { menuType } = this.props
     const { BID, setting, searchlist, pageSize, actions, columns, loadingview, viewlost, pickup, config, triggerBtn, userConfig, tabActive, chartId, search, selectedData } = this.state
 
     return (
@@ -1068,7 +1069,7 @@
             </Tabs>)
           )
         }
-        {options.sysType !== 'cloud' ? <Button
+        {options.sysType !== 'cloud' && menuType !== 'HS' ? <Button
           icon="copy"
           shape="circle"
           className="common-table-copy"
diff --git a/src/tabviews/custom/components/card/data-card/index.scss b/src/tabviews/custom/components/card/data-card/index.scss
index edace1d..423d9bb 100644
--- a/src/tabviews/custom/components/card/data-card/index.scss
+++ b/src/tabviews/custom/components/card/data-card/index.scss
@@ -23,6 +23,7 @@
   .prev-page.disabled {
     img {
       cursor: not-allowed;
+      opacity: 0.4;
     }
   }
   .card-row-list::after {
diff --git a/src/tabviews/custom/components/chart/antv-bar-line/index.jsx b/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
index 1ca90a9..0a7e252 100644
--- a/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
+++ b/src/tabviews/custom/components/chart/antv-bar-line/index.jsx
@@ -102,8 +102,11 @@
     }
 
     let showHeader = false
-    if (config.plot.title || _config.plot.datatype === 'statistics') {
+    if (config.plot.title || _config.plot.datatype === 'statistics' || config.search.length > 0) {
       showHeader = true
+      _config.plot.height = _config.plot.height - 80
+    } else {
+      _config.plot.height = _config.plot.height - 30
     }
 
     this.setState({
@@ -1077,7 +1080,7 @@
               }
             })}
           </div>
-          <div className={'canvas' + (empty ? ' empty' : '')} style={{minHeight: plot.height ? plot.height : 400}} id={this.state.chartId}></div>
+          <div className={'canvas' + (empty ? ' empty' : '')} id={this.state.chartId}></div>
         </div>
         {empty ? <Empty description={false}/> : null}
       </div>
diff --git a/src/tabviews/custom/components/chart/antv-bar-line/index.scss b/src/tabviews/custom/components/chart/antv-bar-line/index.scss
index 561bce9..9f58671 100644
--- a/src/tabviews/custom/components/chart/antv-bar-line/index.scss
+++ b/src/tabviews/custom/components/chart/antv-bar-line/index.scss
@@ -1,16 +1,24 @@
 .custom-line-chart-plot-box {
   background: #ffffff;
+  border-style: solid;
+  border-width: 0;
 
   > .chart-header {
     height: 45px;
     border-bottom: 1px solid #e8e8e8;
     overflow: hidden;
+    text-decoration: inherit;
+    font-weight: inherit;
+    font-style: inherit;
 
     .chart-title {
-      font-size: 16px;
+      // font-size: 16px;
       float: left;
       line-height: 45px;
       margin-left: 10px;
+      text-decoration: inherit;
+      font-weight: inherit;
+      font-style: inherit;
     }
   }
   
@@ -31,7 +39,8 @@
   .canvas {
     margin: 0;
     // border: 1px solid #e8e8e8;
-    padding: 25px 15px;
+    padding: 15px;
+    letter-spacing: 0px;
   }
   .canvas.empty {
     div {
diff --git a/src/tabviews/custom/components/tabs/antv-tabs/index.jsx b/src/tabviews/custom/components/tabs/antv-tabs/index.jsx
index 2ef9f4a..839ca01 100644
--- a/src/tabviews/custom/components/tabs/antv-tabs/index.jsx
+++ b/src/tabviews/custom/components/tabs/antv-tabs/index.jsx
@@ -54,7 +54,7 @@
     const { tabs } = this.state
 
     return (
-      <div className="menu-antv-tabs-wrap">
+      <div className="menu-antv-tabs-wrap" style={tabs.style}>
         <Tabs defaultActiveKey="1" tabPosition={tabs.setting.position} type={tabs.setting.tabStyle}>
           {tabs.subtabs.map(tab => (
             <TabPane tab={<span>{tab.icon ? <Icon type={tab.icon} /> : null}{tab.label}</span>} key={tab.uuid}>
diff --git a/src/tabviews/custom/components/tabs/antv-tabs/index.scss b/src/tabviews/custom/components/tabs/antv-tabs/index.scss
index a86b7d7..732ea1f 100644
--- a/src/tabviews/custom/components/tabs/antv-tabs/index.scss
+++ b/src/tabviews/custom/components/tabs/antv-tabs/index.scss
@@ -2,4 +2,6 @@
   position: relative;
   box-sizing: border-box;
   background: #ffffff;
+  border-style: solid;
+  border-width: 0;
 }
diff --git a/src/tabviews/zshare/normalTable/index.jsx b/src/tabviews/zshare/normalTable/index.jsx
index c97cbdd..da89069 100644
--- a/src/tabviews/zshare/normalTable/index.jsx
+++ b/src/tabviews/zshare/normalTable/index.jsx
@@ -856,10 +856,6 @@
 
     let selects = this.props.data.filter((item, _index) => selectedRowKeys.includes(_index))
 
-    // selectedRowKeys.forEach(item => {
-    //   selects.push(this.props.data[item])
-    // })
-
     this.props.chgSelectData(selects)
   }
 
@@ -893,9 +889,6 @@
     }
 
     let selects = this.props.data.filter((item, _index) => newkeys.includes(_index))
-    // newkeys.forEach(item => {
-    //   selects.push(this.props.data[item])
-    // })
     
     this.props.chgSelectData(selects)
   }
@@ -1022,7 +1015,7 @@
         {offset && <Affix offsetTop={offset} className="fix-header">
           <Table
             size="middle"
-            bordered={true}
+            bordered={setting.bordered !== 'false'}
             rowSelection={rowSelection}
             columns={this.state.columns.map(column => {
               return {
@@ -1036,7 +1029,7 @@
         </Affix>}
         <Table
           size="middle"
-          bordered={true}
+          bordered={setting.bordered !== 'false'}
           rowSelection={rowSelection}
           columns={this.state.columns}
           dataSource={_data}
diff --git a/src/templates/calendarconfig/index.jsx b/src/templates/calendarconfig/index.jsx
index 6ff2fa5..d37142f 100644
--- a/src/templates/calendarconfig/index.jsx
+++ b/src/templates/calendarconfig/index.jsx
@@ -34,7 +34,6 @@
 class SubTableConfig extends Component {
   static propTpyes = {
     menu: PropTypes.any,
-    optionLibs: PropTypes.any,
     reloadmenu: PropTypes.func,
     handleView: PropTypes.func
   }
@@ -52,7 +51,6 @@
     closeVisible: false,     // 鍏抽棴妯℃�佹
     originConfig: null,      // 鍘熼厤缃�
     tabviews: [],            // 鎵�鏈夋爣绛鹃〉
-    optionLibs: null,        // 鑷畾涔変笅鎷夐�夐」搴�
     activeKey: '0',          // 榛樿灞曞紑鍩烘湰淇℃伅
     pasteContent: null,      // 绮樿创鍐呭
     openEdition: '',         // 缂栬緫鐗堟湰鏍囪锛岄槻姝㈠浜烘搷浣�
@@ -65,7 +63,7 @@
    * 2銆佽缃搷浣滅被鍨嬨�佸師濮嬭彍鍗曚俊鎭紙姣忔淇濆瓨鍚庨噸缃級銆佸凡浣跨敤琛ㄥ強鍩烘湰淇℃伅琛ㄥ崟
    */
   UNSAFE_componentWillMount () {
-    const { menu, optionLibs } = this.props
+    const { menu } = this.props
     let _LongParam = menu.LongParam
     let _config = ''
 
@@ -74,21 +72,6 @@
       _config.isAdd = true
     } else {
       _config = _LongParam
-      _config.search.forEach(item => {
-        if (
-          (item.type === 'select' || item.type === 'multiselect' || item.type === 'link') &&
-          item.resourceType === '0' &&
-          item.options && item.options.length > 0
-        ) {
-          optionLibs.set(menu.MenuID + item.uuid, {
-            uuid: menu.MenuID + item.uuid,
-            label: item.label,
-            parname: menu.MenuName,
-            type: 'search',
-            options: item.options
-          })
-        }
-      })
     }
 
     if (_config.type === 'user') {
@@ -112,7 +95,6 @@
 
     this.setState({
       openEdition: menu.open_edition || '',
-      optionLibs: optionLibs,
       activeKey: menu.activeKey || '0',
       config: _config,
       originMenu: fromJS(_config).toJS(),
@@ -234,7 +216,6 @@
   handleViewBack = () => {
     let param = {
       editMenu: null,
-      optionLibs: null,
       editTab: null,
       tabConfig: null,
       subTabConfig: null,
@@ -533,7 +514,7 @@
    */
   setSubConfig = () => {
     const { menu } = this.props
-    const { config, originMenu, optionLibs, activeKey, openEdition } = this.state
+    const { config, originMenu, activeKey, openEdition } = this.state
 
     if (config.isAdd) { // 鏂板缓鑿滃崟锛屾彁绀鸿彍鍗曞皻鏈繚瀛�
       notification.warning({
@@ -579,7 +560,6 @@
       _Menu.open_edition = openEdition  // 鏇存柊鐗堟湰鍙�
 
       let param = {
-        optionLibs: optionLibs,
         editMenu: _Menu,
         editTab: fromJS(config.tab).toJS(),
         tabConfig: null,
@@ -720,12 +700,10 @@
   /**
    * @description 鏇存柊鎼滅储鏉′欢閰嶇疆淇℃伅
    */
-  updatesearch = (config, options) => {
-    const { optionLibs } = this.state
+  updatesearch = (config) => {
 
     this.setState({
-      config: config,
-      optionLibs: options || optionLibs
+      config: config
     })
   }
 
@@ -825,7 +803,6 @@
                 config={config}
                 pasteContent={this.state.pasteContent}
                 sysRoles={this.props.sysRoles}
-                optionLibs={this.state.optionLibs}
                 updatesearch={this.updatesearch}
               />
               <div className="calendar-wrap">
diff --git a/src/templates/comtableconfig/index.jsx b/src/templates/comtableconfig/index.jsx
index 5d8ab5e..b26feb3 100644
--- a/src/templates/comtableconfig/index.jsx
+++ b/src/templates/comtableconfig/index.jsx
@@ -37,7 +37,6 @@
 class ComTableConfig extends Component {
   static propTpyes = {
     menu: PropTypes.any,
-    optionLibs: PropTypes.any,
     reloadmenu: PropTypes.func,
     handleView: PropTypes.func
   }
@@ -57,7 +56,6 @@
     delActions: [],          // 鍒犻櫎鎸夐挳鍒楄〃
     copyActions: [],         // 澶嶅埗鎸夐挳缁�
     tabviews: [],            // 鎵�鏈夋爣绛鹃〉
-    optionLibs: null,        // 鑷畾涔変笅鎷夐�夐」搴�
     thawButtons: [],         // 宸查�夋嫨瑕佽В鍐荤殑鎸夐挳
     activeKey: '0',          // 榛樿灞曞紑鍩烘湰淇℃伅
     chartview: null,         // 褰撳墠瑙嗗浘
@@ -71,7 +69,7 @@
    * 2銆佽缃搷浣滅被鍨嬨�佸師濮嬭彍鍗曚俊鎭紙姣忔淇濆瓨鍚庨噸缃級銆佸凡浣跨敤琛ㄥ強鍩烘湰淇℃伅琛ㄥ崟
    */
   UNSAFE_componentWillMount () {
-    const { menu, optionLibs } = this.props
+    const { menu } = this.props
     let _LongParam = menu.LongParam
     let _config = ''
 
@@ -83,21 +81,6 @@
       _config.isAdd = true
     } else {
       _config = _LongParam
-      _config.search.forEach(item => {
-        if (
-          (item.type === 'select' || item.type === 'multiselect' || item.type === 'link') &&
-          item.resourceType === '0' &&
-          item.options && item.options.length > 0
-        ) {
-          optionLibs.set(menu.MenuID + item.uuid, {
-            uuid: menu.MenuID + item.uuid,
-            label: item.label,
-            parname: menu.MenuName,
-            type: 'search',
-            options: item.options
-          })
-        }
-      })
     }
 
     // 椤甸潰閰嶇疆涓繚鐣欒彍鍗曚俊鎭紝鍙敤浜庢暟鎹紶閫�
@@ -157,7 +140,6 @@
       config: _config,
       openEdition: menu.open_edition || '',
       activeKey: menu.activeKey || '0',
-      optionLibs: optionLibs,
       originActions: _oriActions,
       originMenu: fromJS(_config).toJS()
     })
@@ -882,7 +864,7 @@
    */
   setSubConfig = (item, type) => {
     const { menu } = this.props
-    const { config, originMenu, optionLibs, activeKey, openEdition } = this.state
+    const { config, originMenu, activeKey, openEdition } = this.state
 
     if (config.isAdd) { // 鏂板缓鑿滃崟锛屾彁绀鸿彍鍗曞皻鏈繚瀛�
       notification.warning({
@@ -948,7 +930,6 @@
       _Menu.open_edition = openEdition  // 鏇存柊鐗堟湰鍙�
 
       let param = {
-        optionLibs: optionLibs,
         editMenu: _Menu,
         editTab: !isbutton ? item : '',
         tabConfig: null,
@@ -1176,12 +1157,10 @@
   /**
    * @description 鏇存柊鎼滅储鏉′欢閰嶇疆淇℃伅
    */
-  updatesearch = (config, options) => {
-    const { optionLibs } = this.state
+  updatesearch = (config) => {
 
     this.setState({
-      config: config,
-      optionLibs: options || optionLibs
+      config: config
     })
   }
 
@@ -1377,7 +1356,6 @@
                 config={config}
                 pasteContent={this.state.pasteContent}
                 sysRoles={this.props.sysRoles}
-                optionLibs={this.state.optionLibs}
                 updatesearch={this.updatesearch}
               />
               <div className="chart-view" style={{position: 'relative'}}>
diff --git a/src/templates/formtabconfig/index.jsx b/src/templates/formtabconfig/index.jsx
index f8b0e1b..3d0de8a 100644
--- a/src/templates/formtabconfig/index.jsx
+++ b/src/templates/formtabconfig/index.jsx
@@ -38,7 +38,6 @@
 class ComTableConfig extends Component {
   static propTpyes = {
     menu: PropTypes.any,
-    optionLibs: PropTypes.any,
     btnTab: PropTypes.object,
     config: PropTypes.any,
     handleView: PropTypes.func
@@ -67,7 +66,6 @@
     profileVisible: false,   // 楠岃瘉淇℃伅妯℃�佹
     editgroup: null,         // 褰撳墠缂栬緫缁�
     groupVisible: false,     // 缂栬緫缁勬ā鎬佹
-    optionLibs: null,        // 鑷畾涔変笅鎷夐�夐」搴�
     activeKey: '0',          // 榛樿灞曞紑鍩烘湰淇℃伅
     pasteVisible: false,     // 绮樿创妯℃�佹
     sqlVerifing: false,      // sql楠岃瘉
@@ -80,7 +78,7 @@
    * 2銆佽缃搷浣滅被鍨嬨�佸師濮嬭彍鍗曚俊鎭紙姣忔淇濆瓨鍚庨噸缃級銆佸凡浣跨敤琛ㄥ強鍩烘湰淇℃伅琛ㄥ崟
    */
   UNSAFE_componentWillMount () {
-    const { menu, btnTab, config, optionLibs } = this.props
+    const { menu, btnTab, config } = this.props
 
     let _config = ''
     let columns = []
@@ -104,24 +102,6 @@
       if (menu && menu.LongParam && menu.LongParam.setting) {
         _config.setting.primaryKey = menu.LongParam.setting.primaryKey
       }
-
-      _config.groups.forEach(group => {
-        group.sublist.forEach(item => {
-          if (
-            (item.type === 'select' || item.type === 'multiselect' || item.type === 'link') &&
-            item.resourceType === '0' &&
-            item.options && item.options.length > 0
-          ) {
-            optionLibs.set(btnTab.uuid + item.uuid, {
-              uuid: btnTab.uuid + item.uuid,
-              label: item.label,
-              parname: btnTab.label,
-              type: 'Modal',
-              options: item.options
-            })
-          }
-        })
-      })
     }
 
     if (!_config.tabgroups) {
@@ -153,7 +133,6 @@
       config: _config,
       activeKey: btnTab.activeKey || '0',
       openEdition: btnTab.open_edition || '',
-      optionLibs: optionLibs,
       columns: columns,
       originMenu: JSON.parse(JSON.stringify(_config)),
       selectedTables: _config.tables,
@@ -355,7 +334,6 @@
     let _tabview = menu ? menu.LongParam.Template : ''
     let param = {
       editMenu: menu,
-      optionLibs: this.state.optionLibs,
       editTab: null,
       tabConfig: null,
       editSubTab: null,
@@ -534,8 +512,7 @@
    * 3銆佹坊鍔犳垨缂栬緫鍒楋紝淇濆瓨鏃讹紝濡傛寜閽綅缃缃负琛ㄦ牸锛屽垯淇敼鎿嶄綔鍒楁樉绀虹姸鎬�
    */
   handleSubmit = () => {
-    const { btnTab } = this.props
-    const { config, modaltype, optionLibs, card } = this.state
+    const { config, modaltype, card } = this.state
 
     if (modaltype === 'search') {
       this.modalFormRef.handleConfirm().then(res => {
@@ -548,19 +525,6 @@
             duration: 5
           })
           return
-        }
-        if ( // 鏇存柊涓嬫媺瀛楀吀
-          (res.type === 'select' || res.type === 'multiselect' || res.type === 'link') &&
-          res.resourceType === '0' &&
-          res.options && res.options.length > 0
-        ) {
-          optionLibs.set(btnTab.uuid + res.uuid, {
-            uuid: btnTab.uuid + res.uuid,
-            label: res.label,
-            parname: btnTab.label,
-            type: 'Modal',
-            options: res.options
-          })
         }
 
         let _groups = null
@@ -654,7 +618,6 @@
               this.setState({
                 sqlVerifing: false,
                 config: {..._config, groups: _groups},
-                optionLibs: optionLibs,
                 modaltype: ''
               })
             } else {
@@ -668,7 +631,6 @@
         } else {
           this.setState({
             config: {..._config, groups: _groups},
-            optionLibs: optionLibs,
             modaltype: ''
           })
         }
@@ -1560,7 +1522,6 @@
 
           let param = {
             editMenu: menu,
-            optionLibs: this.state.optionLibs,
             editTab: btn,
             tabConfig: null,
             editSubTab: null,
@@ -2005,7 +1966,6 @@
             card={this.state.card}
             formlist={this.state.formlist}
             inputSubmit={this.handleSubmit}
-            optionLibs={this.state.optionLibs}
             wrappedComponentRef={(inst) => this.modalFormRef = inst}
           />
         </Modal>
diff --git a/src/templates/menuconfig/editthdmenu/index.jsx b/src/templates/menuconfig/editthdmenu/index.jsx
index b706e1d..0f35f60 100644
--- a/src/templates/menuconfig/editthdmenu/index.jsx
+++ b/src/templates/menuconfig/editthdmenu/index.jsx
@@ -76,7 +76,6 @@
     btnTabConfig: null,     // 鎵撳紑鏂版爣绛炬寜閽厤缃�
     handleMVisible: false,  // 娣诲姞鎴栦慨鏀硅彍鍗曟ā鎬佹锛堣鑹叉潈闄愬垎閰嶇瓑锛�
     sysMenu: false,         // 娣诲姞鎴栫紪杈戣彍鍗曪紙瑙掕壊鏉冮檺鍒嗛厤绛夛級
-    optionLibs: null,       // 鑷畾涔変笅鎷夐�夐」搴�
     fstMenuId: null,        // 涓�绾ц彍鍗旾d
     fstMenuList: null       // 涓�绾ц彍鍗曞垪琛�
   }
@@ -211,7 +210,6 @@
               type: 'edit',
               editMenu: _menu,
               loading: false,
-              optionLibs: new Map(), // 缂栬緫鏃讹紝鍒濆鍖栦负绌�
               tabview: _menu.PageParam.Template
             }, () => {
               document.getElementById('root').style.overflowY = 'hidden'
@@ -220,8 +218,7 @@
             _menu.loadingFstMenuId = true
             this.setState({
               type: 'edit',
-              editMenu: _menu,
-              optionLibs: new Map()
+              editMenu: _menu
             })
           }
         } else {
@@ -523,7 +520,6 @@
       this.setState({
         loading: false,
         tabview: template.type === 'CustomPage' ? '' : template.type,
-        optionLibs: new Map(), // 鏂板缓鏃讹紝鍒濆鍖栦笅鎷夐�夐」搴�
         editMenu: {
           ...editMenu,
           type: template.type,
@@ -735,7 +731,6 @@
             type: 'edit',
             editMenu: _menu,
             loading: false,
-            optionLibs: new Map(), // 缂栬緫鏃讹紝鍒濆鍖栦负绌�
             tabview: _menu.PageParam.Template
           }, () => {
             document.getElementById('root').style.overflowY = 'hidden'
@@ -864,7 +859,6 @@
         {this.state.tabview === 'TreePage' ?
           <TreePageConfig
             menu={this.state.editMenu}
-            optionLibs={this.state.optionLibs}
             reloadmenu={() => {this.props.reload()}}
             handleView={this.handleView}
           /> : null
@@ -872,7 +866,6 @@
         {this.state.tabview === 'CalendarPage' ?
           <CalendarPageConfig
             menu={this.state.editMenu}
-            optionLibs={this.state.optionLibs}
             reloadmenu={() => {this.props.reload()}}
             handleView={this.handleView}
           /> : null
@@ -880,7 +873,6 @@
         {this.state.tabview === 'CommonTable' ?
           <ComTableConfig
             menu={this.state.editMenu}
-            optionLibs={this.state.optionLibs}
             reloadmenu={() => {this.props.reload()}}
             handleView={this.handleView}
           /> : null
@@ -888,7 +880,6 @@
         {this.state.tabview === 'Modal' ?
           <ModalConfig
             menu={this.state.editMenu}
-            optionLibs={this.state.optionLibs}
             editTab={this.state.editTab}
             tabConfig={this.state.tabConfig}
             editSubTab={this.state.editSubTab}
@@ -903,7 +894,6 @@
         {this.state.tabview === 'SubTable' ?
           <SubTable
             menu={this.state.editMenu}
-            optionLibs={this.state.optionLibs}
             editTab={this.state.editTab}
             editSubTab={this.state.editSubTab}
             tabConfig={this.state.tabConfig}
@@ -916,7 +906,6 @@
         {this.state.tabview === 'FormTab' ?
           <FormTabConfig
             menu={this.state.editMenu}
-            optionLibs={this.state.optionLibs}
             btnTab={this.state.btnTab}
             config={this.state.subConfig}
             handleView={this.handleView}
diff --git a/src/templates/modalconfig/dragelement/card.jsx b/src/templates/modalconfig/dragelement/card.jsx
index e7436ea..9fb9bb1 100644
--- a/src/templates/modalconfig/dragelement/card.jsx
+++ b/src/templates/modalconfig/dragelement/card.jsx
@@ -1,6 +1,6 @@
 import React from 'react'
 import { useDrag, useDrop } from 'react-dnd'
-import { Icon, Select, DatePicker, Input, InputNumber, Button, Popover } from 'antd'
+import { Icon, Select, DatePicker, Input, InputNumber, Button, Popover, Switch, Radio, Checkbox } from 'antd'
 import moment from 'moment'
 import './index.scss'
 
@@ -92,6 +92,22 @@
     formItem = (<Input style={{marginTop: '4px'}} defaultValue={card.linkfield} />)
   } else if (card.type === 'linkMain') {
     formItem = (<Input style={{marginTop: '4px'}} />)
+  } else if (card.type === 'switch') {
+    formItem = (<Switch style={{marginTop: '8px'}} checked={card.initval}/>)
+  } else if (card.type === 'radio') {
+    formItem = (<Radio.Group style={{marginTop: '8px'}} value={1}>
+      <Radio value={1}>A</Radio>
+      <Radio value={2}>B</Radio>
+      <Radio value={3}>C</Radio>
+      <Radio value={4}>D</Radio>
+    </Radio.Group>)
+  } else if (card.type === 'checkbox') {
+    formItem = (<Checkbox.Group style={{marginTop: '8px'}} value={['A', 'C']}>
+      <Checkbox value="A">A</Checkbox>
+      <Checkbox value="B">B</Checkbox>
+      <Checkbox value="C">C</Checkbox>
+      <Checkbox value="D">D</Checkbox>
+    </Checkbox.Group>)
   }
 
   return (
diff --git a/src/templates/modalconfig/index.jsx b/src/templates/modalconfig/index.jsx
index a369e07..53313ee 100644
--- a/src/templates/modalconfig/index.jsx
+++ b/src/templates/modalconfig/index.jsx
@@ -33,7 +33,6 @@
 class ComModalConfig extends Component {
   static propTpyes = {
     menu: PropTypes.any,
-    optionLibs: PropTypes.any,
     editTab: PropTypes.any,
     editSubTab: PropTypes.any,
     tabConfig: PropTypes.any,
@@ -66,7 +65,6 @@
     originConfig: null,    // 鍘熷鑿滃崟
     groupVisible: false,   // 鍏ㄥ眬閰嶇疆妯℃�佹
     curgroup: null,        // 褰撳墠缁勶紝鏂板缓鎴栫紪杈�
-    optionLibs: null,      // 鑷畾涔変笅鎷夐�夐」搴�
     sources: null,         // 琛ㄥ崟绫诲瀷
     sqlVerifing: false,    // sql楠岃瘉
     openEdition: ''        // 缂栬緫鐗堟湰鏍囪锛岄槻姝㈠浜烘搷浣�
@@ -80,7 +78,7 @@
    * 4銆佽缃寜閽熀鏈俊鎭�
    */
   UNSAFE_componentWillMount () {
-    const {menu, editAction, tabConfig, subTabConfig, subConfig, optionLibs} = this.props
+    const {menu, editAction, tabConfig, subTabConfig, subConfig} = this.props
 
     let _config = ''
     let _tab = subTabConfig ? subTabConfig : tabConfig
@@ -95,42 +93,6 @@
 
     if (subConfig) {
       _config = subConfig
-
-      if (_config.groups.length > 0) {
-        _config.groups.forEach(group => {
-          group.sublist.forEach(item => {
-            if (
-              (item.type === 'select' || item.type === 'multiselect' || item.type === 'link') &&
-              item.resourceType === '0' &&
-              item.options && item.options.length > 0
-            ) {
-              optionLibs.set(editAction.uuid + item.uuid, {
-                uuid: editAction.uuid + item.uuid,
-                label: item.label,
-                parname: editAction.label,
-                type: 'Modal',
-                options: item.options
-              })
-            }
-          })
-        })
-      } else {
-        _config.fields.forEach(item => {
-          if (
-            (item.type === 'select' || item.type === 'multiselect' || item.type === 'link') &&
-            item.resourceType === '0' &&
-            item.options && item.options.length > 0
-          ) {
-            optionLibs.set(editAction.uuid + item.uuid, {
-              uuid: editAction.uuid + item.uuid,
-              label: item.label,
-              parname: editAction.label,
-              type: 'Modal',
-              options: item.options
-            })
-          }
-        })
-      }
     } else {
       _config = JSON.parse(JSON.stringify(BaseConfig))
     }
@@ -156,7 +118,6 @@
       openEdition: editAction.open_edition || '',
       menu: _menu,
       source: _source,
-      optionLibs: optionLibs,
       config: _config,
       selectedTables: _config.tables || [],
       originConfig: JSON.parse(JSON.stringify(_config)),
@@ -290,7 +251,6 @@
     
     let param = {
       editMenu: menu,
-      optionLibs: this.state.optionLibs,
       editTab: editTab,
       tabConfig: tabConfig,
       editSubTab: editSubTab,
@@ -525,25 +485,10 @@
    * 3銆侀�氳繃loading鍒锋柊
    */
   handleSubmit = () => {
-    const {editAction, optionLibs} = this.props
     const { card, modalType } = this.state
 
     this.formRef.handleConfirm().then(res => {
       let _config = JSON.parse(JSON.stringify(this.state.config))
-      if ( // 鏇存柊涓嬫媺瀛楀吀
-        (res.type === 'select' || res.type === 'multiselect' || res.type === 'link') &&
-        res.resourceType === '0' &&
-        res.options && res.options.length > 0
-      ) {
-        optionLibs.set(editAction.uuid + res.uuid, {
-          uuid: editAction.uuid + res.uuid,
-          label: res.label,
-          parname: editAction.label,
-          type: 'Modal',
-          options: res.options
-        })
-      }
-
       let fieldrepet = false // 瀛楁閲嶅
       let labelrepet = false // 鎻愮ず鏂囧瓧閲嶅
 
@@ -664,7 +609,6 @@
               config: _config,
               modalType: null,
               card: null,
-              optionLibs: optionLibs,
               visible: false
             })
           } else {
@@ -680,7 +624,6 @@
           config: _config,
           modalType: null,
           card: null,
-          optionLibs: optionLibs,
           visible: false
         })
       }
@@ -1358,7 +1301,7 @@
         <Modal
           title={this.state.modalType !== 'copy' ? this.state.dict['model.edit'] : this.state.dict['header.modal.form.copy']}
           visible={this.state.visible}
-          width={700}
+          width={800}
           onCancel={this.editModalCancel}
           onOk={this.handleSubmit}
           confirmLoading={this.state.sqlVerifing}
@@ -1369,7 +1312,6 @@
             card={this.state.card}
             formlist={this.state.formlist}
             inputSubmit={this.handleSubmit}
-            optionLibs={this.state.optionLibs}
             wrappedComponentRef={(inst) => this.formRef = inst}
           />}
         </Modal>
diff --git a/src/templates/modalconfig/index.scss b/src/templates/modalconfig/index.scss
index 1576160..f09e697 100644
--- a/src/templates/modalconfig/index.scss
+++ b/src/templates/modalconfig/index.scss
@@ -219,6 +219,7 @@
                 right: 0;
                 bottom: 0;
                 opacity: 0;
+                z-index: 1;
               }
             }
             .ant-col-cuslabel {
diff --git a/src/templates/modalconfig/source.jsx b/src/templates/modalconfig/source.jsx
index 7cf801f..d3ec36b 100644
--- a/src/templates/modalconfig/source.jsx
+++ b/src/templates/modalconfig/source.jsx
@@ -104,6 +104,30 @@
   },
   {
     type: 'form',
+    label: '寮�鍏�',
+    subType: 'switch',
+    url: ''
+  },
+  {
+    type: 'form',
+    label: '澶氶�夋',
+    subType: 'checkbox',
+    url: ''
+  },
+  {
+    type: 'form',
+    label: '鍗曢�夋',
+    subType: 'radio',
+    url: ''
+  },
+  {
+    type: 'form',
+    label: '閫夐」鍗�',
+    subType: 'checkcard',
+    url: ''
+  },
+  {
+    type: 'form',
     label: CommonDict['header.form.fileupload'],
     subType: 'fileupload',
     url: ''
diff --git a/src/templates/sharecomponent/searchcomponent/index.jsx b/src/templates/sharecomponent/searchcomponent/index.jsx
index aeb9569..6c70ffb 100644
--- a/src/templates/sharecomponent/searchcomponent/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/index.jsx
@@ -21,7 +21,6 @@
     menu: PropTypes.object,          // 褰撳墠鑿滃崟淇℃伅
     config: PropTypes.object,        // 閰嶇疆淇℃伅
     pasteContent: PropTypes.object,  // 绮樿创閰嶇疆淇℃伅
-    optionLibs: PropTypes.any,       // 涓嬫媺瀛楀吀
     sysRoles: PropTypes.array,       // 瑙掕壊鍒楄〃锛岄粦鍚嶅崟
     updatesearch: PropTypes.func     // 鏇存柊
   }
@@ -128,7 +127,7 @@
    * 4銆佷笅鎷夎彍鍗曟暟鎹簮璇硶楠岃瘉
    */
   handleSubmit = () => {
-    const { optionLibs, menu, config } = this.props
+    const { config } = this.props
     let _searchlist = fromJS(this.state.searchlist).toJS()
 
     this.searchFormRef.handleConfirm().then(res => {
@@ -189,16 +188,6 @@
         return
       }
 
-      if ( res.options && res.options.length > 0 ) { // 涓嬫媺鑿滃崟鍙�夐泦鍚�
-        optionLibs.set(menu.MenuID + res.uuid, {
-          uuid: menu.MenuID + res.uuid,
-          label: res.label,
-          parname: menu.MenuName,
-          type: 'search',
-          options: res.options
-        })
-      }
-
       if ((res.type === 'select' || res.type === 'multiselect' || res.type === 'link') && res.resourceType === '1' && /\s/.test(res.dataSource)) {
         this.setState({
           sqlVerifing: true
@@ -226,7 +215,7 @@
               searchlist: _searchlist,
               visible: false
             }, ()=> {
-              this.props.updatesearch({...config, search: _searchlist}, optionLibs)
+              this.props.updatesearch({...config, search: _searchlist})
             })
           } else {
             this.setState({sqlVerifing: false})
@@ -241,7 +230,7 @@
           searchlist: _searchlist,
           visible: false
         }, ()=> { 
-          this.props.updatesearch({...config, search: _searchlist}, optionLibs)
+          this.props.updatesearch({...config, search: _searchlist})
         })
       }
     })
@@ -316,7 +305,6 @@
             card={this.state.card}
             formlist={this.state.formlist}
             inputSubmit={this.handleSubmit}
-            optionLibs={this.props.optionLibs}
             wrappedComponentRef={(inst) => this.searchFormRef = inst}
           />
         </Modal>
diff --git a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
index 1fea449..708b052 100644
--- a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
@@ -84,7 +84,6 @@
   static propTpyes = {
     dict: PropTypes.object,     // 瀛楀吀椤�
     formlist: PropTypes.any,    // 琛ㄥ崟
-    optionLibs: PropTypes.any,  // 鑷畾涔変笅鎷夐泦
     card: PropTypes.object,     // 鎼滅储鏉′欢淇℃伅
     inputSubmit: PropTypes.any  // 鍥炶溅鎻愪氦浜嬩欢
   }
@@ -102,7 +101,7 @@
    * 2銆佷笅鎷夐�夋嫨锛屾牴鎹暟鎹簮绫诲瀷鏄剧ず鐩稿叧閰嶇疆
    */
   UNSAFE_componentWillMount () {
-    const { formlist, optionLibs, dict } = this.props
+    const { formlist, dict } = this.props
 
     let type = formlist.filter(cell => cell.key === 'type')[0].initVal
     let _items = formlist.filter(cell => cell.key === 'items')[0].initVal
@@ -110,7 +109,7 @@
     let _options = ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide']                // 榛樿鏄剧ず椤�
 
     if ((type === 'multiselect' || type === 'select' || type === 'link') && resourceType === '0') {        // 涓嬫媺閫夋嫨绫诲瀷銆侀�夐」涓鸿嚜瀹氫箟璧勬簮
-      _options = [..._options, 'resourceType', 'options', 'display', 'quick']
+      _options = [..._options, 'resourceType', 'options', 'display']
     } else if ((type === 'multiselect' || type === 'select' || type === 'link') && resourceType === '1') { // 涓嬫媺閫夋嫨绫诲瀷銆侀�夐」涓哄悗鍙版暟鎹簮涓幏鍙�
       _options = [..._options, 'resourceType', 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'display', 'database']
     } else if (type === 'group') {
@@ -151,13 +150,6 @@
           } else if (type === 'dateweek' || type === 'daterange') {
             form.options = matchReg.daterange
           }
-        } else if (form.key === 'quick') {
-          form.options = [...optionLibs.values()].map(cell => {
-            return {
-              value: cell.uuid,
-              text: cell.label + '(' + cell.parname + ')'
-            }
-          })
         } else if (form.key === 'field' && type === 'text') {
           form.tooltip = this.state.textTooltip
         } else if (form.key === 'field' && type === 'group') {
@@ -193,7 +185,7 @@
       let _options = ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide']
 
       if ((value === 'multiselect' || value === 'select' || value === 'link') && resourceType === '0') {        // 涓嬫媺閫夋嫨绫诲瀷銆侀�夐」涓鸿嚜瀹氫箟璧勬簮
-        _options = [..._options, 'resourceType', 'options', 'display', 'quick']
+        _options = [..._options, 'resourceType', 'options', 'display']
       } else if ((value === 'multiselect' || value === 'select' || value === 'link') && resourceType === '1') { // 涓嬫媺閫夋嫨绫诲瀷銆侀�夐」涓哄悗鍙版暟鎹簮涓幏鍙�
         _options = [..._options, 'resourceType', 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'display', 'database']
       } else if (value === 'group') {
@@ -260,18 +252,6 @@
           this.props.form.setFieldsValue({match: matchs[0].value})
         }
       })
-    } else if (key === 'quick') {
-      let _option = this.props.optionLibs.get(value)
-
-      this.setState({
-        formlist: this.state.formlist.map(form => {
-          if (form.key === 'options') {
-            form.initVal = _option.options
-          }
-
-          return form
-        })
-      })
     }
   }
 
@@ -286,7 +266,7 @@
       let _options = ['label', 'field', 'initval', 'type', 'match', 'resourceType', 'display', 'ratio', 'blacklist', 'required', 'Hide']
 
       if (value === '0') {
-        _options = [..._options, 'options', 'quick']
+        _options = [..._options, 'options']
       } else if (value === '1') {
         _options = [..._options, 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'database']
       }
diff --git a/src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx b/src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx
index 4c86036..93db0bd 100644
--- a/src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx
+++ b/src/templates/sharecomponent/settingcomponent/settingform/datasource/index.jsx
@@ -412,6 +412,17 @@
                 </Radio.Group>)}
               </Form.Item>
             </Col> : null}
+            <Col span={12}>
+              <Form.Item label="杈规">
+                {getFieldDecorator('bordered', {
+                  initialValue: setting.bordered || 'true'
+                })(
+                <Radio.Group>
+                  <Radio value="true">鏈�</Radio>
+                  <Radio value="false">鏃�</Radio>
+                </Radio.Group>)}
+              </Form.Item>
+            </Col>
           </Row>
         </Form>
       </div>
diff --git a/src/templates/subtableconfig/index.jsx b/src/templates/subtableconfig/index.jsx
index a3da1e4..6cdd3a1 100644
--- a/src/templates/subtableconfig/index.jsx
+++ b/src/templates/subtableconfig/index.jsx
@@ -37,7 +37,6 @@
 class SubTableConfig extends Component {
   static propTpyes = {
     menu: PropTypes.any,
-    optionLibs: PropTypes.any,
     editTab: PropTypes.any,
     tabConfig: PropTypes.any,
     editSubTab: PropTypes.any,
@@ -61,7 +60,6 @@
     delActions: [],          // 鍒犻櫎鎸夐挳鍒楄〃
     copyActions: [],         // 澶嶅埗鎸夐挳缁�
     tabviews: [],            // 鎵�鏈夋爣绛鹃〉
-    optionLibs: null,        // 鑷畾涔変笅鎷夐�夐」搴�
     thawButtons: [],         // 宸查�夋嫨瑕佽В鍐荤殑鎸夐挳
     activeKey: '0',          // 榛樿灞曞紑鍩烘湰淇℃伅
     chartview: null,         // 褰撳墠瑙嗗浘
@@ -75,7 +73,7 @@
    * 2銆佽缃搷浣滅被鍨嬨�佸師濮嬭彍鍗曚俊鎭紙姣忔淇濆瓨鍚庨噸缃級銆佸凡浣跨敤琛ㄥ強鍩烘湰淇℃伅琛ㄥ崟
    */
   UNSAFE_componentWillMount () {
-    const { config, editTab, editSubTab, optionLibs } = this.props
+    const { config, editTab, editSubTab } = this.props
 
     let _config = null
 
@@ -86,22 +84,6 @@
       _config.isAdd = true
     } else {
       _config = fromJS(config).toJS()
-
-      _config.search.forEach(item => {
-        if (
-          (item.type === 'select' || item.type === 'multiselect' || item.type === 'link') &&
-          item.resourceType === '0' &&
-          item.options && item.options.length > 0
-        ) {
-          optionLibs.set(_config.uuid + item.uuid, {
-            uuid: _config.uuid + item.uuid,
-            label: item.label,
-            parname: _config.tabName,
-            type: 'search',
-            options: item.options
-          })
-        }
-      })
     }
     
     let _oriActions = []
@@ -131,7 +113,6 @@
       openEdition: editSubTab ? (editSubTab.open_edition || '') : (editTab.open_edition || ''),
       chartview: _config.charts[0].uuid,
       originActions: _oriActions,
-      optionLibs: optionLibs,
       config: _config,
       activeKey: _activeKey || '0',
       originConfig: fromJS(_config).toJS(),
@@ -226,7 +207,6 @@
 
     let param = {
       editMenu: menu,
-      optionLibs: this.state.optionLibs,
       editTab: editSubTab ? editTab : null,
       tabConfig: null,
       editSubTab: null,
@@ -797,7 +777,6 @@
 
         let param = {
           editMenu: menu,
-          optionLibs: this.state.optionLibs,
           editTab: editTab,
           tabConfig: editSubTab ? tabConfig : originConfig,
           editSubTab: _subtab,
@@ -956,12 +935,10 @@
   /**
    * @description 鏇存柊鎼滅储鏉′欢閰嶇疆淇℃伅
    */
-  updatesearch = (config, options) => {
-    const { optionLibs } = this.state
+  updatesearch = (config) => {
 
     this.setState({
-      config: config,
-      optionLibs: options || optionLibs
+      config: config
     })
   }
 
@@ -1130,7 +1107,6 @@
                 config={config}
                 pasteContent={this.state.pasteContent}
                 sysRoles={this.props.sysRoles}
-                optionLibs={this.state.optionLibs}
                 updatesearch={this.updatesearch}
               />
               <div className="chart-view" style={{position: 'relative'}}>
diff --git a/src/templates/treepageconfig/index.jsx b/src/templates/treepageconfig/index.jsx
index 35f1c09..1fd9e94 100644
--- a/src/templates/treepageconfig/index.jsx
+++ b/src/templates/treepageconfig/index.jsx
@@ -29,7 +29,6 @@
 class ComTableConfig extends Component {
   static propTpyes = {
     menu: PropTypes.any,
-    optionLibs: PropTypes.any,
     reloadmenu: PropTypes.func,
     handleView: PropTypes.func
   }
@@ -46,7 +45,6 @@
     originMenu: null,        // 鍘熷鑿滃崟
     delTabs: [],             // 鍒犻櫎鏍囩鍒楄〃
     tabviews: [],            // 鎵�鏈夋爣绛鹃〉
-    optionLibs: null,        // 鑷畾涔変笅鎷夐�夐」搴�
     activeKey: '0',          // 榛樿灞曞紑鍩烘湰淇℃伅
     pasteContent: null,      // 绮樿创閰嶇疆淇℃伅
     openEdition: ''          // 缂栬緫鐗堟湰鏍囪锛岄槻姝㈠浜烘搷浣�
@@ -58,7 +56,7 @@
    * 2銆佽缃搷浣滅被鍨嬨�佸師濮嬭彍鍗曚俊鎭紙姣忔淇濆瓨鍚庨噸缃級銆佸凡浣跨敤琛ㄥ強鍩烘湰淇℃伅琛ㄥ崟
    */
   UNSAFE_componentWillMount () {
-    const { menu, optionLibs } = this.props
+    const { menu } = this.props
 
     let _LongParam = menu.LongParam
     let _config = ''
@@ -105,7 +103,6 @@
       config: _config,
       openEdition: menu.open_edition || '',
       activeKey: menu.activeKey || '0',
-      optionLibs: optionLibs,
       originMenu: fromJS(_config).toJS()
     })
   }
@@ -554,7 +551,7 @@
    */
   setSubConfig = (item) => {
     const { menu } = this.props
-    const { config, originMenu, optionLibs, activeKey, openEdition } = this.state
+    const { config, originMenu, activeKey, openEdition } = this.state
 
     if (config.isAdd) { // menuID涓嶅瓨鍦ㄦ椂锛屼负鏂板缓鑿滃崟锛屾彁绀鸿彍鍗曞皻鏈繚瀛�
       notification.warning({
@@ -600,7 +597,6 @@
       _Menu.open_edition = openEdition  // 鏇存柊鐗堟湰鍙�
 
       let param = {
-        optionLibs: optionLibs,
         editMenu: _Menu,
         editTab: item,
         tabConfig: null,
diff --git a/src/templates/zshare/formconfig.jsx b/src/templates/zshare/formconfig.jsx
index 5dc3afa..2632de6 100644
--- a/src/templates/zshare/formconfig.jsx
+++ b/src/templates/zshare/formconfig.jsx
@@ -534,14 +534,6 @@
       required: false
     },
     {
-      type: 'select',
-      key: 'quick',
-      label: Formdict['header.form.quickadd'],
-      initVal: '',
-      required: false,
-      options: []
-    },
-    {
       type: 'radio',
       key: 'required',
       label: Formdict['model.required'],
@@ -1822,6 +1814,18 @@
         value: 'link',
         text: Formdict['model.form.link']
       }, {
+        value: 'switch',
+        text: '寮�鍏�'
+      }, {
+        value: 'checkbox',
+        text: '澶氶�夋'
+      }, {
+        value: 'radio',
+        text: '鍗曢�夋'
+      }, {
+        value: 'checkcard',
+        text: '閫夐」鍗�'
+      }, {
         value: 'fileupload',
         text: Formdict['header.form.fileupload']
       }, {
@@ -1849,8 +1853,23 @@
       type: 'text',
       key: 'initval',
       label: Formdict['header.form.initval'],
+      tooltip: '涓嬫媺澶氶�変笌澶氶�夋锛屾坊鍔犲涓垵濮嬪�艰浣跨敤鈥�,鈥濆彿鍒嗛殧銆�',
       initVal: card.initval || '',
       required: false
+    },
+    {
+      type: 'text',
+      key: 'openVal',
+      label: '寮�鍚��',
+      initVal: card.openVal || '',
+      required: true
+    },
+    {
+      type: 'text',
+      key: 'closeVal',
+      label: '鍏抽棴鍊�',
+      initVal: card.closeVal || '',
+      required: true
     },
     {
       type: 'radio',
@@ -1864,6 +1883,20 @@
       }, {
         value: '1',
         text: Formdict['header.form.datasource']
+      }]
+    },
+    {
+      type: 'radio',
+      key: 'display',
+      label: '鏄剧ず',
+      initVal: card.display || 'text',
+      required: true,
+      options: [{
+        value: 'text',
+        text: '鏂囨湰'
+      }, {
+        value: 'picture',
+        text: '鍥剧墖'
       }]
     },
     {
@@ -2017,14 +2050,6 @@
     },
     {
       type: 'select',
-      key: 'quick',
-      label: Formdict['header.form.quickadd'],
-      initVal: '',
-      required: false,
-      options: []
-    },
-    {
-      type: 'select',
       key: 'fileType',
       label: '鏄剧ず鏂瑰紡',
       initVal: card.fileType || 'text',
@@ -2128,6 +2153,20 @@
     },
     {
       type: 'radio',
+      key: 'entireLine',
+      label: '鍗犳嵁鏁磋',
+      initVal: card.entireLine || 'false',
+      required: false,
+      options: [{
+        value: 'true',
+        text: '鏄�'
+      }, {
+        value: 'false',
+        text: '鍚�'
+      }]
+    },
+    {
+      type: 'radio',
       key: 'encryption',
       label: '鍔犲瘑浼犺緭',
       initVal: card.encryption || 'false',
diff --git a/src/templates/zshare/modalform/index.jsx b/src/templates/zshare/modalform/index.jsx
index bcc8328..689c1f2 100644
--- a/src/templates/zshare/modalform/index.jsx
+++ b/src/templates/zshare/modalform/index.jsx
@@ -1,5 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
+import { fromJS } from 'immutable'
 import { Form, Row, Col, Input, Select, Icon, Radio, notification, InputNumber, Tooltip } from 'antd'
 import { formRule } from '@/utils/option.js'
 import { dateOptions } from '@/utils/option.js'
@@ -9,25 +10,28 @@
 import './index.scss'
 
 const modalTypeOptions = {
-  text: ['label', 'field', 'initval', 'type', 'readonly', 'required', 'hidden', 'readin', 'blacklist', 'fieldlength', 'regular', 'interception', 'writein'],
-  number: ['label', 'field', 'initval', 'type', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'blacklist', 'writein'],
-  select: ['label', 'field', 'initval', 'type', 'readonly', 'required', 'hidden', 'readin', 'blacklist', 'resourceType', 'setAll', 'linkSubField', 'writein'],
-  multiselect: ['label', 'field', 'initval', 'type', 'readonly', 'required', 'hidden', 'readin', 'blacklist', 'resourceType', 'fieldlength', 'writein'],
-  link: ['label', 'field', 'initval', 'type', 'readonly', 'required', 'hidden', 'readin', 'blacklist', 'resourceType', 'setAll', 'linkField', 'writein'],
-  fileupload: ['label', 'field', 'type', 'readonly', 'required', 'readin', 'fieldlength', 'blacklist', 'maxfile', 'fileType', 'writein'],
-  date: ['label', 'field', 'initval', 'type', 'readonly', 'required', 'hidden', 'readin', 'blacklist', 'writein'],
-  datemonth: ['label', 'field', 'initval', 'type', 'readonly', 'required', 'hidden', 'readin', 'blacklist', 'writein'],
-  datetime: ['label', 'field', 'initval', 'type', 'readonly', 'required', 'hidden', 'readin', 'blacklist', 'writein'],
-  textarea: ['label', 'field', 'initval', 'type', 'readonly', 'required', 'hidden', 'readin', 'blacklist', 'fieldlength', 'maxRows', 'encryption', 'interception', 'writein'],
-  color: ['label', 'field', 'type', 'blacklist', 'readonly', 'required', 'hidden', 'readin', 'writein'],
-  funcvar: ['label', 'field', 'type', 'blacklist', 'hidden', 'writein'],
-  linkMain: ['label', 'field', 'type', 'readonly', 'required', 'hidden', 'fieldlength', 'blacklist', 'writein']
+  text: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'regular', 'interception', 'entireLine'],
+  number: ['initval', 'readonly', 'hidden', 'decimal', 'min', 'max', 'readin', 'entireLine'],
+  select: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkSubField', 'entireLine'],
+  checkbox: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'entireLine'],
+  radio: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'entireLine'],
+  checkcard: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'linkSubField', 'display'],
+  multiselect: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'fieldlength', 'entireLine'],
+  link: ['initval', 'readonly', 'required', 'hidden', 'readin', 'resourceType', 'setAll', 'linkField', 'entireLine'],
+  fileupload: ['readonly', 'required', 'readin', 'fieldlength', 'maxfile', 'fileType', 'entireLine'],
+  switch: ['initval', 'openVal', 'closeVal', 'readonly', 'required', 'hidden', 'readin', 'entireLine'],
+  date: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine'],
+  datemonth: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine'],
+  datetime: ['initval', 'readonly', 'required', 'hidden', 'readin', 'entireLine'],
+  textarea: ['initval', 'readonly', 'required', 'hidden', 'readin', 'fieldlength', 'maxRows', 'encryption', 'interception'],
+  color: ['readonly', 'required', 'hidden', 'readin', 'entireLine'],
+  funcvar: ['hidden'],
+  linkMain: ['readonly', 'required', 'hidden', 'fieldlength', 'entireLine']
 }
 
 class MainSearch extends Component {
   static propTpyes = {
     dict: PropTypes.object,    // 瀛楀吀椤�
-    optionLibs: PropTypes.any, // 鑷畾涔変笅鎷夐泦
     formlist: PropTypes.any,
     card: PropTypes.object,
     inputSubmit: PropTypes.any
@@ -42,8 +46,7 @@
   }
 
   UNSAFE_componentWillMount () {
-    const { optionLibs } = this.props
-    let formlist = JSON.parse(JSON.stringify(this.props.formlist))
+    let formlist = fromJS(this.props.formlist).toJS()
 
     let type = ''
     let resourceType = ''
@@ -70,21 +73,7 @@
       }
     })
     
-    let _options = JSON.parse(JSON.stringify(modalTypeOptions[type]))
-
-    if ((type === 'multiselect' || type === 'select' || type === 'link') && resourceType === '0') { // 閫夋嫨绫诲瀷銆佽嚜瀹氫箟璧勬簮
-      _options = [..._options, 'options', 'quick']
-    } else if ((type === 'multiselect' || type === 'select' || type === 'link') && resourceType === '1') { // 閫夋嫨绫诲瀷銆佹暟鎹簮
-      _options = [..._options, 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'database']
-    }
-
-    if (type !== 'funcvar' && type !== 'linkMain') {
-      if (supField) {
-        _options.push('supField', 'supvalue')
-      } else {
-        _options.push('supField')
-      }
-    }
+    let _options = this.getOptions(type, resourceType, supField)
 
     this.setState({
       openType: type,
@@ -95,17 +84,17 @@
         if (dateOptions.hasOwnProperty(type) && form.key === 'initval') {
           form.options = dateOptions[type]
           form.type = 'select'
+        } else if (type === 'switch' && form.key === 'initval') {
+          form.initVal = !!form.initVal
+          form.options = [
+            {value: true, text: '寮�'},
+            {value: false, text: '鍏�'}
+          ]
+          form.type = 'radio'
         } else if (type === 'number' && form.key === 'initval') {
           form.type = 'number'
           form.initVal = form.initVal || 0
           form.required = true
-        } else if (form.key === 'quick') {
-          form.options = [...optionLibs.values()].map(cell => {
-            return {
-              value: cell.uuid,
-              text: cell.label + '(' + cell.parname + ')'
-            }
-          })
         }
 
         form.show = _options.includes(form.key)
@@ -127,24 +116,31 @@
     }
   }
 
-  openTypeChange = (key, value) => {
-    if (key === 'type') {
-      let _options = JSON.parse(JSON.stringify(modalTypeOptions[value]))
+  getOptions = (type, resourceType, supField) => {
+    let _options = ['label', 'field', 'type', 'blacklist', 'writein', ...fromJS(modalTypeOptions[type]).toJS()]
 
-      if ((value === 'multiselect' || value === 'select' || value === 'link') && this.state.resourceType === '0') { // 閫夋嫨绫诲瀷銆佽嚜瀹氫箟璧勬簮
-        _options = [..._options, 'options', 'quick']
-      } else if ((value === 'multiselect' || value === 'select' || value === 'link') && this.state.resourceType === '1') { // 閫夋嫨绫诲瀷銆佹暟鎹簮
+    if (['multiselect', 'select', 'link', 'radio', 'checkbox', 'checkcard'].includes(type)) {
+      if (resourceType === '0') {        // 鑷畾涔夎祫婧�
+        _options = [..._options, 'options']
+      } else if (resourceType === '1') { // 鏁版嵁婧�
         _options = [..._options, 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'database']
       }
+    }
 
-      if (value !== 'funcvar' && value !== 'linkMain') {
-        if (this.state.supField) {
-          _options.push('supField', 'supvalue')
-        } else {
-          _options.push('supField')
-        }
+    if (type !== 'funcvar' && type !== 'linkMain') {
+      if (supField) {
+        _options.push('supField', 'supvalue')
+      } else {
+        _options.push('supField')
       }
+    }
 
+    return _options
+  }
+
+  openTypeChange = (key, value) => {
+    if (key === 'type') {
+      let _options = this.getOptions(value, this.state.resourceType, this.state.supField)
       let fieldValue = {}
       
       this.setState({
@@ -157,6 +153,13 @@
             if (dateOptions.hasOwnProperty(value)) {
               form.options = dateOptions[value]
               form.type = 'select'
+            } else if (value === 'switch') {
+              form.initVal = false
+              form.options = [
+                {value: true, text: '寮�'},
+                {value: false, text: '鍏�'}
+              ]
+              form.type = 'radio'
             } else if (value === 'number') {
               form.type = 'number'
               form.required = true
@@ -170,7 +173,7 @@
             }
           } else if (form.key === 'fieldlength') {
             form.initVal = 50
-            if (value === 'textarea' || value === 'fileupload' || value === 'multiselect') {
+            if (value === 'textarea' || value === 'fileupload' || value === 'multiselect' || value === 'checkbox') {
               form.initVal = 512
             }
 
@@ -194,18 +197,6 @@
         })
       }, () => {
         this.props.form.setFieldsValue(fieldValue)
-      })
-    } else if (key === 'quick') {
-      let option = this.props.optionLibs.get(value)
-
-      this.setState({
-        formlist: this.state.formlist.map(form => {
-          if (form.key === 'options') {
-            form.initVal = option.options
-          }
-
-          return form
-        })
       })
     } else if (key === 'supField') {
       this.setState({
@@ -249,22 +240,8 @@
     const { openType } = this.state
     let value = e.target.value
     if (key === 'resourceType') {
-      let _options = JSON.parse(JSON.stringify(modalTypeOptions[openType]))
-
-      if (value === '0') {
-        _options = [..._options, 'options', 'quick']
-      } else if (value === '1') {
-        _options = [..._options, 'dataSource', 'valueField', 'valueText', 'orderBy', 'orderType', 'database']
-      }
-
-      if (openType !== 'funcvar' && openType !== 'linkMain') {
-        if (this.state.supField) {
-          _options.push('supField', 'supvalue')
-        } else {
-          _options.push('supField')
-        }
-      }
-
+      let _options = this.getOptions(openType, value, this.state.supField)
+      
       this.setState({
         resourceType: value,
         formlist: this.state.formlist.map(form => {
@@ -500,7 +477,12 @@
       } else if (item.type === 'options') {
         fields.push(
           <Col span={20} offset={4} key={index}>
-            <EditTable data={item.initVal} dict={this.props.dict} type={this.state.openType} linkSubFields={this.state.linkSubFields} ref="editTable"/>
+            <Form.Item className="text-area">
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal
+              })(<EditTable dict={this.props.dict} type={this.state.openType} linkSubFields={this.state.linkSubFields}/>)}
+            </Form.Item>
+            {/* <EditTable data={item.initVal} dict={this.props.dict} type={this.state.openType} linkSubFields={this.state.linkSubFields} ref="editTable"/> */}
           </Col>
         )
       }
@@ -514,38 +496,43 @@
     return new Promise((resolve, reject) => {
       this.props.form.validateFieldsAndScroll((err, values) => {
         if (!err) {
-          let isvalid = true
           values.uuid = this.props.card.uuid
           // 涓嬫媺鑿滃崟鎴栬仈鍔ㄨ彍鍗�
-          if ((values.type === 'multiselect' || values.type === 'select' || values.type === 'link') && values.resourceType === '0') {
-            values.options = this.refs.editTable.state.dataSource
-            values.dataSource = ''
-            let emptys = []
-            if (values.type === 'multiselect' || values.type === 'select') {
-              emptys = values.options.filter(op => !((op.Value || op.Value === 0) && (op.Text || op.Text === 0)))
-            } else {
-              emptys = values.options.filter(op => !((op.Value || op.Value === 0) && (op.Text || op.Text === 0) && (op.ParentID || op.ParentID === 0)))
-            }
-            if (emptys.length > 0) {
-              isvalid = false
-              notification.warning({
-                top: 92,
-                message: this.props.dict['model.form.selectItem.error'],
-                duration: 5
+          if (['multiselect', 'select', 'link', 'radio', 'checkbox'].includes(values.type)) {
+            if (values.resourceType === '0') {
+              values.options = values.options || []
+              values.dataSource = ''
+              let empty = false
+
+              values.options.forEach(op => {
+                if (!((op.Value || op.Value === 0) && (op.Text || op.Text === 0))) {
+                  empty = true
+                } else if (values.type === 'link' && !(op.ParentID || op.ParentID === 0)) {
+                  empty = true
+                }
               })
+
+              if (empty) {
+                notification.warning({
+                  top: 92,
+                  message: this.props.dict['model.form.selectItem.error'],
+                  duration: 5
+                })
+                return
+              }
+            } else {
+              values.options = []
             }
-          } else if ((values.type === 'multiselect' || values.type === 'select' || values.type === 'link') && values.resourceType === '1') {
-            values.options = []
           } else if (values.type === 'funcvar') { // 鍑芥暟鍙橀噺涓哄彧璇诲厓绱�
             values.readonly = 'true'
           } else if (values.type === 'number' && (values.min || values.min === 0) && (values.max || values.max === 0)) { // 鏁板�煎瀷楠岃瘉鏈�灏忔渶澶у��
             if (values.min > values.max) {
-              isvalid = false
               notification.warning({
                 top: 92,
                 message: '鏈�灏忓�间笉鍙ぇ浜庢渶澶у�硷紒',
                 duration: 5
               })
+              return
             }
           } else if (values.type === 'linkMain') {
             values.initval = ''
@@ -553,7 +540,7 @@
 
           ['linkField', 'valueField', 'valueText', 'orderBy'].forEach(item => {
             if (values[item]) {
-              values[item] = values[item].replace(/\s* | \t* | \v* | \r*/ig, '')
+              values[item] = values[item].replace(/\s*|\t*|\v*|\r*/ig, '')
             }
           })
 
@@ -568,9 +555,7 @@
             return
           }
 
-          if (isvalid) {
-            resolve(values)
-          }
+          resolve(values)
         } else {
           reject(err)
         }
diff --git a/src/templates/zshare/modalform/modaleditable/index.jsx b/src/templates/zshare/modalform/modaleditable/index.jsx
index 8a790c6..f24e275 100644
--- a/src/templates/zshare/modalform/modaleditable/index.jsx
+++ b/src/templates/zshare/modalform/modaleditable/index.jsx
@@ -1,4 +1,5 @@
 import React, {Component} from 'react'
+import PropTypes from 'prop-types'
 import { is, fromJS } from 'immutable'
 import { Table, Input, Popconfirm, Form, Icon, Radio } from 'antd'
 import { formRule } from '@/utils/option.js'
@@ -107,24 +108,44 @@
 }
 
 class EditTable extends Component {
-  constructor(props) {
-    super(props)
+  static propTpyes = {
+    dict: PropTypes.object,         // 瀛楀吀椤�
+    type: PropTypes.string,         // 琛ㄥ崟绫诲瀷
+    linkSubFields: PropTypes.array, // 鍏宠仈瀛楁
+    onChange: PropTypes.func        // 鏁版嵁鍙樺寲
+  }
+
+  state = {
+    columns: [],
+    dataSource: [],
+    count: 0,
+    type: null,
+    linkSubFields: []
+  }
+
+  UNSAFE_componentWillMount () {
+    const { linkSubFields, type, dict } = this.props
+    let data = this.props['data-__meta'].initialValue
+
+    if (!data) {
+      data = []
+    }
 
     let _width = '40%'
     let fields = []
-    let dataItem = props.data ? props.data[0] : ''
+    let dataItem = data[0] || ''
 
-    if (props.type === 'link') {
+    if (type === 'link') {
       _width = '27%'
-    } else if (props.type === 'select') {
-      _width = Math.floor(80 / (props.linkSubFields.length + 2)) + '%'
-      fields = props.linkSubFields.map(field => {
+    } else if (type === 'select') {
+      _width = Math.floor(80 / (linkSubFields.length + 2)) + '%'
+      fields = linkSubFields.map(cell => {
         return {
-          title: field.label,
-          dataIndex: field.field,
+          title: cell.label,
+          dataIndex: cell.field,
           width: _width,
           editable: true,
-          datatype: dataItem && typeof(dataItem[field.field]) === 'number' ? 'number' : 'string'
+          datatype: dataItem && typeof(dataItem[cell.field]) === 'number' ? 'number' : 'string'
         }
       })
     }
@@ -154,21 +175,21 @@
         render: (text, record) =>
           this.state.dataSource.length >= 1 ? (
             <div>
-              <span className="operation-btn" title={props.dict['header.form.up']} onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span>
-              <span className="operation-btn" title={props.dict['header.form.down']} onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span>
+              <span className="operation-btn" title={dict['header.form.up']} onClick={() => this.handleUpDown(record, 'up')} style={{color: '#1890ff'}}><Icon type="arrow-up" /></span>
+              <span className="operation-btn" title={dict['header.form.down']} onClick={() => this.handleUpDown(record, 'down')} style={{color: '#ff4d4f'}}><Icon type="arrow-down" /></span>
               <Popconfirm
                 overlayClassName="popover-confirm"
-                title={props.dict['model.query.delete']}
+                title={dict['model.query.delete']}
                 onConfirm={() => this.handleDelete(record.key)
               }>
-                <span style={{color: '#1890ff', cursor: 'pointer'}}><Icon type="delete" /></span>
+                <span style={{color: '#ff4d4f', cursor: 'pointer'}}><Icon type="delete" /></span>
               </Popconfirm>
             </div>
           ) : null,
       }
     ]
 
-    if (props.type === 'link') {
+    if (type === 'link') {
       columns.unshift({
         title: 'ParentID',
         dataIndex: 'ParentID',
@@ -178,18 +199,18 @@
       })
     }
 
-    this.state = {
+    this.setState({
       columns: columns.map(col => {
         if (col.dataIndex !== 'operation') {
           col = {...col, ...this.getColumnSearchProps(col)}
         }
         return col
       }),
-      dataSource: props.data,
-      count: props.data.length,
-      type: props.type,
-      linkSubFields: props.linkSubFields
-    }
+      dataSource: data,
+      count: data.length,
+      type: type,
+      linkSubFields: linkSubFields
+    })
   }
 
   getColumnSearchProps = column => ({
@@ -197,10 +218,10 @@
       <div style={{ padding: 8 }}>
         <Radio.Group onChange={(e) => this.changeDatatype(column, e)} value={column.datatype}>
           <Radio style={{display: 'block', height: '30px', lineHeight: '30px'}} value="string">
-            String
+            瀛楃涓�
           </Radio>
           <Radio style={{display: 'block', height: '30px', lineHeight: '30px'}} value="number">
-            Number
+            鏁板瓧
           </Radio>
         </Radio.Group>
       </div>
@@ -213,27 +234,28 @@
   changeDatatype = (column, e) => {
     const { columns, dataSource } = this.state
     let value = e.target.value
-
-    this.setState({
-      dataSource: dataSource.map(item => {
-        let val = item[column.dataIndex]
-        if (value === 'number') {
-          try {
-            val = parseFloat(val)
-            if (isNaN(val)) {
-              val = ''
-            }
-          } catch {
+    let _data = dataSource.map(item => {
+      let val = item[column.dataIndex]
+      if (value === 'number') {
+        try {
+          val = parseFloat(val)
+          if (isNaN(val)) {
             val = ''
           }
-        } else {
-          val = '' + val
+        } catch {
+          val = ''
         }
+      } else {
+        val = '' + val
+      }
 
-        item[column.dataIndex] = val
+      item[column.dataIndex] = val
 
-        return item
-      }),
+      return item
+    })
+
+    this.setState({
+      dataSource: _data,
       columns: columns.map(col => {
         if (col.dataIndex === column.dataIndex) {
           col.datatype = value
@@ -245,6 +267,8 @@
 
         return col
       })
+    }, () => {
+      this.props.onChange(_data)
     })
   }
 
@@ -271,12 +295,18 @@
 
     this.setState({
       dataSource: _data
+    }, () => {
+      this.props.onChange(_data)
     })
   }
 
   handleDelete = key => {
-    const dataSource = [...this.state.dataSource]
-    this.setState({ dataSource: dataSource.filter(item => item.key !== key) })
+    const { dataSource } = this.state
+    let _data = dataSource.filter(item => item.key !== key)
+
+    this.setState({ dataSource: _data }, () => {
+      this.props.onChange(_data)
+    })
   }
 
   handleAdd = () => {
@@ -289,9 +319,14 @@
     if (type === 'link') {
       newData.ParentID = `${count}`
     }
+
+    let _data = [...dataSource, newData]
+
     this.setState({
-      dataSource: [...dataSource, newData],
+      dataSource: _data,
       count: count + 1
+    }, () => {
+      this.props.onChange(_data)
     })
   }
 
@@ -303,7 +338,9 @@
       ...item,
       ...row
     })
-    this.setState({ dataSource: newData })
+    this.setState({ dataSource: newData }, () => {
+      this.props.onChange(newData)
+    })
   }
 
   resetColumn = (type, linkSubFields) => {
@@ -392,28 +429,14 @@
       }),
       dataSource: dataSource,
       type: type
+    }, () => {
+      this.props.onChange(dataSource)
     })
   }
 
   UNSAFE_componentWillReceiveProps (nextProps) {
     if (!is(fromJS(this.props.linkSubFields), fromJS(nextProps.linkSubFields)) || this.props.type !== nextProps.type) {
       this.resetColumn(nextProps.type, nextProps.linkSubFields)
-    } else if (!is(fromJS(this.props.data), fromJS(nextProps.data))) {
-      let _data = []
-      nextProps.data.forEach(item => {
-        let _item = {key: Utils.getuuid()}
-        this.state.columns.forEach(col => {
-          _item[col.dataIndex] = item[col.dataIndex] || ''
-          if (col.dataIndex !== 'ParentID' && !_item[col.dataIndex]) {
-            _item[col.dataIndex] = item.Text
-          }
-        })
-        _data.push(_item)
-      })
-      this.setState({
-        dataSource: _data,
-        count: nextProps.data.length
-      })
     }
   }
 

--
Gitblit v1.8.0