From 6e106eb13ce404d9955d6c9045d21050d3e08294 Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期五, 20 十一月 2020 11:19:36 +0800
Subject: [PATCH] 2020-11-20

---
 src/menu/components/chart/antv-bar/chartcompile/index.jsx                   |   40 +
 src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx              |   60 -
 src/components/header/index.jsx                                             |   27 
 src/menu/components/search/main-search/wrapsetting/settingform/index.jsx    |   36 +
 src/menu/components/card/prop-card/index.scss                               |    3 
 src/menu/components/table/normal-table/cardcomponent/index.scss             |    0 
 src/tabviews/custom/components/search/main-search/index.scss                |    8 
 src/menu/components/table/normal-table/cardcomponent/settingform/index.jsx  |  131 ++++
 src/menu/components/table/normal-table/index.scss                           |   92 +++
 src/menu/components/card/data-card/index.scss                               |    3 
 src/templates/sharecomponent/settingcomponent/settingform/index.jsx         |    2 
 src/components/barcode/index.scss                                           |    9 
 src/tabviews/custom/components/card/data-card/index.scss                    |    1 
 src/menu/components/search/main-search/index.scss                           |   38 
 src/views/menudesign/index.jsx                                              |    1 
 src/tabviews/custom/components/card/table-card/index.scss                   |    1 
 src/views/sso/index.jsx                                                     |  152 +++++
 src/tabviews/custom/components/card/prop-card/index.scss                    |    1 
 src/components/header/index.scss                                            |    8 
 src/menu/components/search/main-search/dragsearch/index.jsx                 |   14 
 src/views/sso/index.scss                                                    |    7 
 src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx              |  124 ++--
 src/menu/components/share/normalform/index.scss                             |   11 
 src/tabviews/custom/components/search/main-search/index.jsx                 |   46 
 src/menu/components/table/normal-table/cardcomponent/index.jsx              |  208 +++++++
 src/templates/zshare/formconfig.jsx                                         |   41 
 src/menu/components/chart/antv-pie/chartcompile/index.jsx                   |   59 +
 src/menu/components/search/main-search/dragsearch/card.jsx                  |    2 
 src/router/index.js                                                         |   24 
 src/menu/components/search/main-search/index.jsx                            |    2 
 src/menu/components/table/normal-table/cardcomponent/settingform/index.scss |   11 
 src/templates/zshare/customscript/index.jsx                                 |    1 
 src/menu/components/share/normalform/index.jsx                              |  170 ++++++
 src/menu/components/table/normal-table/index.jsx                            |  289 ++++++++++
 src/components/barcode/index.jsx                                            |   32 
 src/menu/components/tabs/tabsetting/settingform/index.jsx                   |    4 
 src/templates/sharecomponent/searchcomponent/searchform/index.jsx           |   10 
 37 files changed, 1,416 insertions(+), 252 deletions(-)

diff --git a/src/components/barcode/index.jsx b/src/components/barcode/index.jsx
index c7dd144..001e63e 100644
--- a/src/components/barcode/index.jsx
+++ b/src/components/barcode/index.jsx
@@ -11,6 +11,10 @@
     value: PropTypes.any,    // 鏉$爜鍊�
   }
 
+  state = {
+    error: false
+  }
+
   componentDidMount () {
     this.resetBarcode()
   }
@@ -28,22 +32,30 @@
 
     let style = card.style || {}
 
-    JsBarcode(this.barcode, value, {
-      displayValue: card.displayValue === 'true',
-      width: card.interval || 1,
-      height: card.barHeight || 25,
-      margin: 0,
-      fontOptions: `${style.fontWeight || ''} ${style.fontStyle || ''}`,
-      textAlign: style.textAlign || 'left',
-      fontSize: (style.fontSize || 14) + 'px',
-      lineColor: style.color || '#000000'
-    })
+    try {
+      JsBarcode(this.barcode, value, {
+        displayValue: card.displayValue === 'true',
+        width: card.interval || 1,
+        height: card.barHeight || 25,
+        margin: 0,
+        fontOptions: `${style.fontWeight || ''} ${style.fontStyle || ''}`,
+        textAlign: style.textAlign || 'left',
+        fontSize: (style.fontSize || 14) + 'px',
+        lineColor: style.color || '#000000'
+      })
+      this.setState({error: false})
+    } catch {
+      this.setState({error: true})
+    }
 
   }
 
   render() {
+    const { error } = this.state
+
     return (
       <div className="barcode-box">
+        {error ? <span className="barcode-error">瀛楃闈炴硶鎴栬繃闀匡紒</span> : null}
         <svg ref={(ref) => { this.barcode = ref }}/>
       </div>
     )
diff --git a/src/components/barcode/index.scss b/src/components/barcode/index.scss
index 98b112a..19eafbc 100644
--- a/src/components/barcode/index.scss
+++ b/src/components/barcode/index.scss
@@ -1,5 +1,14 @@
 .barcode-box {
+  overflow-y: hidden;
+  height: 100%;
   svg {
     vertical-align: top;
   }
+  .barcode-error {
+    font-size: 12px;
+    vertical-align: top;
+  }
+  .barcode-error + svg {
+    display: none;
+  }
 }
diff --git a/src/components/header/index.jsx b/src/components/header/index.jsx
index 8ab7d60..61d8f47 100644
--- a/src/components/header/index.jsx
+++ b/src/components/header/index.jsx
@@ -193,7 +193,7 @@
           }
           return item
         }),
-        systems: result.Systems.filter(sys => sys.LinkUrl1 && sys.AppKey !== window.GLOB.appkey)
+        systems: sessionStorage.getItem('isEditState') === 'true' ? [] : result.Systems.filter(sys => sys.LinkUrl1 && sys.AppName && sys.AppKey !== window.GLOB.appkey)
       })
     } else {
       notification.error({
@@ -275,10 +275,10 @@
           })
         }
 
-        resolve({permAction: _permAction})
+        resolve(_permAction)
       })
     })
-    
+
     // 鑾峰彇涓昏彍鍗曞弬鏁�
     let promiseMenu = new Promise(resolve => {
       let _param = {func: 'sPC_Get_MainMenu', systemType: options.sysType}
@@ -314,7 +314,7 @@
               }
               return item
             }),
-            systems: result.Systems.filter(sys => sys.LinkUrl1 && sys.AppKey !== window.GLOB.appkey)
+            systems: result.Systems.filter(sys => sys.LinkUrl1 && sys.AppName && sys.AppKey !== window.GLOB.appkey)
           })
         } else if (result) {
           notification.error({
@@ -333,9 +333,9 @@
       this.props.modifyMainMenu(_mainMenu)
     }
 
-    let _role = await promiseRole
+    let permAction = await promiseRole
 
-    this.props.initActionPermission(_role.permAction)
+    this.props.initActionPermission(permAction)
   }
 
   reload = () => {
@@ -547,11 +547,18 @@
   }
 
   changeSystem = (system) => {
-    window.location.href = system.LinkUrl1 + '#/ssologin/' + window.btoa(window.encodeURIComponent(JSON.stringify({
+    let href = system.LinkUrl1 + 'index.html#/ssologin/' + window.btoa(window.encodeURIComponent(JSON.stringify({
       UserID: sessionStorage.getItem('UserID'),
       LoginUID: sessionStorage.getItem('LoginUID'),
-      User_Name: sessionStorage.getItem('User_Name')
+      User_Name: sessionStorage.getItem('User_Name'),
+      Full_Name: sessionStorage.getItem('Full_Name'),
+      avatar: sessionStorage.getItem('avatar'),
+      dataM: system.dataM ? 'true' : '',
+      debug: system.debug || '',
+      role_id: system.role_id || ''
     })))
+
+    window.open(href)
   }
 
   dropdownMenuChange = (visible) => {
@@ -677,11 +684,11 @@
           <Switch size="small" className="edit-switch" disabled={!!this.props.editLevel} checked={this.props.editState} onChange={this.changeEditState} />
         </Menu.Item>}
         {!this.props.editState ? <Menu.Item key="password" onClick={this.changePassword}>{this.state.dict['main.password']}</Menu.Item> : null}
-        {/* {this.state.systems.length > 0 ? <Menu.SubMenu title="鍒囨崲绯荤粺">
+        {this.state.systems.length > 0 ? <Menu.SubMenu className="header-subSystem-box" title="鍒囨崲绯荤粺">
           {this.state.systems.map((system, index) => (
             <Menu.Item className="header-subSystem" key={'sub' + index} onClick={() => {this.changeSystem(system)}}> {system.AppName} </Menu.Item>
           ))}
-        </Menu.SubMenu> : null} */}
+        </Menu.SubMenu> : null}
         <Menu.Item key="doc" onClick={this.gotoDoc}>{this.state.dict['main.doc']}</Menu.Item>
         {oriVersion ? <Menu.Item key="verup" onClick={this.verup}>
           <Badge dot={oriVersion !== newVersion}>{this.state.dict['main.verup']}</Badge>
diff --git a/src/components/header/index.scss b/src/components/header/index.scss
index 3ae1951..2f21768 100644
--- a/src/components/header/index.scss
+++ b/src/components/header/index.scss
@@ -194,9 +194,15 @@
   }
 }
 .header-dropdown {
-  li {
+  >li {
     padding: 5px 25px;
   }
+  >li.ant-dropdown-menu-submenu {
+    padding: 0px;
+    .ant-dropdown-menu-submenu-title {
+      padding: 5px 25px;
+    }
+  }
 }
 .header-subSystem {
   min-width: 100px;
diff --git a/src/menu/components/card/data-card/index.scss b/src/menu/components/card/data-card/index.scss
index c7faaf7..8e267dd 100644
--- a/src/menu/components/card/data-card/index.scss
+++ b/src/menu/components/card/data-card/index.scss
@@ -29,8 +29,9 @@
   }
 
   .card-item {
-    overflow-y: hidden;
+    overflow: hidden;
     position: relative;
+    background-color: #ffffff;
     background-position: center center;
     background-repeat: no-repeat;
     background-size: cover;
diff --git a/src/menu/components/card/prop-card/index.scss b/src/menu/components/card/prop-card/index.scss
index 2e1b614..51c310a 100644
--- a/src/menu/components/card/prop-card/index.scss
+++ b/src/menu/components/card/prop-card/index.scss
@@ -29,8 +29,9 @@
   }
 
   .card-item {
-    overflow-y: hidden;
+    overflow: hidden;
     position: relative;
+    background-color: #ffffff;
     background-position: center center;
     background-repeat: no-repeat;
     background-size: cover;
diff --git a/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
index e53c3d6..9b14404 100644
--- a/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-bar/chartcompile/formconfig.jsx
@@ -8,34 +8,8 @@
  * @param {object} card       // 鍥捐〃瀵硅薄
  * @param {Array}  columns    // 鏄剧ず鍒�
  */
-export function getBarOrLineChartOptionForm (card, columns, sysRoles = [], MenuType) {
-  let shapes = []
+export function getBaseForm (card, sysRoles = [], MenuType) {
   let _sysRoles = sysRoles.map(item => ({...item, field: item.value, label: item.text}))
-
-  if (card.chartType === 'line') {
-    shapes = [
-      { field: 'smooth', label: 'smooth' },
-      { field: 'line', label: 'line' },
-      { field: 'dot', label: 'dot' },
-      { field: 'dash', label: 'dash' },
-      { field: 'hv', label: 'hv' },
-      { field: 'vh', label: 'vh' },
-      { field: 'hvh', label: 'hvh' },
-      { field: 'vhv', label: 'vhv' }
-    ]
-  } else if (card.chartType === 'bar') {
-    shapes = [
-      { field: 'rect', label: 'rect' },
-      { field: 'hollow-rect', label: 'hollow-rect' },
-      { field: 'line', label: 'line' },
-      { field: 'tick', label: 'tick' },
-      { field: 'funnel', label: 'funnel' },
-      { field: 'pyramid', label: 'pyramid' }
-    ]
-  }
-
-  let xfields = columns.filter(item => /^Nvarchar/ig.test(item.datatype))
-  let yfields = columns.filter(item => /^(Int|Decimal)/ig.test(item.datatype))
 
   return [
     {
@@ -74,6 +48,53 @@
       decimal: 0,
       required: true
     },
+    {
+      type: 'select',
+      key: 'blacklist',
+      label: '榛戝悕鍗�',
+      initVal: card.blacklist || [],
+      multi: true,
+      required: false,
+      forbid: MenuType === 'billPrint',
+      options: _sysRoles
+    }
+  ]
+}
+
+/**
+ * @description 鑾峰彇鍥捐〃瑙嗗浘閰嶇疆琛ㄥ崟
+ * @param {object} card       // 鍥捐〃瀵硅薄
+ * @param {Array}  columns    // 鏄剧ず鍒�
+ */
+export function getOptionForm (card, columns, MenuType) {
+  let shapes = []
+
+  if (card.chartType === 'line') {
+    shapes = [
+      { field: 'smooth', label: 'smooth' },
+      { field: 'line', label: 'line' },
+      { field: 'dot', label: 'dot' },
+      { field: 'dash', label: 'dash' },
+      { field: 'hv', label: 'hv' },
+      { field: 'vh', label: 'vh' },
+      { field: 'hvh', label: 'hvh' },
+      { field: 'vhv', label: 'vhv' }
+    ]
+  } else if (card.chartType === 'bar') {
+    shapes = [
+      { field: 'rect', label: 'rect' },
+      { field: 'hollow-rect', label: 'hollow-rect' },
+      { field: 'line', label: 'line' },
+      { field: 'tick', label: 'tick' },
+      { field: 'funnel', label: 'funnel' },
+      { field: 'pyramid', label: 'pyramid' }
+    ]
+  }
+
+  let xfields = columns.filter(item => /^Nvarchar/ig.test(item.datatype))
+  let yfields = columns.filter(item => /^(Int|Decimal)/ig.test(item.datatype))
+
+  return [
     {
       type: 'radio',
       key: 'datatype',
@@ -155,7 +176,7 @@
     {
       type: 'radio',
       key: 'tooltip',
-      label: '鎻愮ず淇℃伅',
+      label: '鎮诞鎻愮ず',
       initVal: card.tooltip || 'true',
       required: false,
       options: [{
@@ -164,20 +185,6 @@
       }, {
         value: 'false',
         text: '闅愯棌'
-      }]
-    },
-    {
-      type: 'radio',
-      key: 'coordinate',
-      label: '鍧愭爣',
-      initVal: card.coordinate || 'angle',
-      required: false,
-      options: [{
-        value: 'angle',
-        text: '浜岀淮鍧愭爣'
-      }, {
-        value: 'polar',
-        text: '鏋佸潗鏍�'
       }]
     },
     {
@@ -200,6 +207,7 @@
       key: 'transpose',
       label: '鍙樻崲',
       initVal: card.transpose || 'false',
+      tooltip: '妯旱鍧愭爣杞翠氦鎹�',
       required: false,
       options: [{
         value: 'true',
@@ -212,21 +220,21 @@
     {
       type: 'radio',
       key: 'show',
-      label: '鏄剧ず鍊�',
+      label: '鏍煎紡鍖�',
       initVal: card.show || 'value',
       required: false,
       options: [{
+        value: 'value',
+        text: '鏃�'
+      }, {
         value: 'percent',
         text: '鐧惧垎姣�'
-      }, {
-        value: 'value',
-        text: '鏁板��'
       }]
     },
     {
       type: 'radio',
       key: 'label',
-      label: '鏍囨敞-鍊�',
+      label: '鏍囨敞鍊�',
       initVal: card.label || 'false',
       required: false,
       options: [{
@@ -267,6 +275,19 @@
         text: '绱姞'
       }]
     }, {
+      type: 'radio',
+      key: 'coordinate',
+      label: '鍧愭爣',
+      initVal: card.coordinate || 'angle',
+      required: false,
+      options: [{
+        value: 'angle',
+        text: '浜岀淮鍧愭爣'
+      }, {
+        value: 'polar',
+        text: '鏋佸潗鏍�'
+      }]
+    }, {
       type: 'number',
       key: 'InfoDefNumber',
       label: '灞曠ず鏁�',
@@ -302,15 +323,6 @@
         value: 'white',
         text: '鐧借壊'
       }]
-    }, {
-      type: 'select',
-      key: 'blacklist',
-      label: '榛戝悕鍗�',
-      initVal: card.blacklist || [],
-      multi: true,
-      required: false,
-      forbid: MenuType === 'billPrint',
-      options: _sysRoles
     }
   ]
 }
diff --git a/src/menu/components/chart/antv-bar/chartcompile/index.jsx b/src/menu/components/chart/antv-bar/chartcompile/index.jsx
index 5390f44..283faf1 100644
--- a/src/menu/components/chart/antv-bar/chartcompile/index.jsx
+++ b/src/menu/components/chart/antv-bar/chartcompile/index.jsx
@@ -5,13 +5,14 @@
 
 import Utils from '@/utils/utils.js'
 import { chartColors } from '@/utils/option.js'
-import { getBarOrLineChartOptionForm } from './formconfig'
+import { getBaseForm, getOptionForm } from './formconfig'
 import asyncComponent from '@/utils/asyncComponent'
 import ColorSketch from '@/mob/colorsketch'
 import './index.scss'
 
 const { TabPane } = Tabs
 const EditTable = asyncComponent(() => import('@/templates/zshare/editTable'))
+const NormalForm = asyncComponent(() => import('@/menu/components/share/normalform'))
 
 class LineChartDrawerForm extends Component {
   static propTpyes = {
@@ -29,6 +30,7 @@
     datatype: '',
     plot: null,
     formlist: null,
+    baseFormlist: null,
     fieldName: null,
     colorColumns: [
       {
@@ -166,7 +168,8 @@
       datatype: config.plot.datatype || 'query',
       fieldName: fieldName,
       plot: fromJS(config.plot).toJS(),
-      formlist: getBarOrLineChartOptionForm(config.plot, config.columns, sysRoles, MenuType)
+      baseFormlist: getBaseForm(config.plot, sysRoles, MenuType),
+      formlist: getOptionForm(config.plot, config.columns, MenuType)
     })
   }
 
@@ -218,7 +221,7 @@
                     message: this.props.dict['form.required.input'] + item.label + '!'
                   }
                 ]
-              })(<Input placeholder="" autoComplete="off" disabled={item.readonly}/>)}
+              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.onSubmit}/>)}
             </Form.Item>
           </Col>
         )
@@ -239,7 +242,7 @@
                     message: this.props.dict['form.required.input'] + item.label + '!'
                   }
                 ]
-              })(<InputNumber min={item.min} max={item.max} precision={item.decimal} />)}
+              })(<InputNumber min={item.min} max={item.max} precision={item.decimal} onPressEnter={this.onSubmit}/>)}
             </Form.Item>
           </Col>
         )
@@ -341,8 +344,10 @@
 
           if (values.datatype === 'statistics' || values.datatype !== plot.datatype) {
             _plot.enabled = 'false'
+            _plot.customs = []
           } else if (!values.Yaxis || !plot.Yaxis || !is(fromJS(values.Yaxis), fromJS(plot.Yaxis))) {
             _plot.enabled = 'false'
+            _plot.customs = []
             _plot.colors = null
           }
 
@@ -357,6 +362,17 @@
 
           this.props.plotchange({...config, plot: _plot})
         }
+      })
+    } else if (view === 'base') {
+      this.baseRef.handleConfirm().then(res => {
+        let _plot = {...plot, ...res}
+
+        this.setState({
+          plot: _plot,
+          visible: false
+        })
+
+        this.props.plotchange({...config, plot: _plot})
       })
     } else {
       this.setState({
@@ -397,7 +413,7 @@
                 name: labels[item] || item,
                 axis: i === 0 ? 'true' : 'false',
                 label: 'false',
-                shape: _plot.chartType === 'bar' ? ['bar', 'rect'] : ['line', 'smooth']
+                shape: _plot.chartType === 'bar' && i === 0 ? ['bar', 'rect'] : ['line', 'smooth']
               }
             })
           }
@@ -423,6 +439,13 @@
             view: tab
           })
         }
+      })
+    } else if (view === 'base') {
+      this.baseRef.handleConfirm().then(res => {
+        this.setState({
+          plot: {...plot, ...res},
+          view: tab
+        })
       })
     } else {
       this.setState({
@@ -457,7 +480,7 @@
   }
 
   render() {
-    const { view, visible, datatype, plot, colorColumns, statColorColumns, cusColumns } = this.state
+    const { view, visible, datatype, plot, colorColumns, statColorColumns, cusColumns, baseFormlist } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -483,7 +506,10 @@
           destroyOnClose
         >
           <Tabs activeKey={view} className="menu-chart-edit-box" onChange={this.changeTab}>
-            <TabPane tab="鍩虹璁剧疆" key="normal">
+            <TabPane tab="缁勪欢璁剧疆" key="base">
+              <NormalForm dict={this.props.dict} formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
+            </TabPane>
+            <TabPane tab="鍥捐〃璁剧疆" key="normal">
               <Form {...formItemLayout}>
                 <Row gutter={16}>{this.getFields()}</Row>
               </Form>
diff --git a/src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx b/src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx
index 5379e71..ccb8b2b 100644
--- a/src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx
+++ b/src/menu/components/chart/antv-pie/chartcompile/formconfig.jsx
@@ -8,48 +8,11 @@
  * @param {object} card       // 鍥捐〃瀵硅薄
  * @param {Array}  columns    // 鏄剧ず鍒�
  */
-export function getPieChartOptionForm (card, columns, sysRoles = [], MenuType) {
+export function getOptionForm (card, columns) {
   let xfields = columns.filter(item => /^Nvarchar/ig.test(item.datatype))
   let yfields = columns.filter(item => /^(Int|Decimal)/ig.test(item.datatype))
-  let _sysRoles = sysRoles.map(item => ({...item, field: item.value, label: item.text}))
 
   return [
-    {
-      type: 'text',
-      key: 'title',
-      label: '鏍囬',
-      initVal: card.title,
-      required: false
-    },
-    {
-      type: 'text',
-      key: 'name',
-      label: '缁勪欢鍚嶇О',
-      initVal: card.name,
-      tooltip: '鐢ㄤ簬缁勪欢闂寸殑鍖哄垎銆�',
-      required: true
-    },
-    {
-      type: 'number',
-      key: 'width',
-      label: '瀹藉害',
-      initVal: card.width,
-      tooltip: '鏍呮牸甯冨眬锛屾瘡琛岀瓑鍒嗕负24鍒椼��',
-      min: 1,
-      max: 24,
-      decimal: 0,
-      required: true
-    },
-    {
-      type: 'number',
-      key: 'height',
-      label: '楂樺害',
-      initVal: card.height,
-      min: 100,
-      max: 1000,
-      decimal: 0,
-      required: true
-    },
     {
       type: 'radio',
       key: 'shape',
@@ -126,7 +89,7 @@
     {
       type: 'radio',
       key: 'tooltip',
-      label: '鎻愮ず淇℃伅',
+      label: '鎮诞鎻愮ず',
       initVal: card.tooltip || 'true',
       required: false,
       options: [{
@@ -140,21 +103,21 @@
     {
       type: 'radio',
       key: 'show',
-      label: '鏄剧ず鍊�',
+      label: '鏍煎紡鍖�',
       initVal: card.show || 'value',
       required: false,
       options: [{
+        value: 'value',
+        text: '鏃�'
+      }, {
         value: 'percent',
         text: '鐧惧垎姣�'
-      }, {
-        value: 'value',
-        text: '鏁板��'
       }]
     },
     {
       type: 'radio',
       key: 'label',
-      label: '鏍囨敞',
+      label: '鏍囨敞鍊�',
       initVal: card.label || 'false',
       required: false,
       options: [{
@@ -197,15 +160,6 @@
         value: 'white',
         text: '鐧借壊'
       }]
-    }, {
-      type: 'select',
-      key: 'blacklist',
-      label: '榛戝悕鍗�',
-      initVal: card.blacklist || [],
-      multi: true,
-      required: false,
-      forbid: MenuType === 'billPrint',
-      options: _sysRoles
     }
   ]
 }
diff --git a/src/menu/components/chart/antv-pie/chartcompile/index.jsx b/src/menu/components/chart/antv-pie/chartcompile/index.jsx
index 7107522..790cfc2 100644
--- a/src/menu/components/chart/antv-pie/chartcompile/index.jsx
+++ b/src/menu/components/chart/antv-pie/chartcompile/index.jsx
@@ -4,7 +4,8 @@
 import { Modal, Form, Row, Col, Select, Icon, Radio, Tooltip, Input, InputNumber, Tabs, Button } from 'antd'
 
 import Utils from '@/utils/utils.js'
-import { getPieChartOptionForm } from './formconfig'
+import { getOptionForm } from './formconfig'
+import { getBaseForm } from '../../antv-bar/chartcompile/formconfig'
 import asyncComponent from '@/utils/asyncComponent'
 import ColorSketch from '@/mob/colorsketch'
 import './index.scss'
@@ -12,6 +13,7 @@
 const { TabPane } = Tabs
 
 const EditTable = asyncComponent(() => import('@/templates/zshare/editTable'))
+const NormalForm = asyncComponent(() => import('@/menu/components/share/normalform'))
 
 class LineChartDrawerForm extends Component {
   static propTpyes = {
@@ -27,6 +29,7 @@
     visible: false,
     plot: null,
     formlist: null,
+    baseFormlist: null,
     view: 'normal',
     colorColumns: [
       {
@@ -56,7 +59,8 @@
       visible: true,
       view: 'normal',
       plot: fromJS(config.plot).toJS(),
-      formlist: getPieChartOptionForm(config.plot, config.columns, sysRoles, MenuType)
+      baseFormlist: getBaseForm(config.plot, sysRoles, MenuType),
+      formlist: getOptionForm(config.plot, config.columns)
     })
   }
 
@@ -216,26 +220,6 @@
     return fields
   }
 
-  axisChange = (e) => {
-    const { plot } = this.state
-    let val = e.target.value
-    let fieldvalue = {}
-
-    plot.customs.forEach(item => {
-      if (this.props.form.getFieldValue(item.field + '$axis') === val) {
-        fieldvalue[item.field + '$axis'] = 'unset'
-      }
-    })
-    
-    this.props.form.setFieldsValue(fieldvalue)
-  }
-
-  enabledChange = (e) => {
-    let val = e.target.value
-
-    this.setState({enabled: val})
-  }
-
   onSubmit = () => {
     const { config } = this.props
     const { plot, view } = this.state
@@ -253,6 +237,17 @@
           this.props.plotchange({...config, plot: _plot})
         }
       })
+    } else if (view === 'base') {
+      this.baseRef.handleConfirm().then(res => {
+        let _plot = {...plot, ...res}
+
+        this.setState({
+          plot: _plot,
+          visible: false
+        })
+
+        this.props.plotchange({...config, plot: _plot})
+      })
     } else {
       this.setState({
         visible: false
@@ -263,9 +258,9 @@
   }
 
   changeTab = (tab) => {
-    const { plot } = this.state
+    const { plot, view } = this.state
 
-    if (tab === 'color') {
+    if (view === 'normal') {
       this.props.form.validateFieldsAndScroll((err, values) => {
         if (!err) {
           let _plot = {...plot, ...values}
@@ -275,6 +270,15 @@
             view: tab
           })
         }
+      })
+    } else if (view === 'base') {
+      this.baseRef.handleConfirm().then(res => {
+        let _plot = {...plot, ...res}
+
+        this.setState({
+          plot: _plot,
+          view: tab
+        })
       })
     } else {
       this.setState({
@@ -303,7 +307,7 @@
   }
 
   render() {
-    const { visible, plot, colorColumns, view } = this.state
+    const { visible, plot, colorColumns, view, baseFormlist } = this.state
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -329,7 +333,10 @@
           destroyOnClose
         >
           <Tabs activeKey={view} className="menu-chart-edit-box" onChange={this.changeTab}>
-            <TabPane tab="鍩虹璁剧疆" key="normal">
+            <TabPane tab="缁勪欢璁剧疆" key="base">
+              <NormalForm dict={this.props.dict} formlist={baseFormlist} inputSubmit={this.onSubmit} wrappedComponentRef={(inst) => this.baseRef = inst}/>
+            </TabPane>
+            <TabPane tab="鍥捐〃璁剧疆" key="normal">
               <Form {...formItemLayout}>
                 <Row gutter={16}>{this.getFields()}</Row>
               </Form>
diff --git a/src/menu/components/search/main-search/dragsearch/card.jsx b/src/menu/components/search/main-search/dragsearch/card.jsx
index 454e743..ec8e875 100644
--- a/src/menu/components/search/main-search/dragsearch/card.jsx
+++ b/src/menu/components/search/main-search/dragsearch/card.jsx
@@ -62,7 +62,7 @@
         <Icon className="close" title="delete" type="close" onClick={() => delCard(id)} />
       </div>
     } trigger="hover">
-      <div className="page-card" style={{ opacity: opacity}}>
+      <div className={'page-card ' + card.labelShow} style={{ opacity: opacity}}>
         <div ref={node => drag(drop(node))}>
           <div className="ant-row ant-form-item">
             <div className="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-8">
diff --git a/src/menu/components/search/main-search/dragsearch/index.jsx b/src/menu/components/search/main-search/dragsearch/index.jsx
index 178a530..4193afa 100644
--- a/src/menu/components/search/main-search/dragsearch/index.jsx
+++ b/src/menu/components/search/main-search/dragsearch/index.jsx
@@ -2,7 +2,7 @@
 import { useDrop } from 'react-dnd'
 import { is, fromJS } from 'immutable'
 import update from 'immutability-helper'
-import { Col } from 'antd'
+import { Col, Button } from 'antd'
 import Utils from '@/utils/utils.js'
 import Card from './card'
 import './index.scss'
@@ -92,7 +92,17 @@
           />
         </Col>
       ))}
-      
+      {cards.length > 0 ? <Col key="action" className="action" span={6}>
+        <div className="ant-row ant-form-item" style={{lineHeight: '40px', height: '55px', marginBottom: 0}}>
+          <div className="ant-col ant-form-item-label ant-col-xs-24 ant-col-sm-8">
+          </div>
+          <div className="ant-col ant-form-item-control-wrapper ant-col-xs-24 ant-col-sm-16">
+            <Button type="primary">鎼滅储</Button>
+            <Button style={{ marginLeft: 8 }}>閲嶇疆</Button>
+            <div style={{position: 'absolute', top: 0, bottom: 0, left: 0, right: 0}}></div>
+          </div>
+        </div>
+      </Col> : null}
       {cards.length === 0 ?
         <div className="common-drawarea-placeholder">
           {placeholder}
diff --git a/src/menu/components/search/main-search/index.jsx b/src/menu/components/search/main-search/index.jsx
index 6e7e13c..982ab49 100644
--- a/src/menu/components/search/main-search/index.jsx
+++ b/src/menu/components/search/main-search/index.jsx
@@ -343,7 +343,7 @@
     const { dict, card, visible, sqlVerifing } = this.state
 
     return (
-      <div className="main-search-edit-list" style={card.style}>
+      <div className={`main-search-edit-list ${card.wrap.float} ${card.wrap.show}`} style={card.style}>
         <DragElement
           list={card.search}
           handleList={this.handleList}
diff --git a/src/menu/components/search/main-search/index.scss b/src/menu/components/search/main-search/index.scss
index 543f44e..64c6210 100644
--- a/src/menu/components/search/main-search/index.scss
+++ b/src/menu/components/search/main-search/index.scss
@@ -1,10 +1,11 @@
 .main-search-edit-list {
   min-height: 50px;
   position: relative;
+  background: #ffffff;
 
   >.anticon-tool {
     position: absolute;
-    z-index: 1;
+    z-index: 3;
     font-size: 16px;
     right: 1px;
     top: 1px;
@@ -23,7 +24,6 @@
   }
   .page-card {
     position: relative;
-    background: #ffffff;
     border-radius: 2px;
     padding-bottom: 15px;
     .ant-form-item {
@@ -65,21 +65,10 @@
         }
       }
     }
-    .edit {
-      position: absolute;
-      left: 0;
-      top: 5px;
-      color: #1890ff;
-      cursor: pointer;
+  }
+  .page-card.false {
+    .ant-form-item-label {
       display: none;
-    }
-    .edit.copy {
-      left: 20px;
-      color: #26C281;
-    }
-    .edit.close {
-      left: 40px;
-      color: #ff4d4f;
     }
   }
   .page-card:hover {
@@ -92,6 +81,23 @@
     width: 100%;
   }
 }
+.main-search-edit-list.right {
+  >.ant-row {
+    >.ant-col {
+      float: right;
+    }
+    >.ant-col.action {
+      display: none;
+    }
+  }
+}
+.main-search-edit-list.false {
+  >.ant-row {
+    >.ant-col.action {
+      display: none;
+    }
+  }
+}
 .main-search-edit-list::after {
   display: block;
   content: ' ';
diff --git a/src/menu/components/search/main-search/wrapsetting/settingform/index.jsx b/src/menu/components/search/main-search/wrapsetting/settingform/index.jsx
index 330e44f..03954cf 100644
--- a/src/menu/components/search/main-search/wrapsetting/settingform/index.jsx
+++ b/src/menu/components/search/main-search/wrapsetting/settingform/index.jsx
@@ -1,6 +1,6 @@
 import React, {Component} from 'react'
 import PropTypes from 'prop-types'
-import { Form, Row, Col, Input, Tooltip, Icon, InputNumber, Select } from 'antd'
+import { Form, Row, Col, Input, Tooltip, Icon, InputNumber, Select, Radio } from 'antd'
 
 import './index.scss'
 
@@ -10,6 +10,10 @@
     wrap: PropTypes.object,      // 鏁版嵁婧愰厤缃�
     sysRoles: PropTypes.array,   // 瑙掕壊鍒楄〃
     inputSubmit: PropTypes.func  // 鍥炶溅浜嬩欢
+  }
+
+  state = {
+    float: this.props.wrap.float
   }
 
   handleConfirm = () => {
@@ -36,6 +40,7 @@
   render() {
     const { wrap, sysRoles } = this.props
     const { getFieldDecorator } = this.props.form
+    const { float } = this.state
 
     const formItemLayout = {
       labelCol: {
@@ -89,6 +94,35 @@
               </Form.Item>
             </Col>
             <Col span={12}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="鍙冲榻愭椂锛岄殣钘忔悳绱㈡寜閽��">
+                  <Icon type="question-circle" />
+                  瀵归綈
+                </Tooltip>
+              }>
+                {getFieldDecorator('float', {
+                  initialValue: wrap.float || 'left'
+                })(
+                  <Radio.Group onChange={(e) => this.setState({float: e.target.value})}>
+                    <Radio value="left">宸﹀榻�</Radio>
+                    <Radio value="right">鍙冲榻�</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col>
+            {float !== 'right' ? <Col span={12}>
+              <Form.Item label="鎼滅储鎸夐挳">
+                {getFieldDecorator('show', {
+                  initialValue: wrap.show || 'true'
+                })(
+                  <Radio.Group>
+                    <Radio value="true">鏄剧ず</Radio>
+                    <Radio value="false">闅愯棌</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col> : null}
+            <Col span={12}>
               <Form.Item label="榛戝悕鍗�">
                 {getFieldDecorator('blacklist', {
                   initialValue: wrap.blacklist || []
diff --git a/src/menu/components/share/normalform/index.jsx b/src/menu/components/share/normalform/index.jsx
new file mode 100644
index 0000000..0a52226
--- /dev/null
+++ b/src/menu/components/share/normalform/index.jsx
@@ -0,0 +1,170 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { Form, Row, Col, Input, Tooltip, Icon, InputNumber, Select, Radio } from 'antd'
+
+import './index.scss'
+
+class SettingForm extends Component {
+  static propTpyes = {
+    dict: PropTypes.object,      // 瀛楀吀椤�
+    formlist: PropTypes.array,   // 琛ㄥ崟
+    inputSubmit: PropTypes.func  // 鍥炶溅浜嬩欢
+  }
+
+  handleConfirm = () => {
+    // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
+    return new Promise((resolve, reject) => {
+      this.props.form.validateFieldsAndScroll((err, values) => {
+        if (!err) {
+          resolve(values)
+        } else {
+          reject(err)
+        }
+      })
+    })
+  }
+
+  handleSubmit = (e) => {
+    e.preventDefault()
+
+    if (this.props.inputSubmit) {
+      this.props.inputSubmit()
+    }
+  }
+
+  getFields() {
+    const { formlist } = this.props
+    const { getFieldDecorator } = this.props.form
+    const fields = []
+
+    if (!formlist) return []
+
+    formlist.forEach((item, index) => {
+      if (item.hidden || item.forbid) return
+      
+      if (item.type === 'text') {
+        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,
+                rules: [
+                  {
+                    required: item.required,
+                    message: this.props.dict['form.required.input'] + item.label + '!'
+                  }
+                ]
+              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.handleSubmit}/>)}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'number') {
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.tooltip ?
+              <Tooltip placement="topLeft" title={item.tooltip}>
+                <Icon type="question-circle" />
+                {item.label}
+              </Tooltip> : item.label
+            }>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal,
+                rules: [
+                  {
+                    required: item.required,
+                    message: this.props.dict['form.required.input'] + item.label + '!'
+                  }
+                ]
+              })(<InputNumber min={item.min} max={item.max} precision={item.decimal} onPressEnter={this.handleSubmit}/>)}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'select') { // 涓嬫媺
+        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,
+                rules: [
+                  {
+                    required: item.required,
+                    message: this.props.dict['form.required.select'] + item.label + '!'
+                  }
+                ]
+              })(
+                <Select mode={item.multi ? 'multiple' : ''}>
+                  {item.options.map((option, index) =>
+                    <Select.Option key={index} value={option.field}>
+                      {option.label}
+                    </Select.Option>
+                  )}
+                </Select>
+              )}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'radio') {
+        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,
+                rules: [
+                  {
+                    required: item.required,
+                    message: this.props.dict['form.required.select'] + item.label + '!'
+                  }
+                ]
+              })(
+                <Radio.Group disabled={item.readonly} onChange={(e) => this.radioChange(e, item.key)}>
+                  {item.options.map(option => {
+                    return (
+                      <Radio key={option.value} value={option.value}>{option.text}</Radio>
+                    )
+                  })}
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
+        )
+      }
+    })
+    return fields
+  }
+
+  render() {
+    const formItemLayout = {
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 8 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      }
+    }
+
+    return (
+      <div className="model-menu-normal-form">
+        <Form {...formItemLayout}><Row gutter={16}>{this.getFields()}</Row></Form>
+      </div>
+    )
+  }
+}
+
+export default Form.create()(SettingForm)
\ No newline at end of file
diff --git a/src/menu/components/share/normalform/index.scss b/src/menu/components/share/normalform/index.scss
new file mode 100644
index 0000000..5b30221
--- /dev/null
+++ b/src/menu/components/share/normalform/index.scss
@@ -0,0 +1,11 @@
+.model-menu-normal-form {
+  position: relative;
+
+  .anticon-question-circle {
+    color: #c49f47;
+    margin-right: 3px;
+  }
+  .ant-input-number {
+    width: 100%;
+  }
+}
\ No newline at end of file
diff --git a/src/menu/components/table/normal-table/cardcomponent/index.jsx b/src/menu/components/table/normal-table/cardcomponent/index.jsx
new file mode 100644
index 0000000..3d0f004
--- /dev/null
+++ b/src/menu/components/table/normal-table/cardcomponent/index.jsx
@@ -0,0 +1,208 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Modal, Popover, Icon } from 'antd'
+
+import asyncComponent from '@/utils/asyncComponent'
+import zhCN from '@/locales/zh-CN/model.js'
+import enUS from '@/locales/en-US/model.js'
+import SettingForm from './settingform'
+
+import Utils from '@/utils/utils.js'
+import MKEmitter from '@/utils/events.js'
+import './index.scss'
+
+const CardCellComponent = asyncComponent(() => import('../../cardcellcomponent'))
+
+class CardBoxComponent extends Component {
+  static propTpyes = {
+    cards: PropTypes.object,         // 鍗$墖琛岄厤缃俊鎭�
+    card: PropTypes.object,          // 鍗$墖閰嶇疆淇℃伅
+    deleteElement: PropTypes.func,   // 鍗$墖鍒犻櫎
+    updateElement: PropTypes.func    // 鑿滃崟閰嶇疆鏇存柊
+  }
+
+  state = {
+    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
+    card: null,            // 鍗$墖淇℃伅锛屽寘鎷鍙嶉潰
+    formlist: null,        // 璁剧疆琛ㄥ崟淇℃伅
+    elements: null,        // 缂栬緫缁�
+    visible: false,        // 妯℃�佹鎺у埗
+    settingVisible: false,
+  }
+
+  /**
+   * @description 鎼滅储鏉′欢鍒濆鍖�
+   */
+  UNSAFE_componentWillMount () {
+    const { card } = this.props
+
+    this.setState({
+      card: fromJS(card).toJS(),
+      elements: fromJS(card.elements).toJS(),
+    })
+  }
+
+  componentDidMount () {
+    MKEmitter.addListener('submitStyle', this.getStyle)
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.props.cards), fromJS(nextProps.cards)) || !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+    MKEmitter.removeListener('submitStyle', this.getStyle)
+  }
+
+  getStyle = (comIds, style) => {
+    const { cards } = this.props
+    const { card } = this.state
+
+    if (comIds.length !== 2 || comIds[0] !== cards.uuid || comIds[1] !== card.uuid) return
+
+    let _card = fromJS(card).toJS()
+    _card.style = style
+
+    this.setState({
+      card: _card
+    })
+
+    this.props.updateElement(_card)
+  }
+
+  updateCard = (elements) => {
+    const { card } = this.state
+
+    let _card = {...card, elements: elements}
+
+    this.setState({
+      card: _card
+    })
+
+    this.props.updateElement(_card)
+  }
+  
+  addElement = () => {
+    const { cards } = this.props
+    const { card } = this.state
+
+    let newcard = {}
+    newcard.uuid = Utils.getuuid()
+    newcard.focus = true
+    
+    newcard.eleType = 'text'
+    newcard.datatype = 'dynamic'
+    newcard.color = 'rgba(0,0,0,0.85)'
+    newcard.padding = '5px'
+    newcard.align = 'left'
+
+    // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
+    MKEmitter.emit('cardAddElement', [cards.uuid, card.uuid], newcard)
+  }
+
+  addButton = () => {
+    const { cards } = this.props
+    const { card } = this.state
+
+    let newcard = {}
+    newcard.uuid = Utils.getuuid()
+    newcard.focus = true
+    
+    newcard.eleType = 'button'
+    newcard.label = 'button'
+    newcard.sqlType = ''
+    newcard.Ot = 'requiredSgl'
+    newcard.OpenType = 'prompt'
+    newcard.icon = ''
+    newcard.class = 'primary'
+    newcard.intertype = 'system'
+    newcard.method = 'POST'
+    newcard.execSuccess = 'grid'
+    newcard.execError = 'never'
+    newcard.popClose = 'never'
+    newcard.errorTime = 10
+    newcard.verify = null
+    newcard.show = 'link'
+
+    // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
+    MKEmitter.emit('cardAddElement', [cards.uuid, card.uuid], newcard)
+  }
+
+  changeStyle = () => {
+    const { cards } = this.props
+    const { card } = this.state
+
+    let _style = null
+    let options = ['height', 'background', 'border', 'padding', 'margin']
+    _style = card.style ? fromJS(card.style).toJS() : {}
+
+    MKEmitter.emit('changeStyle', [cards.uuid, card.uuid], options, _style)
+  }
+
+  settingSubmit = () => {
+    const { card } = this.state
+
+    this.settingRef.handleConfirm().then(res => {
+      this.setState({
+        settingVisible: false,
+        card: {...card, setting: res}
+      })
+
+      this.props.updateElement({...card, setting: res})
+    })
+  }
+
+  render() {
+    const { cards } = this.props
+    const { card, elements, settingVisible, dict } = this.state
+
+    return (
+      <div className="ant-col ant-col-24">
+        <div className="card-item" style={card.style}>
+          <CardCellComponent cards={cards} cardCell={card} elements={elements} updateElement={this.updateCard}/>
+          <div className="card-control">
+            <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+              <div className="mk-popover-control">
+                <Icon className="plus" title="娣诲姞鍏冪礌" onClick={this.addElement} type="plus" />
+                <Icon className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton} type="plus-square" />
+                <Icon className="edit" type="edit" onClick={() => this.setState({settingVisible: true})} />
+                <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
+                <Icon className="close" title="鍒犻櫎鍗$墖" type="delete" onClick={() => this.props.deleteElement(card)} />
+              </div>
+            } trigger="hover">
+              <Icon type="tool" />
+            </Popover>
+          </div>
+        </div>
+        <Modal
+          wrapClassName="popview-modal"
+          title={'琛岃缃�'}
+          visible={settingVisible}
+          width={700}
+          maskClosable={false}
+          okText={dict['model.submit']}
+          onOk={this.settingSubmit}
+          onCancel={() => { this.setState({ settingVisible: false }) }}
+          destroyOnClose
+        >
+          <SettingForm
+            dict={dict}
+            cards={cards}
+            setting={card.setting}
+            inputSubmit={this.settingSubmit}
+            wrappedComponentRef={(inst) => this.settingRef = inst}
+          />
+        </Modal>
+      </div>
+    )
+  }
+}
+
+export default CardBoxComponent
\ No newline at end of file
diff --git a/src/menu/components/table/normal-table/cardcomponent/index.scss b/src/menu/components/table/normal-table/cardcomponent/index.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/menu/components/table/normal-table/cardcomponent/index.scss
diff --git a/src/menu/components/table/normal-table/cardcomponent/settingform/index.jsx b/src/menu/components/table/normal-table/cardcomponent/settingform/index.jsx
new file mode 100644
index 0000000..ba0dcf4
--- /dev/null
+++ b/src/menu/components/table/normal-table/cardcomponent/settingform/index.jsx
@@ -0,0 +1,131 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { Form, Row, Col, Radio, Tooltip, Icon, Input, Select } from 'antd'
+
+import './index.scss'
+
+class SettingForm extends Component {
+  static propTpyes = {
+    dict: PropTypes.object,      // 瀛楀吀椤�
+    cards: PropTypes.object,     // 鍗$墖闆�
+    setting: PropTypes.object,   // 鏁版嵁婧愰厤缃�
+    inputSubmit: PropTypes.func  // 鍥炶溅浜嬩欢
+  }
+
+  state = {
+    condition: this.props.setting.condition || 'false'
+  }
+
+  handleConfirm = () => {
+    // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
+    return new Promise((resolve, reject) => {
+      this.props.form.validateFieldsAndScroll((err, values) => {
+        if (!err) {
+          resolve(values)
+        } else {
+          reject(err)
+        }
+      })
+    })
+  }
+
+  handleSubmit = (e) => {
+    e.preventDefault()
+
+    if (this.props.inputSubmit) {
+      this.props.inputSubmit()
+    }
+  }
+
+  render() {
+    const { setting, cards } = this.props
+    const { getFieldDecorator } = this.props.form
+
+    const formItemLayout = {
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 8 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      }
+    }
+
+    return (
+      <div className="model-menu-setting-form">
+        <Form {...formItemLayout}>
+          <Row gutter={24}>
+            <Col span={12}>
+              <Form.Item label={
+                <Tooltip placement="topLeft" title="褰撻�夋嫨鈥滄湁鈥濇椂锛屽彧鏈夌鍚堟潯浠剁殑鏁版嵁鎵嶄細灞曠ず銆�">
+                  <Icon type="question-circle" />
+                  鏄剧ず鏉′欢
+                </Tooltip>
+              }>
+                {getFieldDecorator('condition', {
+                  initialValue: setting.condition || 'false'
+                })(
+                  <Radio.Group onChange={(e) => this.setState({ condition: e.target.value })}>
+                    <Radio value="true">鏈�</Radio>
+                    <Radio value="false">鏃�</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col>
+            {this.state.condition === 'true' ? <Col span={12}>
+              <Form.Item label="鎺у埗瀛楁">
+                {getFieldDecorator('controlField', {
+                  initialValue: setting.controlField || '',
+                  rules: [
+                    {
+                      required: true,
+                      message: this.props.dict['form.required.select'] + '鎺у埗瀛楁!'
+                    }
+                  ]
+                })(
+                  <Select>
+                    {cards.columns.map((option, index) =>
+                      <Select.Option key={index} value={option.field}>
+                        {option.label}
+                      </Select.Option>
+                    )}
+                  </Select>
+                )}
+              </Form.Item>
+            </Col> : null}
+            {this.state.condition === 'true' ? <Col span={12}>
+              <Form.Item label="瀵规瘮鏂瑰紡">
+                {getFieldDecorator('controlType', {
+                  initialValue: setting.controlType || '=',
+                  rules: [
+                    {
+                      required: true,
+                      message: this.props.dict['form.required.select'] + '瀵规瘮鏂瑰紡!'
+                    }
+                  ]
+                })(
+                  <Radio.Group>
+                    <Radio value="=">=</Radio>
+                    <Radio value="!=">!=</Radio>
+                    <Radio value=">">&gt;</Radio>
+                    <Radio value="<">&lt;</Radio>
+                  </Radio.Group>
+                )}
+              </Form.Item>
+            </Col> : null}
+            {this.state.condition === 'true' ? <Col span={12}>
+              <Form.Item label="瀵规瘮鍊�">
+                {getFieldDecorator('controlValue', {
+                  initialValue: setting.controlValue || ''
+                })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit}/>)}
+              </Form.Item>
+            </Col> : null}
+          </Row>
+        </Form>
+      </div>
+    )
+  }
+}
+
+export default Form.create()(SettingForm)
\ No newline at end of file
diff --git a/src/menu/components/table/normal-table/cardcomponent/settingform/index.scss b/src/menu/components/table/normal-table/cardcomponent/settingform/index.scss
new file mode 100644
index 0000000..159130b
--- /dev/null
+++ b/src/menu/components/table/normal-table/cardcomponent/settingform/index.scss
@@ -0,0 +1,11 @@
+.model-menu-setting-form {
+  position: relative;
+
+  .anticon-question-circle {
+    color: #c49f47;
+    margin-right: 3px;
+  }
+  .ant-input-number {
+    width: 100%;
+  }
+}
\ No newline at end of file
diff --git a/src/menu/components/table/normal-table/index.jsx b/src/menu/components/table/normal-table/index.jsx
new file mode 100644
index 0000000..fd79a3f
--- /dev/null
+++ b/src/menu/components/table/normal-table/index.jsx
@@ -0,0 +1,289 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import {connect} from 'react-redux'
+import { is, fromJS } from 'immutable'
+import { Icon, Popover, Modal } from 'antd'
+
+import asyncComponent from '@/utils/asyncComponent'
+import asyncIconComponent from '@/utils/asyncIconComponent'
+
+import MKEmitter from '@/utils/events.js'
+import Utils from '@/utils/utils.js'
+import zhCN from '@/locales/zh-CN/model.js'
+import enUS from '@/locales/en-US/model.js'
+import './index.scss'
+
+const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
+const WrapComponent = asyncIconComponent(() => import('../data-card/wrapsetting'))
+const SearchComponent = asyncComponent(() => import('@/menu/searchcomponent'))
+const CardComponent = asyncComponent(() => import('./cardcomponent'))
+
+const { confirm } = Modal
+
+class TableCardEditComponent extends Component {
+  static propTpyes = {
+    card: PropTypes.object,
+    deletecomponent: PropTypes.func,
+    updateConfig: PropTypes.func,
+  }
+
+  state = {
+    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
+    card: null,
+    back: false
+  }
+
+  UNSAFE_componentWillMount () {
+    const { card } = this.props
+
+    if (card.isNew) {
+      let subcards = null
+
+      if (card.config) {
+        subcards = JSON.parse(card.config)
+        subcards = subcards.map(scard => {
+          scard.uuid = Utils.getuuid()
+          scard.elements = scard.elements.map(elem => {
+            elem.uuid = Utils.getuuid()
+            return elem
+          })
+          return scard
+        })
+      } else {
+        subcards = [{
+          uuid: Utils.getuuid(),
+          setting: { width: 24, type: 'simple'},
+          style: {
+            paddingTop: '5px', paddingBottom: '5px', paddingLeft: '15px', paddingRight: '15px',
+          },
+          elements: []
+        }]
+      }
+
+      let _card = {
+        uuid: card.uuid,
+        type: card.type,
+        floor: card.floor,
+        tabId: card.tabId || '',
+        parentId: card.parentId || '',
+        format: 'array',    // 缁勪欢灞炴�� - 鏁版嵁鏍煎紡
+        pageable: true,     // 缁勪欢灞炴�� - 鏄惁鍙垎椤�
+        switchable: false,  // 缁勪欢灞炴�� - 鏁版嵁鏄惁鍙垏鎹�
+        dataName: card.dataName || '',
+        width: 12,
+        search: [],
+        name: card.name,
+        subtype: card.subtype,
+        setting: { interType: 'system' },
+        wrap: { name: card.name, width: 12 },
+        style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' },
+        headerStyle: { fontSize: '16px' },
+        columns: [],
+        scripts: [],
+        subcards: subcards
+      }
+      
+      this.setState({
+        card: _card
+      })
+      this.props.updateConfig(_card)
+    } else {
+      this.setState({
+        card: fromJS(card).toJS()
+      })
+    }
+  }
+
+  componentDidMount () {
+    MKEmitter.addListener('submitStyle', this.getStyle)
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState)) || (!this.props.menu && nextProps.menu)
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+    MKEmitter.removeListener('submitStyle', this.getStyle)
+  }
+
+  /**
+   * @description 鍗$墖琛屽灞備俊鎭洿鏂帮紙鏁版嵁婧愶紝鏍峰紡绛夛級
+   */
+  updateComponent = (component) => {
+    this.setState({
+      card: component
+    })
+
+    component.width = component.wrap.width
+    component.name = component.wrap.name
+
+    this.props.updateConfig(component)
+  }
+
+  /**
+   * @description 鍗曚釜鍗$墖淇℃伅鏇存柊
+   */
+  updateCard = (cell) => {
+    let card = fromJS(this.state.card).toJS()
+
+    card.subcards = card.subcards.map(item => {
+      if (item.uuid === cell.uuid) return cell
+      return item
+    })
+
+    this.setState({card})
+
+    this.props.updateConfig(card)
+  }
+
+  /**
+   * @description 鍗曚釜鍗$墖淇℃伅鏇存柊
+   */
+  deleteCard = (cell) => {
+    let card = fromJS(this.state.card).toJS()
+    let _this = this
+
+    confirm({
+      content: '纭畾鍒犻櫎鍗$墖鍚楋紵',
+      onOk() {
+        card.subcards = card.subcards.filter(item => item.uuid !== cell.uuid)
+    
+        _this.setState({card})
+        _this.props.updateConfig(card)
+      },
+      onCancel() {}
+    })
+  }
+
+  changeStyle = () => {
+    const { card } = this.state
+
+    MKEmitter.emit('changeStyle', [card.uuid], ['background', 'border', 'padding', 'margin'], card.style)
+  }
+
+  changeTitleStyle = () => {
+    const { card } = this.state
+
+    MKEmitter.emit('changeStyle', [card.uuid, 'header'], ['font', 'border'], card.headerStyle)
+  }
+
+  getStyle = (comIds, style) => {
+    const { card } = this.state
+
+    if (comIds[0] !== card.uuid) return
+
+    let _card = {}
+    if (comIds.length === 1) {
+      _card = {...card, style}
+    } else if (comIds.length === 2 && comIds[1] === 'header') {
+      _card = {...card, headerStyle: style}
+    } else {
+      return
+    }
+
+    this.setState({
+      card: _card
+    })
+    
+    this.props.updateConfig(_card)
+  }
+
+  addCard = () => {
+    let card = fromJS(this.state.card).toJS()
+
+    let newcard = {
+      uuid: Utils.getuuid(),
+      setting: { width: 6, type: 'simple'},
+      style: {
+        paddingTop: '5px', paddingBottom: '5px', paddingLeft: '15px', paddingRight: '15px',
+      },
+      elements: []
+    }
+
+    if (card.subcards.length > 0) {
+      newcard = fromJS(card.subcards[card.subcards.length - 1]).toJS()
+      newcard.uuid = Utils.getuuid()
+      newcard.elements = newcard.elements.map(elem => {
+        elem.uuid = Utils.getuuid()
+        return elem
+      })
+    }
+
+    card.subcards.push(newcard)
+    
+    this.setState({card})
+    this.props.updateConfig(card)
+  }
+
+  addSearch = () => {
+    const { card } = this.state
+
+    let newcard = {}
+    newcard.uuid = Utils.getuuid()
+    newcard.focus = true
+
+    newcard.label = 'label'
+    newcard.initval = ''
+    newcard.type = 'select'
+    newcard.resourceType = '0'
+    newcard.options = []
+    newcard.setAll = 'false'
+    newcard.orderType = 'asc'
+    newcard.display = 'dropdown'
+    newcard.match = '='
+
+    // 娉ㄥ唽浜嬩欢-娣诲姞鎼滅储
+    MKEmitter.emit('addSearch', card.uuid, newcard)
+  }
+
+  render() {
+    const { menu } = this.props
+    const { card } = this.state
+
+    return (
+      <div className="menu-table-card-edit-box" style={{...card.style, height: card.wrap.height}}>
+        <div className="table-header" style={card.headerStyle}>
+          <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+            <div className="mk-popover-control">
+              <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeTitleStyle} type="font-colors" />
+            </div>
+          } trigger="hover">
+            <span className="table-title">{card.wrap.title || ''}</span>
+          </Popover>
+          <SearchComponent config={card} updatesearch={this.updateComponent}/>
+        </div>
+        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+          <div className="mk-popover-control">
+            <Icon className="plus" title="娣诲姞鍗$墖" onClick={this.addCard} type="plus" />
+            <Icon className="plus" title="娣诲姞鎼滅储" onClick={this.addSearch} type="plus-circle" />
+            {menu ? <WrapComponent config={card} sysRoles={menu.sysRoles} MenuType={menu.MenuType} updateConfig={this.updateComponent} /> : null}
+            <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
+            <Icon className="close" title="鍒犻櫎缁勪欢" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
+            {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null}
+          </div>
+        } trigger="hover">
+          <Icon type="tool" />
+        </Popover>
+        {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} MenuType={menu ? menu.MenuType : ''} cards={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
+      </div>
+    )
+  }
+}
+
+const mapStateToProps = (state) => {
+  return {
+    menu: state.customMenu
+  }
+}
+
+const mapDispatchToProps = () => {
+  return {}
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(TableCardEditComponent)
\ No newline at end of file
diff --git a/src/menu/components/table/normal-table/index.scss b/src/menu/components/table/normal-table/index.scss
new file mode 100644
index 0000000..88da58c
--- /dev/null
+++ b/src/menu/components/table/normal-table/index.scss
@@ -0,0 +1,92 @@
+.menu-table-card-edit-box {
+  position: relative;
+  box-sizing: border-box;
+  background: #ffffff;
+  background-position: center center;
+  background-repeat: no-repeat;
+  background-size: cover;
+  min-height: 100px;
+  
+  .table-header {
+    position: relative;
+    height: 45px;
+    overflow: hidden;
+    padding-right: 35px;
+
+    .table-title {
+      text-decoration: inherit;
+      font-weight: inherit;
+      font-style: inherit;
+      float: left;
+      line-height: 45px;
+      margin-left: 10px;
+      position: relative;
+      z-index: 1;
+    }
+  }
+  .card-control {
+    position: absolute;
+    top: 0px;
+    left: 0px;
+    .anticon-tool {
+      right: auto;
+      left: 1px;
+      padding: 1px;
+    }
+  }
+  .anticon-tool {
+    position: absolute;
+    z-index: 1;
+    font-size: 16px;
+    right: 1px;
+    top: 1px;
+    cursor: pointer;
+    padding: 5px;
+    background: rgba(255, 255, 255, 0.55);
+  }
+
+  .card-item {
+    overflow-y: hidden;
+    position: relative;
+    background-position: center center;
+    background-repeat: no-repeat;
+    background-size: cover;
+    min-height: 20px;
+  }
+  
+  .card-item:hover {
+    box-shadow: 0px 0px 2px #e8e8e8;
+  }
+
+  .model-menu-card-cell-list .card-detail-row > .anticon-plus {
+    position: absolute;
+    right: -30px;
+    font-size: 16px;
+  }
+  .model-menu-action-list {
+    line-height: 40px;
+    .ant-row > .anticon-plus {
+      position: absolute;
+      right: -30px;
+      font-size: 16px;
+    }
+  }
+  .card-add-button {
+    text-align: right;
+    clear: left;
+    .anticon-plus {
+      font-size: 20px;
+      color: #26C281;
+      padding: 5px;
+      margin-right: 10px;
+    }
+  }
+}
+.menu-table-card-edit-box::after {
+  display: block;
+  content: ' ';
+  clear: both;
+}
+.menu-table-card-edit-box:hover {
+  box-shadow: 0px 0px 2px #e8e8e8;
+}
diff --git a/src/menu/components/tabs/tabsetting/settingform/index.jsx b/src/menu/components/tabs/tabsetting/settingform/index.jsx
index 818ea3f..c82dd8c 100644
--- a/src/menu/components/tabs/tabsetting/settingform/index.jsx
+++ b/src/menu/components/tabs/tabsetting/settingform/index.jsx
@@ -14,10 +14,6 @@
 
   state = {}
 
-  UNSAFE_componentWillMount () {
-
-  }
-
   handleConfirm = () => {
     // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
     return new Promise((resolve, reject) => {
diff --git a/src/router/index.js b/src/router/index.js
index 46c93e1..a794081 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -7,6 +7,7 @@
 import asyncLoadComponent from '@/utils/asyncLoadComponent'
 
 const Pay = asyncLoadComponent(() => import('@/views/pay'))
+const Sso = asyncLoadComponent(() => import('@/views/sso'))
 const Main = asyncLoadComponent(() => import('@/views/main'))
 const Login = asyncLoadComponent(() => import('@/views/login'))
 const NotFound = asyncComponent(() => import('@/views/404'))
@@ -20,7 +21,7 @@
   {path: '/login', name: 'login', component: Login, auth: false},
   {path: '/pay/:param', name: 'pay', component: Pay, auth: false},
   {path: '/print/:param', name: 'print', component: PrintT, auth: false},
-  {path: '/ssologin/:param', name: 'ssologin', auth: true},
+  {path: '/ssologin/:param', name: 'ssologin', component: Sso, auth: false},
   {path: '/main', name: 'main', component: Main, auth: true},
   {path: '/mobmanage', name: 'mobmanage', component: MobManage, auth: true},
   {path: '/mobdesign/:appId/:appType/:appCode/:appName', name: 'mobdesign', component: MobDesign, auth: true},
@@ -31,7 +32,7 @@
 
 export default class RouteConfig extends Component {
   controlRoute (item, props) {
-    if (!item.auth) {            // 涓嶉渶瑕佹巿鏉冿紝鐩存帴璺宠浆锛堢櫥褰曢〉锛�
+    if (!item.auth) {            // 涓嶉渶瑕佹巿鏉冿紝鐩存帴璺宠浆
       return (<item.component {...props}/>)
     }
 
@@ -75,25 +76,6 @@
       }
 
       return (<item.component {...props}/>)
-    } else if (item.name === 'ssologin') {
-      try {
-        let _param = JSON.parse(window.decodeURIComponent(window.atob(props.match.params.param)))
-        if (typeof(_param) === 'object') {
-          if (_param.UserID) {
-            sessionStorage.setItem('UserID', _param.UserID)
-          }
-          if (_param.LoginUID) {
-            sessionStorage.setItem('LoginUID', _param.LoginUID)
-          }
-          if (_param.User_Name) {
-            sessionStorage.setItem('User_Name', _param.User_Name)
-          }
-        }
-      } catch {
-        console.warn('鑿滃崟鍙傛暟瑙f瀽閿欒锛�')
-      }
-
-      return (<Redirect to={{ pathname: '/main'}}/>)
     }
     
     let userId = sessionStorage.getItem('UserID') // 鍒ゆ柇鏄惁瀛樺湪userid
diff --git a/src/tabviews/custom/components/card/data-card/index.scss b/src/tabviews/custom/components/card/data-card/index.scss
index 9f7d929..91a0db0 100644
--- a/src/tabviews/custom/components/card/data-card/index.scss
+++ b/src/tabviews/custom/components/card/data-card/index.scss
@@ -39,6 +39,7 @@
     flex: 10;
 
     .card-item-box {
+      background-color: #ffffff;
       transition: all 0.3s;
     }
     >.active >.card-item-box {
diff --git a/src/tabviews/custom/components/card/prop-card/index.scss b/src/tabviews/custom/components/card/prop-card/index.scss
index b03d482..dae2885 100644
--- a/src/tabviews/custom/components/card/prop-card/index.scss
+++ b/src/tabviews/custom/components/card/prop-card/index.scss
@@ -14,6 +14,7 @@
 
   .card-row-list {
     .card-item-box {
+      background-color: #ffffff;
       transition: all 0.3s;
     }
     >.active >.card-item-box {
diff --git a/src/tabviews/custom/components/card/table-card/index.scss b/src/tabviews/custom/components/card/table-card/index.scss
index 26c5a25..04dbf0f 100644
--- a/src/tabviews/custom/components/card/table-card/index.scss
+++ b/src/tabviews/custom/components/card/table-card/index.scss
@@ -36,6 +36,7 @@
   .card-row-list {
     overflow-y: auto;
     .card-item-box {
+      background-color: #ffffff;
       transition: all 0.3s;
     }
     >.active >.card-item-box {
diff --git a/src/tabviews/custom/components/search/main-search/index.jsx b/src/tabviews/custom/components/search/main-search/index.jsx
index 1aad4c6..e6ab5e5 100644
--- a/src/tabviews/custom/components/search/main-search/index.jsx
+++ b/src/tabviews/custom/components/search/main-search/index.jsx
@@ -434,6 +434,7 @@
 
   getFields() {
     const { getFieldDecorator } = this.props.form
+    const { config } = this.props
     const fields = []
 
     this.state.searchlist.forEach((item, index) => {
@@ -442,7 +443,7 @@
       if (item.type === 'text') { // 鏂囨湰鎼滅储
         fields.push(
           <Col span={item.ratio || 6} key={index}>
-            <Form.Item label={item.label}>
+            <Form.Item label={item.labelShow !== 'false' ? item.label : ''}>
               {getFieldDecorator(item.field, {
                 initialValue: item.initval,
                 rules: [
@@ -458,7 +459,7 @@
       } else if (item.type === 'select') { // 涓嬫媺鎼滅储
         fields.push(
           <Col span={item.ratio || 6} key={index}>
-            <Form.Item label={item.label}>
+            <Form.Item label={item.labelShow !== 'false' ? item.label : ''}>
               {getFieldDecorator(item.field, {
                 initialValue: item.initval,
                 rules: [
@@ -486,7 +487,7 @@
         let _initval = item.initval ? item.initval.split(',').filter(Boolean) : []
         fields.push(
           <Col span={item.ratio || 6} key={index}>
-            <Form.Item label={item.label}>
+            <Form.Item label={item.labelShow !== 'false' ? item.label : ''}>
               {getFieldDecorator(item.field, {
                 initialValue: _initval,
                 rules: [
@@ -514,7 +515,7 @@
       } else if (item.type === 'date') { // 鏃堕棿鎼滅储
         fields.push(
           <Col span={item.ratio || 6} key={index}>
-            <Form.Item label={item.label}>
+            <Form.Item label={item.labelShow !== 'false' ? item.label : ''}>
               {getFieldDecorator(item.field, {
                 initialValue: item.initval ? moment().subtract(item.initval, 'days') : null,
                 rules: [
@@ -532,7 +533,7 @@
       } else if (item.type === 'datemonth') {
         fields.push(
           <Col span={item.ratio || 6} key={index}>
-            <Form.Item label={item.label}>
+            <Form.Item label={item.labelShow !== 'false' ? item.label : ''}>
               {getFieldDecorator(item.field, {
                 initialValue: item.initval ? moment().subtract(item.initval, 'month') : null,
                 rules: [
@@ -550,7 +551,7 @@
       } else if (item.type === 'dateweek') {
         fields.push(
           <Col span={item.ratio || 6} key={index}>
-            <Form.Item label={item.label}>
+            <Form.Item label={item.labelShow !== 'false' ? item.label : ''}>
               {getFieldDecorator(item.field, {
                 initialValue: item.initval ? moment().subtract(item.initval * 7, 'days') : null,
                 rules: [
@@ -579,7 +580,7 @@
 
         fields.push(
           <Col className="daterange" span={item.ratio || 6} key={index}>
-            <Form.Item label={item.label}>
+            <Form.Item label={item.labelShow !== 'false' ? item.label : ''}>
               {getFieldDecorator(item.field,
                 {
                   initialValue: _defaultValue,
@@ -603,7 +604,7 @@
       } else if (item.type === 'group') {
         fields.push(
           <Col span={item.ratio || 6} key={index}>
-            <Form.Item label={item.label} className={item.required === 'true' ? 'group-required' : ''}>
+            <Form.Item label={item.labelShow !== 'false' ? item.label : ''} className={item.required === 'true' ? 'group-required' : ''}>
               <DateGroup ref={item.uuid} position={index} card={item} onGroupChange={this.searchChange} />
             </Form.Item>
           </Col>
@@ -611,18 +612,20 @@
       }
     })
 
-    fields.push(
-      <Col span={6} style={{ whiteSpace: 'nowrap' }} key="actions">
-        <Form.Item label={' '} colon={false} style={{ minHeight: '40px' }}>
-          <Button type="primary" htmlType="submit">
-            {this.state.dict['main.search']}
-          </Button>
-          <Button style={{ marginLeft: 8 }} onClick={this.handleReset}>
-            {this.state.dict['main.reset']}
-          </Button>
-        </Form.Item>
-      </Col>
-    )
+    if (config.wrap.float !== 'right' && config.wrap.show !== 'false') {
+      fields.push(
+        <Col span={6} style={{ whiteSpace: 'nowrap' }} key="actions">
+          <Form.Item label={' '} colon={false} style={{ minHeight: '40px' }}>
+            <Button type="primary" htmlType="submit">
+              {this.state.dict['main.search']}
+            </Button>
+            <Button style={{ marginLeft: 8 }} onClick={this.handleReset}>
+              {this.state.dict['main.reset']}
+            </Button>
+          </Form.Item>
+        </Col>
+      )
+    }
     
     return fields
   }
@@ -770,6 +773,7 @@
   }
 
   render() {
+    const { config } = this.props
     const formItemLayout = {
       labelCol: {
         xs: { span: 24 },
@@ -782,7 +786,7 @@
     }
 
     return (
-      <Form {...formItemLayout} className="custom-main-search" id={this.state.formId} onSubmit={this.handleSearch}>
+      <Form {...formItemLayout} className={`custom-main-search ${config.wrap.float} ${config.wrap.show}`} style={config.style} id={this.state.formId} onSubmit={this.handleSearch}>
         <Row gutter={24}>{this.getFields()}</Row>
       </Form>
     )
diff --git a/src/tabviews/custom/components/search/main-search/index.scss b/src/tabviews/custom/components/search/main-search/index.scss
index 4b220df..8b7c1f4 100644
--- a/src/tabviews/custom/components/search/main-search/index.scss
+++ b/src/tabviews/custom/components/search/main-search/index.scss
@@ -1,4 +1,5 @@
 .custom-main-search {
+  background: #ffffff;
   .ant-form-item {
     display: flex;
     margin-bottom: 0px;
@@ -35,4 +36,11 @@
       content: '*';
     }
   }
+}
+.custom-main-search.right {
+  >.ant-row {
+    >.ant-col {
+      float: right;
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
index 5fdbdb7..91a6e80 100644
--- a/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
+++ b/src/templates/sharecomponent/searchcomponent/searchform/index.jsx
@@ -106,14 +106,14 @@
     let type = formlist.filter(cell => cell.key === 'type')[0].initVal
     let _items = formlist.filter(cell => cell.key === 'items')[0].initVal
     let resourceType = formlist.filter(cell => cell.key === 'resourceType')[0].initVal
-    let _options = ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide']                // 榛樿鏄剧ず椤�
+    let _options = ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide', 'labelShow']                // 榛樿鏄剧ず椤�
 
     if ((type === 'multiselect' || type === 'select' || type === 'link') && resourceType === '0') {        // 涓嬫媺閫夋嫨绫诲瀷銆侀�夐」涓鸿嚜瀹氫箟璧勬簮
       _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') {
-      _options = ['label', 'type', 'field', 'datefield', 'initval', 'blacklist', 'ratio', 'items', 'required', 'transfer']
+      _options = ['label', 'type', 'field', 'datefield', 'initval', 'blacklist', 'ratio', 'items', 'required', 'transfer', 'labelShow']
     }
 
     if (type === 'select' || type === 'link') {
@@ -182,14 +182,14 @@
     const { resourceType, items } = this.state
 
     if (key === 'type') {
-      let _options = ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide']
+      let _options = ['label', 'field', 'initval', 'type', 'match', 'ratio', 'blacklist', 'required', 'Hide', 'labelShow']
 
       if ((value === 'multiselect' || value === 'select' || value === 'link') && resourceType === '0') {        // 涓嬫媺閫夋嫨绫诲瀷銆侀�夐」涓鸿嚜瀹氫箟璧勬簮
         _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') {
-        _options = ['label', 'type', 'field', 'datefield', 'initval', 'items', 'ratio', 'blacklist', 'required', 'transfer']
+        _options = ['label', 'type', 'field', 'datefield', 'initval', 'items', 'ratio', 'blacklist', 'required', 'transfer', 'labelShow']
       }
 
       if (value === 'select' || value === 'link') {
@@ -263,7 +263,7 @@
     let value = e.target.value
 
     if (key === 'resourceType') {
-      let _options = ['label', 'field', 'initval', 'type', 'match', 'resourceType', 'display', 'ratio', 'blacklist', 'required', 'Hide']
+      let _options = ['label', 'field', 'initval', 'type', 'match', 'resourceType', 'display', 'ratio', 'blacklist', 'required', 'Hide', 'labelShow']
 
       if (value === '0') {
         _options = [..._options, 'options']
diff --git a/src/templates/sharecomponent/settingcomponent/settingform/index.jsx b/src/templates/sharecomponent/settingcomponent/settingform/index.jsx
index 629c8db..7755636 100644
--- a/src/templates/sharecomponent/settingcomponent/settingform/index.jsx
+++ b/src/templates/sharecomponent/settingcomponent/settingform/index.jsx
@@ -100,6 +100,8 @@
 
     let newsearches = []
     searches.forEach(search => {
+      if (!search.field) return
+      
       let item = {
         key: search.field,
         match: search.match,
diff --git a/src/templates/zshare/customscript/index.jsx b/src/templates/zshare/customscript/index.jsx
index 5d2b774..61b6957 100644
--- a/src/templates/zshare/customscript/index.jsx
+++ b/src/templates/zshare/customscript/index.jsx
@@ -83,6 +83,7 @@
 
     let _usefulFields = []
     searches.forEach(item => {
+      if (!item.field) return
       if (item.type === 'group') {
         if (item.transfer === 'true') {
           _usefulFields.push(item.field)
diff --git a/src/templates/zshare/formconfig.jsx b/src/templates/zshare/formconfig.jsx
index bffa047..0524048 100644
--- a/src/templates/zshare/formconfig.jsx
+++ b/src/templates/zshare/formconfig.jsx
@@ -496,20 +496,20 @@
         text: '>='
       }]
     },
-    {
-      type: 'select',
-      key: 'display',
-      label: Formdict['header.form.display'],
-      initVal: card.display || 'dropdown',
-      required: true,
-      options: [{
-        value: 'dropdown',
-        text: Formdict['header.form.dropdown']
-      // }, {
-      //   value: 'button',
-      //   text: Formdict['header.form.button']
-      }]
-    },
+    // {
+    //   type: 'select',
+    //   key: 'display',
+    //   label: Formdict['header.form.display'],
+    //   initVal: card.display || 'dropdown',
+    //   required: true,
+    //   options: [{
+    //     value: 'dropdown',
+    //     text: Formdict['header.form.dropdown']
+    //   // }, {
+    //   //   value: 'button',
+    //   //   text: Formdict['header.form.button']
+    //   }]
+    // },
     {
       type: 'radio',
       key: 'database',
@@ -574,6 +574,19 @@
       }]
     },
     {
+      type: 'radio',
+      key: 'labelShow',
+      label: '鏄剧ず鍚嶇О',
+      initVal: card.labelShow || 'true',
+      options: [{
+        value: 'true',
+        text: Formdict['model.true']
+      }, {
+        value: 'false',
+        text: Formdict['model.false']
+      }]
+    },
+    {
       type: 'multiselect',
       key: 'blacklist',
       label: Formdict['header.form.blacklist'],
diff --git a/src/views/menudesign/index.jsx b/src/views/menudesign/index.jsx
index 5afc486..5b7d7aa 100644
--- a/src/views/menudesign/index.jsx
+++ b/src/views/menudesign/index.jsx
@@ -373,7 +373,6 @@
             })
           } else {
             this.setState({
-              openEdition: response.open_edition || '',
               menuloading: false
             })
             notification.warning({
diff --git a/src/views/sso/index.jsx b/src/views/sso/index.jsx
new file mode 100644
index 0000000..3734955
--- /dev/null
+++ b/src/views/sso/index.jsx
@@ -0,0 +1,152 @@
+import React, {Component} from 'react'
+import { Spin } from 'antd'
+import { connect } from 'react-redux'
+import md5 from 'md5'
+import moment from 'moment'
+
+import Api from '@/api'
+import Utils from '@/utils/utils.js' 
+import options from '@/store/options.js'
+import { modifyMemberLevel } from '@/store/action'
+import './index.scss'
+
+class SSOLogin extends Component {
+  UNSAFE_componentWillMount() {
+    try {
+      let _param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
+
+      if (typeof(_param) === 'object') {
+        _param.UserID && sessionStorage.setItem('UserID', _param.UserID)
+        _param.LoginUID && sessionStorage.setItem('LoginUID', _param.LoginUID)
+        _param.User_Name && sessionStorage.setItem('User_Name', _param.User_Name)
+        _param.Full_Name && sessionStorage.setItem('Full_Name', _param.Full_Name)
+        _param.debug && sessionStorage.setItem('debug', _param.debug)
+        _param.dataM && sessionStorage.setItem('dataM', _param.dataM)
+        _param.avatar && sessionStorage.setItem('avatar', _param.avatar)
+        _param.role_id && sessionStorage.setItem('role_id', _param.role_id)
+      } else {
+        this.props.history.replace('/login')
+      }
+      this.getMessage()
+    } catch {
+      this.props.history.replace('/login')
+    }
+  }
+
+  getMessage = () => {
+    let _param = {
+      func: 's_Get_style',
+      TypeCharOne: 'PC',
+      LText: `select '${window.GLOB.appkey}'`,
+    }
+
+    _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
+    _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
+
+    Api.getSystemConfig(_param).then(res => {
+      if (res.status) {
+        let _url = window.location.href.split('#')[0] + 'system'
+        let systemMsg = {
+          favicon: res.titlelogo || '',
+          platTitle: res.titleName || '',
+          platName: res.SysName || '',
+          bgImage: res.Banner || '',
+          loginlogo: res.loginlogo || '',
+          copyRight: res.CopyRightYear && res.CopyRightOrg ? `Copyright漏${res.CopyRightYear}    鎵�鏈夌浉鍏崇増鏉冨綊    ${res.CopyRightOrg}` : '',
+          ICP: res.ICP || '',
+          mainlogo: res.indexlogo || '',
+          doclogo: res.doclogo || '',
+          style: res.CSS || '',
+          webSite: res.WebSite || ''
+        }
+
+        // url鏍囬
+        document.title = systemMsg.platTitle
+
+        try {
+          localStorage.setItem(_url, window.btoa(window.encodeURIComponent(JSON.stringify(systemMsg))))
+        } catch {
+          localStorage.removeItem(_url)
+        }
+
+        let _loginurl = window.location.href.split('#')[0] + 'loginways'
+        let login_ways = []
+        let login_types = []
+        if (res.login_ways && res.login_ways.length > 0) {
+          res.login_ways.forEach(item => {
+            // 鐭俊楠岃瘉鐮佺櫥褰曪紝蹇呴』璁剧疆鐭俊Id
+            if (item.way_no === 'sms_vcode' && !item.sms_id) return
+            if (login_types.includes(item.way_no)) return
+
+            login_types.push(item.way_no)
+
+            login_ways.push({
+              label: item.way_name,
+              type: item.way_no,
+              smsId: item.sms_id
+            }) 
+          })
+        } else {
+          login_ways.push({
+            label: '璐﹀彿瀵嗙爜鐧诲綍',
+            type: 'uname_pwd',
+            smsId: ''
+          })
+        }
+
+        try {
+          localStorage.setItem(_loginurl, window.btoa(window.encodeURIComponent(JSON.stringify(login_ways))))
+        } catch {
+          localStorage.removeItem(_loginurl)
+        }
+
+        window.GLOB.mainlogo = systemMsg.mainlogo
+        window.GLOB.style = systemMsg.style
+    
+        if (window.GLOB.style && options.styles[window.GLOB.style]) {
+          document.getElementById('root').className = options.styles[window.GLOB.style]
+        }
+
+        if (res.titlelogo && window.GLOB.favicon !== res.titlelogo) {
+          let link = document.querySelector("link[rel*='icon']") || document.createElement('link')
+          link.type = 'image/x-icon'
+          link.rel = 'shortcut icon'
+          link.href = res.titlelogo
+          document.getElementsByTagName('head')[0].appendChild(link)
+        }
+
+        let memberLevel = res.member_level
+
+        if (typeof(memberLevel) === 'number' && memberLevel > 10 && parseInt(memberLevel / 10) * 10 === memberLevel) {
+          sessionStorage.setItem('Member_Level', md5('mksoft' + moment().format('YYYYMM') + memberLevel))
+          this.props.modifyMemberLevel(memberLevel)
+        }
+        this.props.history.replace('/main')
+      } else {
+        this.props.history.replace('/login')
+      }
+    }, () => {
+      this.props.history.replace('/login')
+    })
+  }
+
+  render () {
+    return (
+      <div className="sso-login">
+        <Spin size="large" />
+      </div>
+    )
+  }
+}
+
+const mapStateToProps = () => {
+  return {}
+}
+
+const mapDispatchToProps = (dispatch) => {
+  return {
+    modifyMemberLevel: (memberLevel) => dispatch(modifyMemberLevel(memberLevel))
+  }
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(SSOLogin)
\ No newline at end of file
diff --git a/src/views/sso/index.scss b/src/views/sso/index.scss
new file mode 100644
index 0000000..f012efb
--- /dev/null
+++ b/src/views/sso/index.scss
@@ -0,0 +1,7 @@
+.sso-login {
+  .ant-spin {
+    position: absolute;
+    left: calc(50vw - 22px);
+    top: 45vh;
+  }
+}
\ No newline at end of file

--
Gitblit v1.8.0